// region_id_v6.c - RegionIdBox implementation for V6-HDR-1 // // Purpose: Centralized ptr -> region lookup for headerless design // Phase V6-HDR-1: OBSERVE only (no behavior change) #include #include #include #include #include "box/region_id_v6_box.h" #include "box/smallsegment_v6_box.h" #ifndef likely #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #endif // ============================================================================ // ENV Control // ============================================================================ #define REGION_OBSERVE_UNINIT (-1) #define REGION_OBSERVE_OFF 0 #define REGION_OBSERVE_ON 1 static int g_region_observe = REGION_OBSERVE_UNINIT; bool region_id_observe_enabled(void) { if (unlikely(g_region_observe == REGION_OBSERVE_UNINIT)) { const char* env = getenv("HAKMEM_REGION_ID_V6_OBSERVE"); g_region_observe = (env && env[0] == '1') ? REGION_OBSERVE_ON : REGION_OBSERVE_OFF; } return g_region_observe == REGION_OBSERVE_ON; } // ============================================================================ // TLS Cache + Segment Registration (Phase V6-HDR-3) // ============================================================================ static __thread RegionIdTlsCache g_region_tls_cache; static __thread int g_region_tls_cache_init = 0; // TLS segment info (registered on first access) static __thread uintptr_t g_v6_segment_base = 0; static __thread uintptr_t g_v6_segment_end = 0; static __thread SmallSegmentV6* g_v6_segment = NULL; static __thread int g_v6_segment_registered = 0; RegionIdTlsCache* region_id_tls_cache_get(void) { if (unlikely(!g_region_tls_cache_init)) { memset(&g_region_tls_cache, 0, sizeof(g_region_tls_cache)); g_region_tls_cache_init = 1; } return &g_region_tls_cache; } /// Register this thread's v6 segment (Phase V6-HDR-3) /// Called from small_heap_ctx_v6() when segment is first acquired void region_id_register_v6_segment(SmallSegmentV6* seg) { if (!seg || g_v6_segment_registered) { return; // Already registered or invalid } g_v6_segment_base = seg->base; g_v6_segment_end = seg->base + SMALL_SEGMENT_V6_SIZE; g_v6_segment = seg; g_v6_segment_registered = 1; } // ============================================================================ // Global RegionIdBox (V6-HDR-2: Full implementation) // ============================================================================ // Maximum number of registered regions #define REGION_MAX_ENTRIES 256 // RegionEntry: Single registered region typedef struct RegionEntry { uintptr_t base; // Region base address uintptr_t end; // Region end address (exclusive) region_kind_t kind; // Region type void* metadata; // Kind-specific metadata (e.g., page_meta) uint32_t id; // Unique region ID uint8_t active; // 1 = active, 0 = free slot uint8_t reserved[3]; // Padding } RegionEntry; // RegionIdBox: Region registry struct RegionIdBox { uint32_t next_id; // Next available ID uint32_t count; // Number of active entries RegionEntry entries[REGION_MAX_ENTRIES]; // Sorted by base address // Note: entries are kept sorted by base for binary search lookup }; static struct RegionIdBox g_region_id_box = { .next_id = 2, // Start from 2 (1 is reserved for TLS segment) .count = 0 }; RegionIdBox* region_id_box_get(void) { return &g_region_id_box; } // Binary search helper: find entry containing address static RegionEntry* region_entry_find(uintptr_t addr) { RegionIdBox* box = &g_region_id_box; if (box->count == 0) return NULL; // Binary search for entry where base <= addr < end uint32_t lo = 0, hi = box->count; while (lo < hi) { uint32_t mid = lo + (hi - lo) / 2; RegionEntry* e = &box->entries[mid]; if (!e->active) { // Skip inactive entries (shouldn't happen in sorted array) lo = mid + 1; continue; } if (addr < e->base) { hi = mid; } else if (addr >= e->end) { lo = mid + 1; } else { // addr is in range [base, end) return e; } } return NULL; } // Insert entry maintaining sorted order static int region_entry_insert(RegionEntry* entry) { RegionIdBox* box = &g_region_id_box; if (box->count >= REGION_MAX_ENTRIES) { return -1; // Registry full } // Find insertion point (binary search) uint32_t pos = 0; for (uint32_t i = 0; i < box->count; i++) { if (box->entries[i].base > entry->base) { pos = i; break; } pos = i + 1; } // Shift entries to make room for (uint32_t i = box->count; i > pos; i--) { box->entries[i] = box->entries[i - 1]; } // Insert new entry box->entries[pos] = *entry; box->count++; return 0; } // Remove entry by ID static int region_entry_remove(uint32_t id) { RegionIdBox* box = &g_region_id_box; for (uint32_t i = 0; i < box->count; i++) { if (box->entries[i].id == id && box->entries[i].active) { // Shift entries to fill gap for (uint32_t j = i; j < box->count - 1; j++) { box->entries[j] = box->entries[j + 1]; } box->count--; return 0; } } return -1; // Not found } // ============================================================================ // Lookup Implementation (V6-HDR-2: TLS + Registry) // ============================================================================ // Forward declaration from smallsegment_v6.c extern SmallPageMetaV6* small_page_meta_v6_of(void* ptr); RegionLookupV6 region_id_lookup_v6(void* ptr) { RegionLookupV6 result = { .kind = REGION_KIND_UNKNOWN, .region_id = 0, .page_meta = NULL }; if (unlikely(!ptr)) { return result; } uintptr_t addr = (uintptr_t)ptr; // Phase V6-HDR-4 P0: Direct page_meta calculation (Double validation 排除) // TLS segment が登録済みかつ範囲内なら、small_page_meta_v6_of() を呼ばずに // 直接 page_meta を計算する。これにより: // - slot->in_use チェックの重複を排除 // - small_ptr_in_segment_v6() の重複を排除 // - 関数呼び出しオーバーヘッドを削減 if (g_v6_segment_registered && addr >= g_v6_segment_base && addr < g_v6_segment_end) { // Calculate page_idx directly using TLS cached base size_t page_idx = (addr - g_v6_segment_base) >> SMALL_PAGE_V6_SHIFT; // Bounds check (should always pass if segment is valid) if (likely(page_idx < SMALL_PAGES_PER_SEGMENT)) { SmallPageMetaV6* page = &g_v6_segment->page_meta[page_idx]; // Minimal validation: only check capacity (page is in use) if (likely(page->capacity > 0)) { result.kind = REGION_KIND_SMALL_V6; result.region_id = 1; result.page_meta = page; // Phase V6-HDR-4 P1: Update TLS cache with page-level info RegionIdTlsCache* cache = region_id_tls_cache_get(); cache->last_base = g_v6_segment_base; cache->last_end = g_v6_segment_end; // Page-level cache: same-page ptr は page_meta lookup をスキップ可能 uintptr_t page_base = g_v6_segment_base + (page_idx << SMALL_PAGE_V6_SHIFT); cache->last_page_base = page_base; cache->last_page_end = page_base + SMALL_PAGE_V6_SIZE; cache->last_page = page; cache->last_result = result; } } return result; } // V6-HDR-2: Check registered regions (binary search) RegionEntry* entry = region_entry_find(addr); if (entry) { result.kind = entry->kind; result.region_id = entry->id; result.page_meta = entry->metadata; // Update TLS cache for segment-level caching RegionIdTlsCache* cache = region_id_tls_cache_get(); cache->last_base = entry->base; cache->last_end = entry->end; cache->last_result = result; // Note: page-level cache not applicable for arbitrary registered regions return result; } // Legacy fallback (if TLS not registered yet) SmallPageMetaV6* page = small_page_meta_v6_of(ptr); if (page != NULL) { result.kind = REGION_KIND_SMALL_V6; result.region_id = 1; result.page_meta = page; RegionIdTlsCache* cache = region_id_tls_cache_get(); SmallSegmentV6* seg = (SmallSegmentV6*)page->segment; if (seg) { cache->last_base = seg->base; cache->last_end = seg->base + SMALL_SEGMENT_V6_SIZE; cache->last_result = result; } } return result; } RegionLookupV6 region_id_lookup_cached_v6(void* ptr) { RegionIdTlsCache* cache = region_id_tls_cache_get(); uintptr_t addr = (uintptr_t)ptr; // Phase V6-HDR-4 P1: Same-page hit optimization // 同一ページ内なら page_meta lookup を完全にスキップ if (addr >= cache->last_page_base && addr < cache->last_page_end && cache->last_page != NULL && cache->last_page->capacity > 0) { // Same page hit - return cached page_meta directly RegionLookupV6 result = cache->last_result; result.page_meta = cache->last_page; return result; } // Segment hit but different page - need to recalculate page_meta if (addr >= cache->last_base && addr < cache->last_end && cache->last_result.kind != REGION_KIND_UNKNOWN) { // Calculate new page_idx size_t page_idx = (addr - cache->last_base) >> SMALL_PAGE_V6_SHIFT; if (likely(page_idx < SMALL_PAGES_PER_SEGMENT && g_v6_segment != NULL)) { SmallPageMetaV6* page = &g_v6_segment->page_meta[page_idx]; if (likely(page->capacity > 0)) { RegionLookupV6 result = cache->last_result; result.page_meta = page; // Update page-level cache uintptr_t page_base = cache->last_base + (page_idx << SMALL_PAGE_V6_SHIFT); cache->last_page_base = page_base; cache->last_page_end = page_base + SMALL_PAGE_V6_SIZE; cache->last_page = page; return result; } } } // Cache miss -> slow path return region_id_lookup_v6(ptr); } // ============================================================================ // Registration API (V6-HDR-2: Full implementation) // ============================================================================ uint32_t region_id_register_v6(void* base, size_t size, region_kind_t kind, void* metadata) { if (!base || size == 0) { return 0; // Invalid arguments } RegionIdBox* box = &g_region_id_box; // Create new entry RegionEntry entry = { .base = (uintptr_t)base, .end = (uintptr_t)base + size, .kind = kind, .metadata = metadata, .id = box->next_id, .active = 1 }; // Insert into registry if (region_entry_insert(&entry) != 0) { return 0; // Registry full } uint32_t id = box->next_id++; // OBSERVE mode logging region_id_observe_register(base, size, kind, id); return id; } void region_id_unregister_v6(uint32_t region_id) { if (region_id == 0 || region_id == 1) { return; // Invalid or reserved ID } // OBSERVE mode logging region_id_observe_unregister(region_id); region_entry_remove(region_id); } bool region_id_is_valid_v6(uint32_t region_id) { if (region_id == 0) return false; if (region_id == 1) return true; // Reserved for TLS segment RegionIdBox* box = &g_region_id_box; for (uint32_t i = 0; i < box->count; i++) { if (box->entries[i].id == region_id && box->entries[i].active) { return true; } } return false; } // ============================================================================ // Utility API // ============================================================================ const char* region_kind_to_string(region_kind_t kind) { switch (kind) { case REGION_KIND_UNKNOWN: return "UNKNOWN"; case REGION_KIND_SMALL_V6: return "SMALL_V6"; case REGION_KIND_C7_ULTRA: return "C7_ULTRA"; case REGION_KIND_POOL_V1: return "POOL_V1"; case REGION_KIND_LARGE: return "LARGE"; case REGION_KIND_TINY_LEGACY: return "TINY_LEGACY"; case REGION_KIND_MID_V3: return "MID_V3"; case REGION_KIND_SMALL_V7: return "SMALL_V7"; default: return "INVALID"; } } void region_id_box_dump(void) { fprintf(stderr, "[REGION_ID_BOX] V6-HDR-2: TLS segment + Registry\n"); fprintf(stderr, "[REGION_ID_BOX] observe=%d\n", region_id_observe_enabled()); RegionIdBox* box = &g_region_id_box; fprintf(stderr, "[REGION_ID_BOX] next_id=%u count=%u\n", box->next_id, box->count); // Dump TLS segment info if (g_v6_segment_registered) { fprintf(stderr, "[REGION_ID_BOX] TLS segment: base=%p end=%p (reserved id=1)\n", (void*)g_v6_segment_base, (void*)g_v6_segment_end); } // Dump registered regions for (uint32_t i = 0; i < box->count; i++) { RegionEntry* e = &box->entries[i]; if (e->active) { fprintf(stderr, "[REGION_ID_BOX] [%u] id=%u kind=%s base=%p end=%p meta=%p\n", i, e->id, region_kind_to_string(e->kind), (void*)e->base, (void*)e->end, e->metadata); } } } // ============================================================================ // OBSERVE Mode Logging // ============================================================================ void region_id_observe_lookup(void* ptr, const RegionLookupV6* result) { if (region_id_observe_enabled()) { fprintf(stderr, "[REGION_ID] lookup ptr=%p kind=%s region_id=%u page_meta=%p\n", ptr, region_kind_to_string(result->kind), result->region_id, result->page_meta); } } void region_id_observe_register(void* base, size_t size, region_kind_t kind, uint32_t id) { if (region_id_observe_enabled()) { fprintf(stderr, "[REGION_ID] register base=%p size=%zu kind=%s id=%u\n", base, size, region_kind_to_string(kind), id); } } void region_id_observe_unregister(uint32_t id) { if (region_id_observe_enabled()) { fprintf(stderr, "[REGION_ID] unregister id=%u\n", id); } }