Phase 7: header-aware TLS front caches and FG gating
- core/hakmem_tiny_fastcache.inc.h: make tiny_fast_pop/push read/write next at base+1 for C0–C6; clear C7 next on pop - core/hakmem_tiny_hot_pop.inc.h: header-aware next reads for g_fast_head pops (classes 0–3) - core/tiny_free_magazine.inc.h: header-aware chain linking for BG spill chain (base+1 for C0–C6) - core/box/front_gate_classifier.c: registry fallback classifies headerless only for class 7; others as headered Build OK; bench_fixed_size_hakmem still SIGBUS right after init. FREE_ROUTE trace shows invalid frees (ptr=0xa0, etc.). Next steps: instrument early frees and audit remaining header-aware writes in any front caches not yet patched.
This commit is contained in:
@ -63,6 +63,10 @@ static void __attribute__((destructor)) front_gate_stats_destructor(void) {
|
||||
//
|
||||
// Performance: 2-3 cycles (L1 cache hit)
|
||||
static inline int safe_header_probe(void* ptr) {
|
||||
// Reject obviously invalid/sentinel-sized pointers (defense-in-depth)
|
||||
if ((uintptr_t)ptr < 4096) {
|
||||
return -1;
|
||||
}
|
||||
// Safety check: header must be in same page as ptr
|
||||
uintptr_t offset_in_page = (uintptr_t)ptr & 0xFFF;
|
||||
if (offset_in_page == 0) {
|
||||
@ -140,9 +144,13 @@ static inline ptr_classification_t registry_lookup(void* ptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Valid Tiny allocation (headerless)
|
||||
// Note: C7 (1KB) is the only headerless class, but Registry handles all
|
||||
result.kind = PTR_KIND_TINY_HEADERLESS;
|
||||
// Valid Tiny allocation
|
||||
// Only class 7 (1KB) is headerless. Other classes use header-based free path.
|
||||
if (ss->size_class == 7) {
|
||||
result.kind = PTR_KIND_TINY_HEADERLESS;
|
||||
} else {
|
||||
result.kind = PTR_KIND_TINY_HEADER;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -177,6 +185,11 @@ ptr_classification_t classify_ptr(void* ptr) {
|
||||
};
|
||||
|
||||
if (!ptr) return result;
|
||||
// Early guard: reject non-canonical tiny integers to avoid ptr-1 probe crashes
|
||||
if ((uintptr_t)ptr < 4096) {
|
||||
result.kind = PTR_KIND_UNKNOWN;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Step 1: Try safe header probe (C0-C6 fast path: 5-10 cycles)
|
||||
// Skip header probe on 1KB-aligned pointers to avoid misclassifying C7/headerless
|
||||
@ -186,13 +199,22 @@ ptr_classification_t classify_ptr(void* ptr) {
|
||||
}
|
||||
if (class_idx >= 0) {
|
||||
// Header found - C0-C6 with header
|
||||
result.kind = PTR_KIND_TINY_HEADER;
|
||||
result.class_idx = class_idx;
|
||||
// Additional safety: verify pointer belongs to a SuperSlab region.
|
||||
// This avoids rare false positives where random header bytes look like 0xA0.
|
||||
struct SuperSlab* ss_chk = hak_super_lookup(ptr);
|
||||
if (!ss_chk) {
|
||||
// Not in Tiny registry; treat as UNKNOWN and continue
|
||||
// (fall back to later checks)
|
||||
} else {
|
||||
result.kind = PTR_KIND_TINY_HEADER;
|
||||
result.class_idx = class_idx;
|
||||
result.ss = ss_chk;
|
||||
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
g_classify_header_hit++;
|
||||
#endif
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2: Check Pool TLS (before Registry to avoid false positives)
|
||||
|
||||
Reference in New Issue
Block a user