Add tiny_ptr_bridge_box for centralized pointer classification

Consolidates the logic for resolving Tiny BASE pointers into
(SuperSlab*, slab_idx, TinySlabMeta*, class_idx) tuples.

Box Theory compliance:
- Single Responsibility: ptr→(ss,slab,meta,class) resolution only
- No side effects: pure classification, no logging, no mutations
- Clear API: 4 functions (classify_raw/base, validate_raw/base_class)
- Fail-fast friendly: callers decide error handling policy

Implementation:
- core/box/tiny_ptr_bridge_box.h: New box (4.7 KB)
- core/box/tls_sll_box.h: Integrated into sanitize_head/check_node

Architecture:
- Used in 3 call sites within TLS SLL Box
- Ready for gradual migration to other code paths
- Foundation for future centralized validation

Testing: 150+ seconds stable (sh8bench)
- 30s test: exit code 0, 0 crashes
- 120s test: exit code 0, 0 crashes
- Behavior: identical to previous hand-rolled implementation

Benefits:
- Single point of authority for ptr→(ss,slab,meta,class) logic
- Easier to add validation rules in future (range check, magic, etc.)
- Consistent API for all ptr classification needs
- Foundation for removing code duplication across allocator

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-04 05:54:54 +09:00
parent 1b58df5568
commit 8bdcae1dac
2 changed files with 154 additions and 20 deletions

View File

@ -0,0 +1,137 @@
// tiny_ptr_bridge_box.h - Pointer→SuperSlab/Slab Bridge Box
// Purpose:
// Centralize the logic for resolving Tiny BASE pointers into
// (SuperSlab*, slab_idx, TinySlabMeta*, class_idx) with a single
// consistent contract.
//
// Box Theory:
// - Single Responsibility:
// "Given a Tiny pointer, tell me which SuperSlab/slab/meta it belongs to."
// - Clear Boundary:
// All ptr→(ss, slab_idx, meta, class) resolution goes through this box.
// - FailFast Friendly:
// Callers decide whether to abort/drop/log based on the result.
// This box itself stays sideeffect free (no logging by default).
// - Reversible / A/B:
// Call sites can be migrated gradually; old handrolled lookups
// can be kept under #ifdef until fully retired.
//
// Notes:
// - This box is intentionally "dumb": it does not know about TLS SLL,
// remote queues, or ownership. It only classifies pointers.
// - Validation (e.g. class match) is done via helpers that return bool.
#ifndef HAKMEM_TINY_PTR_BRIDGE_BOX_H
#define HAKMEM_TINY_PTR_BRIDGE_BOX_H
#include "../hakmem_tiny_superslab_internal.h" // SuperSlab, TinySlabMeta, slab_index_for, ss_slabs_capacity
// Classification result for a Tiny pointer.
typedef struct TinyPtrBridgeInfo {
SuperSlab* ss; // Owning SuperSlab (NULL if not Tiny)
TinySlabMeta* meta; // Perslab metadata (NULL if invalid)
int slab_idx; // Slab index within SuperSlab (1 if invalid)
uint8_t meta_cls; // meta->class_idx if valid, 0xff otherwise
} TinyPtrBridgeInfo;
// Internal helper: classify a raw pointer without applying any policy.
// Preconditions:
// - raw may be arbitrary (stack/heap/garbage).
// Postconditions:
// - On success: info.ss != NULL, info.meta != NULL, slab_idx >= 0, meta_cls set.
// - On failure: all fields are "empty" (ss/meta=NULL, slab_idx=-1, meta_cls=0xff).
static inline TinyPtrBridgeInfo tiny_ptr_bridge_classify_raw(void* raw)
{
TinyPtrBridgeInfo info;
info.ss = NULL;
info.meta = NULL;
info.slab_idx = -1;
info.meta_cls = 0xffu;
if (!raw) {
return info;
}
uintptr_t addr = (uintptr_t)raw;
if (addr < 4096 || addr > 0x00007fffffffffffULL) {
// Noncanonical (very small or nonuserspace) → treat as invalid.
return info;
}
SuperSlab* ss = hak_super_lookup(raw);
if (!ss || ss->magic != SUPERSLAB_MAGIC) {
return info;
}
int cap = ss_slabs_capacity(ss);
if (cap <= 0) {
return info;
}
int slab_idx = slab_index_for(ss, raw);
if (slab_idx < 0 || slab_idx >= cap) {
return info;
}
TinySlabMeta* meta = &ss->slabs[slab_idx];
info.ss = ss;
info.meta = meta;
info.slab_idx = slab_idx;
info.meta_cls = meta->class_idx;
return info;
}
// Convenience: classify a BASE pointer (hak_base_ptr_t) into bridge info.
static inline TinyPtrBridgeInfo tiny_ptr_bridge_classify_base(hak_base_ptr_t base)
{
void* raw = HAK_BASE_TO_RAW(base);
return tiny_ptr_bridge_classify_raw(raw);
}
// Validate that a BASE pointer belongs to a Tiny slab with the expected class.
//
// Parameters:
// class_idx - Expected Tiny class index (1 to skip class check).
// base - BASE pointer to classify.
// out_info - Optional; filled on success with full classification.
//
// Returns:
// true - Pointer classified successfully and (if class_idx>=0) meta_cls matches.
// false - Pointer is not within any valid Tiny slab or class mismatch.
static inline bool tiny_ptr_bridge_validate_base_class(int class_idx,
hak_base_ptr_t base,
TinyPtrBridgeInfo* out_info)
{
TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_base(base);
if (!info.ss || !info.meta) {
return false;
}
if (class_idx >= 0 && info.meta_cls != (uint8_t)class_idx) {
return false;
}
if (out_info) {
*out_info = info;
}
return true;
}
// Convenience wrapper for raw pointers (used by legacy code).
static inline bool tiny_ptr_bridge_validate_raw_class(int class_idx,
void* raw,
TinyPtrBridgeInfo* out_info)
{
TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw);
if (!info.ss || !info.meta) {
return false;
}
if (class_idx >= 0 && info.meta_cls != (uint8_t)class_idx) {
return false;
}
if (out_info) {
*out_info = info;
}
return true;
}
#endif // HAKMEM_TINY_PTR_BRIDGE_BOX_H

View File

@ -37,6 +37,7 @@
#include "../hakmem_super_registry.h" #include "../hakmem_super_registry.h"
#include "ss_addr_map_box.h" #include "ss_addr_map_box.h"
#include "../superslab/superslab_inline.h" #include "../superslab/superslab_inline.h"
#include "tiny_ptr_bridge_box.h" // Box: ptr→(ss,slab,meta,class) bridge
#include "tiny_next_ptr_box.h" #include "tiny_next_ptr_box.h"
#include "tiny_header_box.h" // Header Box: Single Source of Truth for header operations #include "tiny_header_box.h" // Header Box: Single Source of Truth for header operations
@ -190,13 +191,13 @@ static inline void tls_sll_sanitize_head(int class_idx, const char* stage)
if (hak_base_is_null(head)) return; if (hak_base_is_null(head)) return;
void* raw = HAK_BASE_TO_RAW(head); void* raw = HAK_BASE_TO_RAW(head);
SuperSlab* ss = hak_super_lookup(raw); TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw);
int cap = ss ? ss_slabs_capacity(ss) : 0; SuperSlab* ss = info.ss;
int idx = (ss && ss->magic == SUPERSLAB_MAGIC) ? slab_index_for(ss, raw) : -1; int idx = info.slab_idx;
uint8_t meta_cls = (idx >= 0 && idx < cap) ? ss->slabs[idx].class_idx : 0xff; uint8_t meta_cls = info.meta_cls;
int reset = 0; int reset = 0;
if (!ss || ss->magic != SUPERSLAB_MAGIC || idx < 0 || idx >= cap || meta_cls != (uint8_t)class_idx) { if (!ss || !info.meta || idx < 0 || meta_cls != (uint8_t)class_idx) {
reset = 1; reset = 1;
} }
#if HAKMEM_TINY_HEADER_CLASSIDX #if HAKMEM_TINY_HEADER_CLASSIDX
@ -226,15 +227,11 @@ static inline void tls_sll_sanitize_head(int class_idx, const char* stage)
static inline int tls_sll_check_node(int class_idx, void* raw, void* from_base, const char* stage) static inline int tls_sll_check_node(int class_idx, void* raw, void* from_base, const char* stage)
{ {
if (!raw) return 1; if (!raw) return 1;
uintptr_t addr = (uintptr_t)raw; TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw);
if (addr < 4096 || addr > 0x00007fffffffffffULL) { SuperSlab* ss = info.ss;
goto bad; int idx = info.slab_idx;
} uint8_t meta_cls = info.meta_cls;
SuperSlab* ss = hak_super_lookup(raw); if (!ss || !info.meta || idx < 0 || meta_cls != (uint8_t)class_idx) {
int cap = ss ? ss_slabs_capacity(ss) : 0;
int idx = (ss && ss->magic == SUPERSLAB_MAGIC) ? slab_index_for(ss, raw) : -1;
uint8_t meta_cls = (idx >= 0 && idx < cap) ? ss->slabs[idx].class_idx : 0xff;
if (!ss || ss->magic != SUPERSLAB_MAGIC || idx < 0 || idx >= cap || meta_cls != (uint8_t)class_idx) {
goto bad; goto bad;
} }
#if HAKMEM_TINY_HEADER_CLASSIDX #if HAKMEM_TINY_HEADER_CLASSIDX
@ -258,12 +255,12 @@ bad:
uint64_t from_meta_used = 0; uint64_t from_meta_used = 0;
void* from_meta_freelist = NULL; void* from_meta_freelist = NULL;
if (from_base) { if (from_base) {
from_ss = hak_super_lookup(from_base); TinyPtrBridgeInfo from_info = tiny_ptr_bridge_classify_raw(from_base);
int from_cap = from_ss ? ss_slabs_capacity(from_ss) : 0; from_ss = from_info.ss;
from_idx = (from_ss && from_ss->magic == SUPERSLAB_MAGIC) ? slab_index_for(from_ss, from_base) : -1; from_idx = from_info.slab_idx;
if (from_idx >= 0 && from_idx < from_cap) { from_meta = from_info.meta;
from_meta = &from_ss->slabs[from_idx]; from_meta_cls = from_info.meta_cls;
from_meta_cls = from_meta->class_idx; if (from_meta) {
from_meta_used = from_meta->used; from_meta_used = from_meta->used;
from_meta_freelist = from_meta->freelist; from_meta_freelist = from_meta->freelist;
} }