実装内容: 1. SmallSegmentV6のmmap割り当ては既に v6-0で実装済み 2. small_heap_ctx_v6() で segment 取得時に region_id_register_v6_segment() 呼び出し 3. region_id_v6.c に TLS スコープのセグメント登録ロジック実装: - 4つの static __thread 変数でセグメント情報をキャッシュ - region_id_register_v6_segment(): セグメント base/end を TLS に記録 - region_id_lookup_v6(): TLS segment の range check を最初に実行 - TLS cache 更新で O(1) lookup 実現 4. region_id_v6_box.h に SmallSegmentV6 type include & function 宣言追加 5. small_v6_region_observe_validate() に region_id_observe_lookup() 呼び出し追加 効果: - HeaderlessデザインでRegionIdBoxが正式にSMALL_V6分類を返せるように - TLS-scopedな簡潔な登録メカニズム (マルチスレッド対応) - Fast path: TLS segment range check -> page_meta lookup - Fall back path: 従来の small_page_meta_v6_of() による動的検出 - Latency: O(1) TLS cache hit rate がv6 alloc/free の大部分をカバー 🤖 Generated with Claude Code Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
7.8 KiB
7.8 KiB
RegionIdBox v6 -<08>
Date: 2025-12-11 Phase: V6-HDR-0 Status: Design Phase
<EE><84>
v6 headerless -kJDfptr <20> region <20>1 n<>CU<>_ lookup ˒ЛY<8B> <0A>ecWfD classify_ptr / hak_super_lookup / ss_fast_lookup <20> RegionIdBox k<>W free Bn@ $<24><>q<92><71>kLF
<CC>o: <20>en ptr ^nOL
<FE><B6>nc<>
free(ptr)
classify_ptr(ptr) <20> domain $<24> (tiny/mid/large)
hak_super_lookup(ptr) <20> superslab lookup
ss_fast_lookup(ptr) <20> slab index $<24>
tiny_c7_ultra_segment_from_ptr(ptr) <20> C7 ULTRA segment
small_page_meta_v6_of(ptr) <20> v6 page_meta
OL<B9>:
- lookup L<><4C>W_ registry <20>a<01>wj"Lz
- <B0>WD allocator <20><>Bk free path n<06>L<90>H<97>
- header byte k<>XW_ guard L v6 headerless h<>'<27>D
RegionIdBox n<><6E>
X<EFBFBD>n lookup API
typedef enum {
REGION_KIND_UNKNOWN = 0, // *{2 /
REGION_KIND_SMALL_V6, // v6 small-object segment
REGION_KIND_C7_ULTRA, // C7 ULTRA segment (frozen)
REGION_KIND_POOL_V1, // pool v1 region
REGION_KIND_LARGE, // large allocation (mmap)
REGION_KIND_TINY_LEGACY, // legacy tiny heap
} region_kind_t;
typedef struct RegionLookupV6 {
region_kind_t kind; // region n.^
uint32_t region_id; // registry <20>n ID
void* page_meta; // kind-specific metadata (nullable)
} RegionLookupV6;
// /n lookup <20><><EFBFBD><EFBFBD>ݤ<EFBFBD><DDA4>
RegionLookupV6 region_id_lookup_v6(void* ptr);
Registration API
// Segment/Region {2L2 L segment \Bk|v
uint32_t region_id_register_v6(
void* base,
size_t size,
region_kind_t kind,
void* metadata // kind-specific (SmallSegmentV6*, etc.)
);
// Segment/Region {2<>d
void region_id_unregister_v6(uint32_t region_id);
<85><E8><9F>Ź<DD>
Interval Tree / Range Map
ptr <20> region n lookup <20> O(log n) gLF interval tree <20>(:
typedef struct RegionEntry {
uintptr_t start; // region <20>ˢ<EFBFBD><CBA2><EFBFBD>
uintptr_t end; // region B<><42><EFBFBD><EFBFBD><EFBFBD>
region_kind_t kind;
uint32_t region_id;
void* metadata;
} RegionEntry;
typedef struct RegionIdBox {
RegionEntry* entries; // sorted by start address
uint32_t count;
uint32_t capacity;
uint32_t next_id;
pthread_mutex_t lock; // registration o<><6F>
} RegionIdBox;
Lookup <20>i
- TLS Cache: <20><> lookup P<><50> TLS k<><6B>÷<E3>
- Segment Alignment: 2MiB aligned segment j<> mask <08>g<97> lookup
- Lazy Registration: segment \Bks<6B>k{2E<>jW
// Fast path: TLS cache hit
static __thread struct {
uintptr_t last_ptr;
RegionLookupV6 last_result;
} g_region_cache;
RegionLookupV6 region_id_lookup_v6(void* ptr) {
uintptr_t addr = (uintptr_t)ptr;
// TLS cache hit?
if (addr >= g_region_cache.last_result.start &&
addr < g_region_cache.last_result.end) {
return g_region_cache.last_result;
}
// Slow path: interval tree lookup
return region_id_lookup_slow(ptr);
}
free path gn(ѿ<><D1BF>
v6 headerless free
void small_free_fast_v6(void* ptr, SmallHeapCtxV6* ctx) {
// Step 1: TLS ownership check (O(1), no lookup)
if (small_tls_owns_ptr_v6(ctx, ptr)) {
// TLS k pushclass_idx o ctx K<>֗
small_v6_tls_push(ctx, ptr);
return;
}
// Step 2: RegionIdBox lookupTLS miss Bn
RegionLookupV6 lookup = region_id_lookup_v6(ptr);
switch (lookup.kind) {
case REGION_KIND_SMALL_V6:
// page_meta K<> class_idx ֗
SmallPageMetaV6* page = (SmallPageMetaV6*)lookup.page_meta;
small_v6_page_free(page, ptr);
break;
case REGION_KIND_C7_ULTRA:
// C7 ULTRA k<>rfrozen <20>
tiny_c7_ultra_free(ptr);
break;
case REGION_KIND_POOL_V1:
// pool v1 k<>r
hak_pool_free_v1(ptr);
break;
default:
// legacy fallback
tiny_legacy_fallback_free(ptr);
break;
}
}
Headerless <20>L<FB><4C><ED><FC><C9><DE>
Phase 1: RegionIdBox eV6-HDR-0
[<5B><>]
free(ptr)
header <20> <20> class_idx <20> route $<24>
[Phase 1]
free(ptr)
TLS owns? <20> v6 TLS pushheader
<0A>
TLS miss <20> RegionIdBox lookup <20> kind % dispatch
- header <20>oTLS miss Bn fallback hWfn<6E>Y
- v6 segment o RegionIdBox k{2lookup gX%<25><>k
Phase 2: Header <20>n<7F><6E><B5>J
[Phase 2]
free(ptr)
TLS owns? <20> v6 TLS push
RegionIdBox hit? <20> kind % dispatchheader
<0A>
RegionIdBox miss <20> legacy fallbackheader <20>
- v6 / C7 ULTRA / pool v1 Lhf RegionIdBox k{2
- legacy tiny n header <20>X
Phase 3: Header <20>h<8C>be
[Phase 3]
free(ptr)
TLS owns? <20> v6 TLS push
RegionIdBox lookup <20> kind % dispatch
(header <20>jWh region L{2)
- h allocator L RegionIdBox k{2
- header byte o alloc/free g<><07><>jD
ENV p
| ENV | Default | <AC> |
|---|---|---|
HAKMEM_REGION_ID_V6_ENABLED |
1 | RegionIdBox <09>v6 ON Bo<42> |
HAKMEM_REGION_ID_V6_OBSERVE |
0 | lookup Bn<42><6E><ED><B0> |
HAKMEM_REGION_ID_V6_CACHE_SIZE |
1 | TLS cache <20><><A8><F3>p |
OBSERVE <20><><E2>
<C7><D0>ð(k HAKMEM_REGION_ID_V6_OBSERVE=1 g<><67>:
[REGION_ID] lookup ptr=0x7f... kind=SMALL_V6 region_id=123
[REGION_ID] register base=0x7f... size=2097152 kind=SMALL_V6 id=124
[REGION_ID] unregister id=123
<9F><C5>*H<>
| *H<> | _<FD> | 1 |
|---|---|---|
| P0 | <FA>, lookup API | v6 free path k<> |
| P0 | v6 segment registration | v6 <20>\k<> |
| P1 | TLS cache | lookup <20> |
| P2 | C7 ULTRA registration | q lookup<08><>o<B6><6F>g<CB><67> |
| P2 | pool v1 registration | q lookup<08><>o<B6><6F>g<CB><67> |
| P3 | OBSERVE mode | <C7><D0>ð( |
<C2><03><><EA>
SMALLOBJECT_CORE_V6_DESIGN.md: v6 hS-CURRENT_TASK.md: Phase V6-HDR-0 2L<32><4C>PERF_EXEC_SUMMARY_ULTRA_PHASE_20251211.md: ULTRA <16><>n<><6E>
Phase V6-HDR-1: Implementation (2025-12-11)
Overview
V6-HDR-1 connects RegionIdBox to C6 segments and adds OBSERVE mode validation
for ptr -> (kind, page_meta.class_idx) correctness. No behavior change.
Implementation Files
-
core/region_id_v6.c (New)
region_id_lookup_v6(ptr): Usessmall_page_meta_v6_of(ptr)for C6 lookupregion_id_lookup_cached_v6(ptr): TLS cache version for fast pathregion_id_tls_cache_get(): Returns per-thread cache- OBSERVE logging:
HAKMEM_REGION_ID_V6_OBSERVE=1
-
core/smallobject_core_v6.c (Modified)
- Added
#include "box/region_id_v6_box.h" - Added
small_v6_region_observe_enabled(): ENV check forHAKMEM_SMALL_V6_REGION_OBSERVE - Added
small_v6_region_observe_validate(ptr, class_idx_hint): Validates class_idx - Added REGION_OBSERVE call in
small_free_fast_v6()
- Added
Lookup Flow
region_id_lookup_v6(ptr):
1. NULL check -> return UNKNOWN
2. small_page_meta_v6_of(ptr) -> SmallPageMetaV6*
3. If page != NULL:
- kind = REGION_KIND_SMALL_V6
- region_id = 1 (TLS segment for now)
- page_meta = page
- Update TLS cache
4. Else: REGION_KIND_UNKNOWN
REGION_OBSERVE Validation
// In small_free_fast_v6():
if (unlikely(small_v6_region_observe_enabled())) {
small_v6_region_observe_validate(ptr, class_idx);
}
// Validation logic:
RegionLookupV6 lk = region_id_lookup_v6(ptr);
if (lk.kind == REGION_KIND_SMALL_V6 && lk.page_meta != NULL) {
SmallPageMetaV6* page = (SmallPageMetaV6*)lk.page_meta;
if (page->class_idx != class_idx_hint) {
// Log MISMATCH
}
}
ENV Variables
| ENV | Default | Description |
|---|---|---|
HAKMEM_SMALL_V6_REGION_OBSERVE |
0 | Enable class_idx validation in v6 free |
HAKMEM_REGION_ID_V6_OBSERVE |
0 | Enable RegionIdBox lookup logging |
Front-side Wiring Status
class_idxhint: Extracted from header byte(header & 0x0F)infree_tiny_fast()- v6 route: Currently NOT connected (breaks to fallback)
- This is intentional for "OBSERVE only, no behavior change" phase
Next Phase (V6-HDR-2)
- Connect v6 route in
free_tiny_fast()to callsmall_free_fast_v6() - Verify OBSERVE shows no MISMATCH logs
- Remove header byte write from v6 alloc path (true headerless)