Phase v7-2: SmallObject v7 C6-only implementation with RegionIdBox integration

- SmallSegment_v7: 2MiB segment with TLS slot and free page stack
- ColdIface_v7: Page refill/retire between HotBox and SegmentBox
- HotBox_v7: Full C6-only alloc/free with header writing (HEADER_MAGIC|class_idx)
- Free path early-exit: Check v7 route BEFORE ss_fast_lookup (separate mmap segment)
- RegionIdBox: Register v7 segment for ptr->region lookup
- Benchmark: v7 ON ~54.5M ops/s (-7% overhead vs 58.6M legacy baseline)

v7 correctly balances alloc/free counts and page lifecycle.
RegionIdBox overhead identified as primary cost driver.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-12 03:12:28 +09:00
parent a8d0ab06fc
commit 39a3c53dbc
17 changed files with 1729 additions and 61 deletions

View File

@ -29,6 +29,7 @@ typedef enum {
TINY_ROUTE_SMALL_HEAP_V4 = 4, // SmallObject HotHeap v4 (stub, route未使用)
TINY_ROUTE_SMALL_HEAP_V5 = 5, // SmallObject HotHeap v5 (C6-only route stub, Phase v5-1)
TINY_ROUTE_SMALL_HEAP_V6 = 6, // SmallObject Core v6 (C6-only route stub, Phase v6-1)
TINY_ROUTE_SMALL_HEAP_V7 = 7, // SmallObject HotHeap v7 (C6-only route stub, Phase v7-1)
} tiny_route_kind_t;
extern tiny_route_kind_t g_tiny_route_class[TINY_NUM_CLASSES];
@ -70,11 +71,52 @@ static inline int small_heap_v6_class_enabled(uint32_t class_idx) {
return (mask & (1u << class_idx)) ? 1 : 0;
}
// ============================================================================
// Phase v7-1: SmallObject HotHeap v7 ENV gate (must be before tiny_route_snapshot_init)
// ============================================================================
// small_heap_v7_enabled() - グローバル v7 enable check
static inline int small_heap_v7_enabled(void) {
static int g_enabled = ENV_UNINIT;
if (__builtin_expect(g_enabled == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V7_ENABLED");
g_enabled = (e && *e && *e != '0') ? ENV_ENABLED : ENV_DISABLED;
}
return (g_enabled == ENV_ENABLED);
}
// small_heap_v7_class_mask() - v7 対象クラスのビットマスク
static inline uint32_t small_heap_v7_class_mask(void) {
static int g_mask = ENV_UNINIT;
if (__builtin_expect(g_mask == ENV_UNINIT, 0)) {
const char* e = getenv("HAKMEM_SMALL_HEAP_V7_CLASSES");
if (e && *e) {
g_mask = (int)strtoul(e, NULL, 0);
} else {
g_mask = 0x0; // default: OFF
}
}
return (uint32_t)g_mask;
}
// small_heap_v7_class_enabled() - 指定クラスが v7 有効か
static inline int small_heap_v7_class_enabled(uint32_t class_idx) {
if (class_idx >= 8) return 0;
if (!small_heap_v7_enabled()) return 0;
uint32_t mask = small_heap_v7_class_mask();
return (mask & (1u << class_idx)) ? 1 : 0;
}
static inline void tiny_route_snapshot_init(void) {
for (int i = 0; i < TINY_NUM_CLASSES; i++) {
// Phase v6-1: C6-only v6 route stub (highest priority)
// Phase v7-1: C6-only v7 route stub (highest priority)
FREE_DISPATCH_STAT_INC(env_checks); // ENV check counter
if (small_heap_v6_class_enabled((uint32_t)i)) {
if (small_heap_v7_class_enabled((uint32_t)i)) {
g_tiny_route_class[i] = TINY_ROUTE_SMALL_HEAP_V7;
FREE_DISPATCH_STAT_INC(route_core_v7);
} else if (small_heap_v6_class_enabled((uint32_t)i)) {
// Phase v6-1: C6-only v6 route stub
FREE_DISPATCH_STAT_INC(env_checks);
g_tiny_route_class[i] = TINY_ROUTE_SMALL_HEAP_V6;
FREE_DISPATCH_STAT_INC(route_core_v6);
} else if (i == 6 && small_heap_v5_class_enabled(6)) {
@ -119,7 +161,8 @@ static inline int tiny_route_is_heap_kind(tiny_route_kind_t route) {
route == TINY_ROUTE_SMALL_HEAP_V3 ||
route == TINY_ROUTE_SMALL_HEAP_V4 ||
route == TINY_ROUTE_SMALL_HEAP_V5 ||
route == TINY_ROUTE_SMALL_HEAP_V6;
route == TINY_ROUTE_SMALL_HEAP_V6 ||
route == TINY_ROUTE_SMALL_HEAP_V7;
}
// C7 front が TinyHeap を使うかRoute snapshot 経由で判定)