diff --git a/core/box/tiny_ptr_bridge_box.h b/core/box/tiny_ptr_bridge_box.h new file mode 100644 index 00000000..2bc4ef6f --- /dev/null +++ b/core/box/tiny_ptr_bridge_box.h @@ -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. +// - Fail‑Fast Friendly: +// Callers decide whether to abort/drop/log based on the result. +// This box itself stays side‑effect free (no logging by default). +// - Reversible / A/B: +// Call sites can be migrated gradually; old hand‑rolled 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; // Per‑slab 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) { + // Non‑canonical (very small or non‑userspace) → 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 + diff --git a/core/box/tls_sll_box.h b/core/box/tls_sll_box.h index 9c43a32a..e39d6eb6 100644 --- a/core/box/tls_sll_box.h +++ b/core/box/tls_sll_box.h @@ -37,6 +37,7 @@ #include "../hakmem_super_registry.h" #include "ss_addr_map_box.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_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; void* raw = HAK_BASE_TO_RAW(head); - SuperSlab* ss = hak_super_lookup(raw); - 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; + TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw); + SuperSlab* ss = info.ss; + int idx = info.slab_idx; + uint8_t meta_cls = info.meta_cls; 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; } #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) { if (!raw) return 1; - uintptr_t addr = (uintptr_t)raw; - if (addr < 4096 || addr > 0x00007fffffffffffULL) { - goto bad; - } - SuperSlab* ss = hak_super_lookup(raw); - 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) { + TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(raw); + SuperSlab* ss = info.ss; + int idx = info.slab_idx; + uint8_t meta_cls = info.meta_cls; + if (!ss || !info.meta || idx < 0 || meta_cls != (uint8_t)class_idx) { goto bad; } #if HAKMEM_TINY_HEADER_CLASSIDX @@ -258,12 +255,12 @@ bad: uint64_t from_meta_used = 0; void* from_meta_freelist = NULL; if (from_base) { - from_ss = hak_super_lookup(from_base); - int from_cap = from_ss ? ss_slabs_capacity(from_ss) : 0; - from_idx = (from_ss && from_ss->magic == SUPERSLAB_MAGIC) ? slab_index_for(from_ss, from_base) : -1; - if (from_idx >= 0 && from_idx < from_cap) { - from_meta = &from_ss->slabs[from_idx]; - from_meta_cls = from_meta->class_idx; + TinyPtrBridgeInfo from_info = tiny_ptr_bridge_classify_raw(from_base); + from_ss = from_info.ss; + from_idx = from_info.slab_idx; + from_meta = from_info.meta; + from_meta_cls = from_info.meta_cls; + if (from_meta) { from_meta_used = from_meta->used; from_meta_freelist = from_meta->freelist; }