diff --git a/core/tiny_free_fast.inc.h b/core/tiny_free_fast.inc.h index 0bbb43f5..06d9af01 100644 --- a/core/tiny_free_fast.inc.h +++ b/core/tiny_free_fast.inc.h @@ -216,8 +216,12 @@ static inline void tiny_free_fast(void* ptr) { // ss_fast_lookup masks to 1MB boundary and reads magic - would crash on unmapped memory. SuperSlab* ss = hak_super_lookup(ptr); if (__builtin_expect(ss != NULL && ss->magic == SUPERSLAB_MAGIC, 0)) { - void* base = (void*)((uint8_t*)ptr - 1); // Convert USER → BASE - int slab_idx = slab_index_for(ss, base); + // ROOT CAUSE FIX: slab_index_for() can handle USER pointers directly + // Avoid per-class offset conversion errors (C0/C7 have offset=0, C1-6 have offset=1) + int slab_idx = slab_index_for(ss, ptr); + + // Convert USER → BASE for tiny_free_fast_ss (needed for next pointer operations) + void* base = (void*)((uint8_t*)ptr - tiny_user_offset(hak_slab_class(hak_slab_from_superslab(ss, slab_idx)))); uint32_t self_tid = tiny_self_u32(); // Box 6 Boundary: Try same-thread fast path