Front Gate: registry-first classification (no ptr-1 deref); Pool TLS via registry to avoid unsafe header reads.\nTLS-SLL: splice head normalization, remove false misalignment guard, drop heuristic normalization; add carve/splice debug logs.\nRefill: add one-shot sanity checks (range/stride) at P0 and non-P0 boundaries (debug-only).\nInfra: provide ptr_trace_dump_now stub in release to fix linking.\nVerified: bench_fixed_size_hakmem 200000 1024 128 passes (Debug/Release), no SEGV.
This commit is contained in:
@ -23,6 +23,8 @@
|
||||
#include "hakmem_tiny_magazine.h"
|
||||
#include "hakmem_tiny_tls_list.h"
|
||||
#include "tiny_box_geometry.h" // Box 3: Geometry & Capacity Calculator
|
||||
#include "hakmem_super_registry.h" // For hak_super_lookup (Debug validation)
|
||||
#include "superslab/superslab_inline.h" // For slab_index_for/ss_slabs_capacity (Debug validation)
|
||||
#include "box/tls_sll_box.h" // Box TLS-SLL: Safe SLL operations API
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
@ -97,6 +99,46 @@ static inline int ultra_sll_cap_for_class(int class_idx);
|
||||
// Note: tiny_small_mags_init_once and tiny_mag_init_if_needed are declared in hakmem_tiny_magazine.h
|
||||
static void eventq_push(int class_idx, uint32_t size);
|
||||
|
||||
// Debug-only: Validate that a base node belongs to the expected Tiny SuperSlab and is stride-aligned
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
static inline void tiny_debug_validate_node_base(int class_idx, void* node, const char* where) {
|
||||
if ((uintptr_t)node < 4096) {
|
||||
fprintf(stderr, "[SLL_NODE_SMALL] %s: node=%p cls=%d\n", where, node, class_idx);
|
||||
abort();
|
||||
}
|
||||
SuperSlab* ss = hak_super_lookup(node);
|
||||
if (!ss) {
|
||||
fprintf(stderr, "[SLL_NODE_UNKNOWN] %s: node=%p cls=%d\n", where, node, class_idx);
|
||||
abort();
|
||||
}
|
||||
int ocls = ss->size_class;
|
||||
if (ocls == 7 || ocls != class_idx) {
|
||||
fprintf(stderr, "[SLL_NODE_CLASS_MISMATCH] %s: node=%p cls=%d owner_cls=%d\n", where, node, class_idx, ocls);
|
||||
abort();
|
||||
}
|
||||
int slab_idx = slab_index_for(ss, node);
|
||||
if (slab_idx < 0 || slab_idx >= ss_slabs_capacity(ss)) {
|
||||
fprintf(stderr, "[SLL_NODE_SLAB_OOB] %s: node=%p slab_idx=%d cap=%d\n", where, node, slab_idx, ss_slabs_capacity(ss));
|
||||
abort();
|
||||
}
|
||||
uint8_t* base = tiny_slab_base_for_geometry(ss, slab_idx);
|
||||
size_t usable = tiny_usable_bytes_for_slab(slab_idx);
|
||||
size_t stride = tiny_stride_for_class(ocls);
|
||||
uintptr_t a = (uintptr_t)node;
|
||||
if (a < (uintptr_t)base || a >= (uintptr_t)base + usable) {
|
||||
fprintf(stderr, "[SLL_NODE_RANGE] %s: node=%p base=%p usable=%zu\n", where, node, base, usable);
|
||||
abort();
|
||||
}
|
||||
size_t off = (size_t)(a - (uintptr_t)base);
|
||||
if (off % stride != 0) {
|
||||
fprintf(stderr, "[SLL_NODE_MISALIGNED] %s: node=%p off=%zu stride=%zu base=%p\n", where, node, off, stride, base);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void tiny_debug_validate_node_base(int class_idx, void* node, const char* where) { (void)class_idx; (void)node; (void)where; }
|
||||
#endif
|
||||
|
||||
// Fast cache refill and take operation
|
||||
static inline void* tiny_fast_refill_and_take(int class_idx, TinyTLSList* tls) {
|
||||
void* direct = tiny_fast_pop(class_idx);
|
||||
@ -151,6 +193,10 @@ static inline int quick_refill_from_sll(int class_idx) {
|
||||
// CRITICAL: Use Box TLS-SLL API to avoid race condition (rbp=0xa0 SEGV)
|
||||
void* head = NULL;
|
||||
if (!tls_sll_pop(class_idx, &head)) break;
|
||||
// One-shot validation for the first pop
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
do { static _Atomic int once = 0; int exp = 0; if (atomic_compare_exchange_strong(&once, &exp, 1)) { tiny_debug_validate_node_base(class_idx, head, "quick_refill_from_sll"); } } while (0);
|
||||
#endif
|
||||
qs->items[qs->top++] = head;
|
||||
room--; filled++;
|
||||
}
|
||||
@ -419,6 +465,10 @@ static inline int frontend_refill_fc(int class_idx) {
|
||||
while (need > 0) {
|
||||
void* h = NULL;
|
||||
if (!tls_sll_pop(class_idx, &h)) break;
|
||||
// One-shot validation for the first pop into FastCache
|
||||
#if !HAKMEM_BUILD_RELEASE
|
||||
do { static _Atomic int once_fc = 0; int exp2 = 0; if (atomic_compare_exchange_strong(&once_fc, &exp2, 1)) { tiny_debug_validate_node_base(class_idx, h, "frontend_refill_fc"); } } while (0);
|
||||
#endif
|
||||
fc->items[fc->top++] = h;
|
||||
need--; filled++;
|
||||
if (fc->top >= TINY_FASTCACHE_CAP) break;
|
||||
|
||||
Reference in New Issue
Block a user