Files
hakmem/core/region_id_v6.c

266 lines
9.7 KiB
C
Raw Normal View History

// 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#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 (stub for now)
// ============================================================================
// Define the opaque RegionIdBox structure
struct RegionIdBox {
uint32_t next_id;
// Stub implementation - full implementation in V6-HDR-2
};
static struct RegionIdBox g_region_id_box;
RegionIdBox* region_id_box_get(void) {
return &g_region_id_box;
}
// ============================================================================
// Lookup Implementation (V6-HDR-1: TLS segment only)
// ============================================================================
// 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;
}
// 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 (Stub for V6-HDR-1)
// ============================================================================
uint32_t region_id_register_v6(void* base, size_t size, region_kind_t kind, void* metadata) {
(void)base;
(void)size;
(void)kind;
(void)metadata;
// V6-HDR-1: Registration is not yet implemented
// TLS segment is implicitly "registered" by its existence
return 1; // Single region for now
}
void region_id_unregister_v6(uint32_t region_id) {
(void)region_id;
// V6-HDR-1: No-op
}
bool region_id_is_valid_v6(uint32_t region_id) {
return region_id == 1; // Only TLS segment is "registered"
}
// ============================================================================
// 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";
default: return "INVALID";
}
}
void region_id_box_dump(void) {
fprintf(stderr, "[REGION_ID_BOX] V6-HDR-1: TLS segment lookup only\n");
fprintf(stderr, "[REGION_ID_BOX] observe=%d\n", region_id_observe_enabled());
}
// ============================================================================
// 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);
}
}