- Update build configuration and flags - Add missing header files and dependencies - Update TLS list implementation with proper scoping - Fix various compilation warnings and issues - Update debug ring and tiny allocation infrastructure - Update benchmark results documentation Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
60 lines
2.0 KiB
C
60 lines
2.0 KiB
C
// tiny_nextptr.h - Safe load/store for header-aware next pointers
|
||
//
|
||
// Context:
|
||
// - Tiny classes 0–6 place a 1-byte header immediately before the user pointer
|
||
// - Freelist "next" is stored inside the block at an offset that depends on class
|
||
// - Many hot paths currently cast to void** at base+1, which is unaligned and UB in C
|
||
//
|
||
// This header centralizes the offset calculation and uses memcpy-based loads/stores
|
||
// to avoid undefined behavior from unaligned pointer access. Compilers will optimize
|
||
// these to efficient byte moves on x86_64 while remaining standards-compliant.
|
||
|
||
#ifndef TINY_NEXTPTR_H
|
||
#define TINY_NEXTPTR_H
|
||
|
||
#include <stdint.h>
|
||
#include <string.h>
|
||
#include "hakmem_build_flags.h"
|
||
|
||
// Compute freelist next-pointer offset within a block for the given class.
|
||
// - Class 7 (1024B) is headerless → next at offset 0 (block base)
|
||
// - Classes 0–6 have 1-byte header → next at offset 1
|
||
static inline __attribute__((always_inline)) size_t tiny_next_off(int class_idx) {
|
||
#if HAKMEM_TINY_HEADER_CLASSIDX
|
||
return (class_idx == 7) ? 0 : 1;
|
||
#else
|
||
(void)class_idx;
|
||
return 0;
|
||
#endif
|
||
}
|
||
|
||
// Safe load of next pointer from a block base
|
||
static inline __attribute__((always_inline)) void* tiny_next_load(const void* base, int class_idx) {
|
||
size_t off = tiny_next_off(class_idx);
|
||
#if HAKMEM_TINY_HEADER_CLASSIDX
|
||
if (__builtin_expect(off != 0, 0)) {
|
||
void* next = NULL;
|
||
const uint8_t* p = (const uint8_t*)base + off;
|
||
memcpy(&next, p, sizeof(void*));
|
||
return next;
|
||
}
|
||
#endif
|
||
// Either headers are disabled, or this class uses offset 0 (aligned)
|
||
return *(void* const*)base;
|
||
}
|
||
|
||
// Safe store of next pointer into a block base
|
||
static inline __attribute__((always_inline)) void tiny_next_store(void* base, int class_idx, void* next) {
|
||
size_t off = tiny_next_off(class_idx);
|
||
#if HAKMEM_TINY_HEADER_CLASSIDX
|
||
if (__builtin_expect(off != 0, 0)) {
|
||
uint8_t* p = (uint8_t*)base + off;
|
||
memcpy(p, &next, sizeof(void*));
|
||
return;
|
||
}
|
||
#endif
|
||
*(void**)base = next;
|
||
}
|
||
|
||
#endif // TINY_NEXTPTR_H
|