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>
138 lines
4.6 KiB
C
138 lines
4.6 KiB
C
// 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
|
||
|