## P0: Double validation 排除 - region_id_lookup_v6() で TLS segment 登録済み + 範囲内なら small_page_meta_v6_of() を呼ばずに直接 page_meta を計算 - 削除された重複チェック: - slot->in_use (TLS登録で保証) - small_ptr_in_segment_v6() (addr範囲で既にチェック済み) - 関数呼び出しオーバーヘッド - 推定効果: +1-2% (6-8 instructions 削減) ## P1: TLS cache に page_meta キャッシュ追加 - RegionIdTlsCache に追加: - last_page_base / last_page_end (ページ範囲) - last_page (SmallPageMetaV6* 直接ポインタ) - region_id_lookup_cached_v6() で same-page hit 時は page_meta lookup を完全スキップ - 推定効果: +1.5-2.5% (10-12 instructions 削減) ## ベンチマーク結果 (揺れあり) - V6-HDR-3 (P0/P1 前): -3.5% ~ -8.3% 回帰 - V6-HDR-4 (P0+P1 後): +2.7% ~ +12% 改善 (一部の run で) 設計原則: - RegionIdBox は薄く保つ (分類のみ) - キャッシュは TLS 側に寄せる - same-page 判定で last_page_base/end を使用 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
162 lines
6.2 KiB
C
162 lines
6.2 KiB
C
// region_id_v6_box.h - RegionIdBox for ptr->region lookup (V6-HDR-0)
|
|
//
|
|
// Purpose: Centralized ptr classification for headerless design
|
|
// - Replaces scattered classify_ptr / hak_super_lookup / ss_fast_lookup
|
|
// - Provides O(1) or O(log n) lookup from ptr to region info
|
|
|
|
#ifndef HAKMEM_REGION_ID_V6_BOX_H
|
|
#define HAKMEM_REGION_ID_V6_BOX_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include "smallsegment_v6_box.h" // For SmallSegmentV6 type
|
|
|
|
// ============================================================================
|
|
// Region Kind Enum
|
|
// ============================================================================
|
|
|
|
typedef enum {
|
|
REGION_KIND_UNKNOWN = 0, // Unknown / not registered
|
|
REGION_KIND_SMALL_V6, // SmallObject v6 segment
|
|
REGION_KIND_C7_ULTRA, // C7 ULTRA segment (frozen)
|
|
REGION_KIND_POOL_V1, // Pool v1 region
|
|
REGION_KIND_LARGE, // Large mmap allocation
|
|
REGION_KIND_TINY_LEGACY, // Legacy tiny heap
|
|
REGION_KIND_MAX
|
|
} region_kind_t;
|
|
|
|
// ============================================================================
|
|
// Lookup Result Structure
|
|
// ============================================================================
|
|
|
|
/// Result of region_id_lookup_v6()
|
|
typedef struct RegionLookupV6 {
|
|
region_kind_t kind; // Region kind
|
|
uint32_t region_id; // Registry ID (unique per registration)
|
|
void* page_meta; // Kind-specific metadata (nullable)
|
|
// - SMALL_V6: SmallPageMetaV6*
|
|
// - C7_ULTRA: UltraSegment*
|
|
// - POOL_V1: pool_desc*
|
|
// - others: NULL
|
|
} RegionLookupV6;
|
|
|
|
// ============================================================================
|
|
// RegionIdBox Opaque Structure
|
|
// ============================================================================
|
|
|
|
typedef struct RegionIdBox RegionIdBox;
|
|
|
|
// ============================================================================
|
|
// Global Instance
|
|
// ============================================================================
|
|
|
|
/// Get the global RegionIdBox instance
|
|
RegionIdBox* region_id_box_get(void);
|
|
|
|
// ============================================================================
|
|
// Lookup API (Hot Path)
|
|
// ============================================================================
|
|
|
|
/// Lookup region info for a pointer
|
|
/// @param ptr: pointer to lookup (USER pointer)
|
|
/// @return: RegionLookupV6 with kind, region_id, and page_meta
|
|
/// @note: Returns REGION_KIND_UNKNOWN if not found
|
|
RegionLookupV6 region_id_lookup_v6(void* ptr);
|
|
|
|
/// Fast lookup with TLS cache
|
|
/// @param ptr: pointer to lookup
|
|
/// @return: same as region_id_lookup_v6, but uses TLS cache
|
|
RegionLookupV6 region_id_lookup_cached_v6(void* ptr);
|
|
|
|
// ============================================================================
|
|
// Registration API (Cold Path)
|
|
// ============================================================================
|
|
|
|
/// Register a region with the box
|
|
/// @param base: region base address
|
|
/// @param size: region size in bytes
|
|
/// @param kind: region kind
|
|
/// @param metadata: kind-specific metadata (stored as page_meta in lookup result)
|
|
/// @return: unique region_id (0 on failure)
|
|
uint32_t region_id_register_v6(void* base, size_t size, region_kind_t kind, void* metadata);
|
|
|
|
/// Unregister a region
|
|
/// @param region_id: ID returned from register
|
|
void region_id_unregister_v6(uint32_t region_id);
|
|
|
|
// ============================================================================
|
|
// Utility API
|
|
// ============================================================================
|
|
|
|
/// Check if region_id is valid
|
|
bool region_id_is_valid_v6(uint32_t region_id);
|
|
|
|
/// Get region kind as string (for debug)
|
|
const char* region_kind_to_string(region_kind_t kind);
|
|
|
|
/// Dump all registered regions (debug)
|
|
void region_id_box_dump(void);
|
|
|
|
// ============================================================================
|
|
// OBSERVE Mode (Debug)
|
|
// ============================================================================
|
|
|
|
/// ENV: HAKMEM_REGION_ID_V6_OBSERVE (default: 0)
|
|
/// When enabled, logs lookup/register/unregister operations
|
|
|
|
/// Check if observe mode is enabled
|
|
bool region_id_observe_enabled(void);
|
|
|
|
/// Log a lookup operation (called internally when observe=1)
|
|
void region_id_observe_lookup(void* ptr, const RegionLookupV6* result);
|
|
|
|
/// Log a registration (called internally when observe=1)
|
|
void region_id_observe_register(void* base, size_t size, region_kind_t kind, uint32_t id);
|
|
|
|
/// Log an unregistration (called internally when observe=1)
|
|
void region_id_observe_unregister(uint32_t id);
|
|
|
|
// ============================================================================
|
|
// Inline Fast Path (TLS Cache)
|
|
// ============================================================================
|
|
|
|
/// TLS cache for fast lookup (single entry)
|
|
/// Phase V6-HDR-4 P1: page_meta キャッシュ追加
|
|
typedef struct RegionIdTlsCache {
|
|
uintptr_t last_base; // Cached segment base
|
|
uintptr_t last_end; // Cached segment end
|
|
uintptr_t last_page_base; // Cached page base (for same-page optimization)
|
|
uintptr_t last_page_end; // Cached page end
|
|
SmallPageMetaV6* last_page; // Cached page_meta (direct pointer)
|
|
RegionLookupV6 last_result; // Cached result
|
|
} RegionIdTlsCache;
|
|
|
|
/// Get TLS cache for current thread
|
|
RegionIdTlsCache* region_id_tls_cache_get(void);
|
|
|
|
// ============================================================================
|
|
// Phase V6-HDR-3: Segment Registration (TLS scope)
|
|
// ============================================================================
|
|
|
|
/// Register this thread's v6 segment (Phase V6-HDR-3)
|
|
/// Called from small_heap_ctx_v6() when segment is first acquired
|
|
/// @param seg: SmallSegmentV6 pointer (TLS-owned)
|
|
void region_id_register_v6_segment(SmallSegmentV6* seg);
|
|
|
|
/// Inline fast lookup with TLS cache hit
|
|
static inline RegionLookupV6 region_id_lookup_fast_v6(void* ptr) {
|
|
RegionIdTlsCache* cache = region_id_tls_cache_get();
|
|
uintptr_t addr = (uintptr_t)ptr;
|
|
|
|
// TLS cache hit?
|
|
if (addr >= cache->last_base && addr < cache->last_end) {
|
|
return cache->last_result;
|
|
}
|
|
|
|
// Cache miss -> slow path
|
|
return region_id_lookup_v6(ptr);
|
|
}
|
|
|
|
#endif // HAKMEM_REGION_ID_V6_BOX_H
|