Files
hakmem/docs/analysis/REGIONID_V6_DESIGN.md
Moe Charm (CI) df216b6901 Phase V6-HDR-3: SmallSegmentV6 実割り当て & RegionIdBox Registration
実装内容:
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>
2025-12-11 23:51:48 +09:00

7.8 KiB
Raw History

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>:

  1.  lookup L<><4C>W_ registry <20>a<01>wj"Lz
  2. <B0>WD allocator <20><>Bk free path n<06>L<90>H<97>
  3. 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

  1. TLS Cache: <20><> lookup P<><50> TLS k<><6B>÷<E3>
  2. Segment Alignment: 2MiB aligned segment j<> mask <08>g<97> lookup
  3. 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>o TLS 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

  1. core/region_id_v6.c (New)

    • region_id_lookup_v6(ptr): Uses small_page_meta_v6_of(ptr) for C6 lookup
    • region_id_lookup_cached_v6(ptr): TLS cache version for fast path
    • region_id_tls_cache_get(): Returns per-thread cache
    • OBSERVE logging: HAKMEM_REGION_ID_V6_OBSERVE=1
  2. core/smallobject_core_v6.c (Modified)

    • Added #include "box/region_id_v6_box.h"
    • Added small_v6_region_observe_enabled(): ENV check for HAKMEM_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()

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_idx hint: Extracted from header byte (header & 0x0F) in free_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 call small_free_fast_v6()
  • Verify OBSERVE shows no MISMATCH logs
  • Remove header byte write from v6 alloc path (true headerless)