Files
hakmem/core/tiny_nextptr.h
Moe Charm (CI) 862e8ea7db Infrastructure and build updates
- 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>
2025-11-11 21:49:05 +09:00

60 lines
2.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// tiny_nextptr.h - Safe load/store for header-aware next pointers
//
// Context:
// - Tiny classes 06 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 06 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