2025-12-07 22:49:28 +09:00
|
|
|
|
// tiny_heap_env_box.h - ENV gate for TinyHeap front (A/B 切り替え)
|
|
|
|
|
|
// 役割:
|
|
|
|
|
|
// - 新しい TinyHeap front を ON/OFF する環境変数の読み出しをホットパス外に分離。
|
|
|
|
|
|
// - デフォルト OFF(環境変数が未設定または 0 のとき)。
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2025-12-08 21:30:21 +09:00
|
|
|
|
#include <stdint.h>
|
2025-12-07 22:49:28 +09:00
|
|
|
|
#include <stdlib.h>
|
2025-12-08 21:30:21 +09:00
|
|
|
|
#include <string.h>
|
|
|
|
|
|
#include <strings.h>
|
2025-12-07 22:49:28 +09:00
|
|
|
|
#include "c7_hotpath_env_box.h" // tiny_c7_hot_enabled()
|
|
|
|
|
|
|
2025-12-08 21:30:21 +09:00
|
|
|
|
// TinyHeap profile modes (HAKMEM_TINY_HEAP_PROFILE)
|
|
|
|
|
|
enum {
|
|
|
|
|
|
TINY_HEAP_PROFILE_LEGACY = 0, // TinyHeap OFF / 既存 front
|
|
|
|
|
|
TINY_HEAP_PROFILE_C7_SAFE = 1, // C7 TinyHeap + SAFE meta
|
|
|
|
|
|
TINY_HEAP_PROFILE_C7_ULTRA_BENCH = 2, // C7 TinyHeap + ULTRA (bench 専用)
|
|
|
|
|
|
TINY_HEAP_PROFILE_CUSTOM = 3, // クラス/メタを ENV で直接指定
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ENV: HAKMEM_TINY_HEAP_PROFILE
|
|
|
|
|
|
static inline int tiny_heap_profile_mode(void) {
|
|
|
|
|
|
static int g_mode = -1;
|
|
|
|
|
|
if (__builtin_expect(g_mode == -1, 0)) {
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_HEAP_PROFILE");
|
|
|
|
|
|
if (!e || !*e) {
|
|
|
|
|
|
g_mode = TINY_HEAP_PROFILE_LEGACY;
|
|
|
|
|
|
} else if (strcasecmp(e, "C7_SAFE") == 0) {
|
|
|
|
|
|
g_mode = TINY_HEAP_PROFILE_C7_SAFE;
|
|
|
|
|
|
} else if (strcasecmp(e, "C7_ULTRA_BENCH") == 0 || strcasecmp(e, "C7_ULTRA") == 0) {
|
|
|
|
|
|
g_mode = TINY_HEAP_PROFILE_C7_ULTRA_BENCH;
|
|
|
|
|
|
} else if (strcasecmp(e, "CUSTOM") == 0) {
|
|
|
|
|
|
g_mode = TINY_HEAP_PROFILE_CUSTOM;
|
|
|
|
|
|
} else if (strcasecmp(e, "LEGACY") == 0) {
|
|
|
|
|
|
g_mode = TINY_HEAP_PROFILE_LEGACY;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
int v = atoi(e);
|
|
|
|
|
|
if (v < 0) v = 0;
|
|
|
|
|
|
if (v > 3) v = 3;
|
|
|
|
|
|
g_mode = v;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return g_mode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline unsigned tiny_heap_profile_default_class_mask(int profile_mode) {
|
|
|
|
|
|
switch (profile_mode) {
|
|
|
|
|
|
case TINY_HEAP_PROFILE_C7_SAFE:
|
|
|
|
|
|
case TINY_HEAP_PROFILE_C7_ULTRA_BENCH:
|
|
|
|
|
|
return 1u << 7; // C7 のみ
|
|
|
|
|
|
case TINY_HEAP_PROFILE_CUSTOM:
|
|
|
|
|
|
case TINY_HEAP_PROFILE_LEGACY:
|
|
|
|
|
|
default:
|
|
|
|
|
|
return 0u;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline int tiny_heap_profile_default_c7_meta_mode(int profile_mode) {
|
|
|
|
|
|
switch (profile_mode) {
|
|
|
|
|
|
case TINY_HEAP_PROFILE_C7_SAFE:
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
case TINY_HEAP_PROFILE_C7_ULTRA_BENCH:
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
case TINY_HEAP_PROFILE_CUSTOM:
|
|
|
|
|
|
case TINY_HEAP_PROFILE_LEGACY:
|
|
|
|
|
|
default:
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-07 22:49:28 +09:00
|
|
|
|
// ENV: HAKMEM_TINY_HEAP_BOX=1 で TinyHeap front を有効化
|
|
|
|
|
|
static inline int tiny_heap_box_enabled(void) {
|
|
|
|
|
|
static int g_enable = -1;
|
|
|
|
|
|
if (__builtin_expect(g_enable == -1, 0)) {
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_HEAP_BOX");
|
2025-12-08 21:30:21 +09:00
|
|
|
|
if (e && *e) {
|
|
|
|
|
|
g_enable = (*e != '0') ? 1 : 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// profile が LEGACY 以外なら自動で ON
|
|
|
|
|
|
g_enable = (tiny_heap_profile_mode() != TINY_HEAP_PROFILE_LEGACY) ? 1 : 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return g_enable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ENV gate: C6 Hot front (直線パス) を有効化するか
|
|
|
|
|
|
static inline int tiny_c6_hot_enabled(void) {
|
|
|
|
|
|
static int g_enable = -1;
|
|
|
|
|
|
if (__builtin_expect(g_enable == -1, 0)) {
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_C6_HOT");
|
2025-12-07 22:49:28 +09:00
|
|
|
|
g_enable = (e && *e && *e != '0') ? 1 : 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return g_enable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ENV: HAKMEM_TINY_HEAP_CLASSES (bitmask, bit i が 1 のクラスを TinyHeap 経路に載せる)
|
|
|
|
|
|
// 例: 0x80 (デフォルト) → C7 のみ / 0xC0 → C6 + C7 / 0xFF → 全クラス
|
|
|
|
|
|
static inline int tiny_heap_class_enabled(int class_idx) {
|
|
|
|
|
|
static int g_parsed = 0;
|
|
|
|
|
|
static unsigned g_mask = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (__builtin_expect(!g_parsed, 0)) {
|
|
|
|
|
|
g_mask = 0;
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_HEAP_CLASSES");
|
|
|
|
|
|
if (e && *e) {
|
|
|
|
|
|
unsigned v = (unsigned)strtoul(e, NULL, 0);
|
|
|
|
|
|
g_mask = v & 0xFFu;
|
|
|
|
|
|
} else {
|
2025-12-08 21:30:21 +09:00
|
|
|
|
g_mask = tiny_heap_profile_default_class_mask(tiny_heap_profile_mode());
|
2025-12-07 22:49:28 +09:00
|
|
|
|
}
|
|
|
|
|
|
g_parsed = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 21:30:21 +09:00
|
|
|
|
if (!tiny_heap_box_enabled()) return 0;
|
2025-12-07 22:49:28 +09:00
|
|
|
|
if (class_idx < 0 || class_idx >= TINY_NUM_CLASSES) return 0;
|
|
|
|
|
|
return (g_mask & (1u << class_idx)) != 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TinyHeap front とクラス bitmask の両方が有効なときにだけ TinyHeap 経路を使う
|
|
|
|
|
|
static inline int tiny_heap_class_route_enabled(int class_idx) {
|
|
|
|
|
|
if (class_idx == 7) {
|
|
|
|
|
|
return tiny_heap_box_enabled() && tiny_c7_hot_enabled() && tiny_heap_class_enabled(class_idx);
|
|
|
|
|
|
}
|
2025-12-08 21:30:21 +09:00
|
|
|
|
if (class_idx == 6) {
|
|
|
|
|
|
return tiny_heap_box_enabled() && tiny_c6_hot_enabled() && tiny_heap_class_enabled(class_idx);
|
|
|
|
|
|
}
|
2025-12-07 22:49:28 +09:00
|
|
|
|
return tiny_heap_box_enabled() && tiny_heap_class_enabled(class_idx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Helper: TinyHeap front + C7 Hot path が両方 ON のときに true
|
|
|
|
|
|
static inline int tiny_c7_heap_mode_enabled(void) {
|
|
|
|
|
|
return tiny_heap_class_route_enabled(7);
|
|
|
|
|
|
}
|
2025-12-08 21:30:21 +09:00
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
// TinyHotHeap v2 (未配線、Phase30: skeleton 用)
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// ENV: HAKMEM_TINY_HOTHEAP_V2=1 で v2 Box を有効化(デフォルト OFF)
|
|
|
|
|
|
static inline int tiny_hotheap_v2_enabled(void) {
|
|
|
|
|
|
static int g_enable = -1;
|
|
|
|
|
|
if (__builtin_expect(g_enable == -1, 0)) {
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_HOTHEAP_V2");
|
|
|
|
|
|
g_enable = (e && *e && *e != '0') ? 1 : 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return g_enable;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ENV: HAKMEM_TINY_HOTHEAP_CLASSES (bitmask) - v2 用クラスマスク(デフォルト 0 = 全 OFF)
|
|
|
|
|
|
static inline int tiny_hotheap_v2_class_enabled(uint8_t class_idx) {
|
|
|
|
|
|
static int g_parsed = 0;
|
|
|
|
|
|
static unsigned g_mask = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (__builtin_expect(!g_parsed, 0)) {
|
|
|
|
|
|
const char* e = getenv("HAKMEM_TINY_HOTHEAP_CLASSES");
|
|
|
|
|
|
if (e && *e) {
|
|
|
|
|
|
unsigned v = (unsigned)strtoul(e, NULL, 0);
|
|
|
|
|
|
g_mask = v & 0xFFu;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
g_mask = 0; // デフォルトは全 OFF(v2 は明示的に ON にする)
|
|
|
|
|
|
}
|
|
|
|
|
|
g_parsed = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!tiny_hotheap_v2_enabled()) return 0;
|
|
|
|
|
|
if (class_idx >= TINY_NUM_CLASSES) return 0;
|
|
|
|
|
|
return (g_mask & (1u << class_idx)) != 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// C7 用 v2 gate(C7 front からのみ参照)
|
|
|
|
|
|
static inline int tiny_c7_hotheap_v2_enabled(void) {
|
|
|
|
|
|
return tiny_hotheap_v2_class_enabled(7);
|
|
|
|
|
|
}
|