Files
hakmem/core/hakmem_tiny.c
Moe Charm (CI) 6b791b97d4 ENV Cleanup: Delete Ultra HEAP & BG Remote dead code (-1,096 LOC)
Deleted files (11):
- core/ultra/ directory (6 files: tiny_ultra_heap.*, tiny_ultra_page_arena.*)
- core/front/tiny_ultrafront.h
- core/tiny_ultra_fast.inc.h
- core/hakmem_tiny_ultra_front.inc.h
- core/hakmem_tiny_ultra_simple.inc
- core/hakmem_tiny_ultra_batch_box.inc

Edited files (10):
- core/hakmem_tiny.c: Remove Ultra HEAP #includes, move ultra_batch_for_class()
- core/hakmem_tiny_tls_state_box.inc: Delete TinyUltraFront, g_ultra_simple
- core/hakmem_tiny_phase6_wrappers_box.inc: Delete ULTRA_SIMPLE block
- core/hakmem_tiny_alloc.inc: Delete Ultra-Front code block
- core/hakmem_tiny_init.inc: Delete ULTRA_SIMPLE ENV loading
- core/hakmem_tiny_remote_target.{c,h}: Delete g_bg_remote_enable/batch
- core/tiny_refill.h: Remove BG Remote check (always break)
- core/hakmem_tiny_background.inc: Delete BG Remote drain loop

Deleted ENV variables:
- HAKMEM_TINY_ULTRA_HEAP (build flag, undefined)
- HAKMEM_TINY_ULTRA_L0
- HAKMEM_TINY_ULTRA_HEAP_DUMP
- HAKMEM_TINY_ULTRA_PAGE_DUMP
- HAKMEM_TINY_ULTRA_FRONT
- HAKMEM_TINY_BG_REMOTE (no getenv, dead code)
- HAKMEM_TINY_BG_REMOTE_BATCH (no getenv, dead code)
- HAKMEM_TINY_ULTRA_SIMPLE (references only)

Impact:
- Code reduction: -1,096 lines
- Binary size: 305KB → 304KB (-1KB)
- Build: PASS
- Sanity: 15.69M ops/s (3 runs avg)
- Larson: 1 crash observed (seed 43, likely existing instability)

Notes:
- Ultra HEAP never compiled (#if HAKMEM_TINY_ULTRA_HEAP undefined)
- BG Remote variables never initialized (g_bg_remote_enable always 0)
- Ultra SLIM (ultra_slim_alloc_box.h) preserved (active 4-layer path)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 04:35:47 +09:00

647 lines
28 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.

#include "hakmem_tiny.h"
#include "hakmem_tiny_config.h" // Centralized configuration
#include "hakmem_phase7_config.h" // Phase 7: Task 3 constants (PREWARM_COUNT, etc.)
#include "hakmem_tiny_superslab.h"
#include "box/ss_slab_meta_box.h" // Phase 3d-A: SlabMeta Box boundary // Phase 6.22: SuperSlab allocator
#include "hakmem_super_registry.h" // Phase 8.2: SuperSlab registry for memory profiling
#include "hakmem_internal.h"
#include "hakmem_syscall.h" // Phase 6.X P0 Fix: Box 3 syscall layer (bypasses LD_PRELOAD)
#include "hakmem_tiny_magazine.h"
#include "hakmem_tiny_integrity.h" // PRIORITY 1-4: Corruption detection
#include "box/tiny_next_ptr_box.h" // Box API: next pointer read/write
// Phase 1 modules (must come AFTER hakmem_tiny.h for TinyPool definition)
#include "hakmem_tiny_batch_refill.h" // Phase 1: Batch refill/spill for mini-magazine
#include "hakmem_tiny_stats.h" // Phase 1: Batched statistics (replaces XOR RNG)
// Phase 2B modules
#include "tiny_api.h" // Consolidated: stats_api, query_api, rss_api, registry_api
#include "tiny_tls.h"
#include "tiny_debug.h"
#include "tiny_mmap_gate.h"
#include "tiny_debug_ring.h"
#include "tiny_route.h"
#include "front/tiny_heap_v2.h"
#include "tiny_tls_guard.h"
#include "tiny_ready.h"
#include "hakmem_tiny_tls_list.h"
#include "hakmem_tiny_remote_target.h" // Phase 2C-1: Remote target queue
#include "hakmem_tiny_bg_spill.h" // Phase 2C-2: Background spill queue
#include "tiny_adaptive_sizing.h" // Phase 2b: Adaptive TLS cache sizing
// NOTE: hakmem_tiny_tls_ops.h included later (after type definitions)
#include "tiny_system.h" // Consolidated: stdio, stdlib, string, etc.
#include "hakmem_prof.h"
#include "hakmem_trace.h" // Optional USDT (perf) tracepoints
// Phase E5: Ultra fast path - REMOVED (dead code cleanup 2025-11-27)
extern uint64_t g_bytes_allocated; // from hakmem_tiny_superslab.c
// Tiny allocator configuration, debug counters, and return helpers
#include "hakmem_tiny_config_box.inc"
// Forward declarations for static helpers used before definition
struct TinySlab; // forward
static void move_to_free_list(int class_idx, struct TinySlab* target_slab);
static void move_to_full_list(int class_idx, struct TinySlab* target_slab);
static void release_slab(struct TinySlab* slab);
static TinySlab* allocate_new_slab(int class_idx);
static void tiny_tls_cache_drain(int class_idx);
static void tiny_apply_mem_diet(void);
// Phase 6.23: SuperSlab allocation forward declaration
static inline void* hak_tiny_alloc_superslab(int class_idx);
static inline void* superslab_tls_bump_fast(int class_idx);
SuperSlab* superslab_refill(int class_idx);
static inline void* superslab_alloc_from_slab(SuperSlab* ss, int slab_idx);
static inline uint32_t sll_cap_for_class(int class_idx, uint32_t mag_cap);
// Forward decl: used by tiny_spec_pop_path before its definition
#if HAKMEM_TINY_P0_BATCH_REFILL
// P0 enabled: sll_refill_batch_from_ss is defined in hakmem_tiny_refill_p0.inc.h
static inline int sll_refill_batch_from_ss(int class_idx, int max_take);
#else
// Phase 12: sll_refill_small_from_ss is defined in hakmem_tiny_refill.inc.h
// Only a single implementation exists there; declare here for callers.
#ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
int sll_refill_small_from_ss(int class_idx, int max_take);
#else
static inline int sll_refill_small_from_ss(int class_idx, int max_take);
#endif
#endif
static inline void hak_tiny_free_superslab(void* ptr, SuperSlab* ss);
static void* __attribute__((cold, noinline)) tiny_slow_alloc_fast(int class_idx);
static inline void tiny_remote_drain_owner(struct TinySlab* slab);
static void tiny_remote_drain_locked(struct TinySlab* slab);
// Ultra-fast try-only variant: attempt a direct SuperSlab bump/freelist pop
// without any refill or slow-path work. Returns NULL on miss.
/* moved below TinyTLSSlab definition */
// Step 3d: Forced inlining for readability + performance (306M target)
__attribute__((always_inline))
static inline void* hak_tiny_alloc_wrapper(int class_idx);
// Helpers for SuperSlab active block accounting (atomic, saturating dec)
// SuperSlab Active Counter Helpers - EXTRACTED to hakmem_tiny_ss_active_box.inc
#include "hakmem_tiny_ss_active_box.inc"
// EXTRACTED: ss_active_dec_one() moved to hakmem_tiny_superslab.h (Phase 2C-2)
// Front refill count global config (declare before init.inc uses them)
extern int g_refill_count_global;
extern int g_refill_count_hot;
extern int g_refill_count_mid;
extern int g_refill_count_class[TINY_NUM_CLASSES];
// Step 3d: Forced inlining for slow path (maintain monolithic performance)
// Phase 6-1.7: Export for box refactor (Box 5 needs access from hakmem.c)
#ifdef HAKMEM_TINY_PHASE6_BOX_REFACTOR
void* __attribute__((cold, noinline)) hak_tiny_alloc_slow(size_t size, int class_idx);
#else
static void* __attribute__((cold, noinline)) hak_tiny_alloc_slow(size_t size, int class_idx);
#endif
// ---------------------------------------------------------------------------
// Box: adopt_gate_try (implementation moved from header for robust linkage)
// ---------------------------------------------------------------------------
#include "box/adopt_gate_box.h"
extern SuperSlab* g_super_reg_by_class[TINY_NUM_CLASSES][SUPER_REG_PER_CLASS];
extern int g_super_reg_class_size[TINY_NUM_CLASSES];
extern unsigned long long g_adopt_gate_calls[];
extern unsigned long long g_adopt_gate_success[];
extern unsigned long long g_reg_scan_attempts[];
extern unsigned long long g_reg_scan_hits[];
SuperSlab* adopt_gate_try(int class_idx, TinyTLSSlab* tls) {
g_adopt_gate_calls[class_idx]++;
ROUTE_MARK(13);
SuperSlab* ss = tiny_refill_try_fast(class_idx, tls);
if (ss) { g_adopt_gate_success[class_idx]++; return ss; }
g_reg_scan_attempts[class_idx]++;
int reg_size = g_super_reg_class_size[class_idx];
int scan_limit = tiny_reg_scan_max();
if (scan_limit > reg_size) scan_limit = reg_size;
uint32_t self_tid = tiny_self_u32();
// Local helper (mirror adopt_bind_if_safe) to avoid including alloc inline here
auto int adopt_bind_if_safe_local(TinyTLSSlab* tls_l, SuperSlab* ss, int slab_idx, int class_idx_l) {
uint32_t self_tid = tiny_self_u32();
SlabHandle h = slab_try_acquire(ss, slab_idx, self_tid);
if (!slab_is_valid(&h)) return 0;
slab_drain_remote_full(&h);
if (__builtin_expect(slab_is_safe_to_bind(&h), 1)) {
tiny_tls_bind_slab(tls_l, h.ss, h.slab_idx);
slab_release(&h);
return 1;
}
slab_release(&h);
return 0;
}
for (int i = 0; i < scan_limit; i++) {
SuperSlab* cand = g_super_reg_by_class[class_idx][i];
if (!(cand && cand->magic == SUPERSLAB_MAGIC)) continue;
// Fast path: use nonempty_mask / freelist_mask to locate candidates in O(1)
uint32_t mask = cand->nonempty_mask;
// Fallback to atomic freelist_mask for cross-thread visibility
if (mask == 0) {
mask = atomic_load_explicit(&cand->freelist_mask, memory_order_acquire);
}
if (mask == 0) continue; // No visible freelists in this SS
int cap = ss_slabs_capacity(cand);
while (mask) {
int sidx = __builtin_ctz(mask);
mask &= (mask - 1);
if (sidx >= cap) continue;
if (adopt_bind_if_safe_local(tls, cand, sidx, class_idx)) {
g_adopt_gate_success[class_idx]++;
g_reg_scan_hits[class_idx]++;
ROUTE_MARK(14); ROUTE_COMMIT(class_idx, 0x07);
return cand;
}
}
}
return NULL;
}
// ============================================================================
// Global State - EXTRACTED to hakmem_tiny_globals_box.inc
// ============================================================================
#include "hakmem_tiny_globals_box.inc"
#include "hakmem_tiny_publish_box.inc"
// ============================================================================
// EXTRACTED TO hakmem_tiny_fastcache.inc.h (Phase 2D-1)
// ============================================================================
// Functions: tiny_fast_pop(), tiny_fast_push() - 28 lines (lines 377-404)
// Forward declarations for functions defined in hakmem_tiny_fastcache.inc.h
static inline void* tiny_fast_pop(int class_idx);
static inline int tiny_fast_push(int class_idx, void* ptr);
static inline void* fastcache_pop(int class_idx);
static inline int fastcache_push(int class_idx, void* ptr);
// ============================================================================
// EXTRACTED TO hakmem_tiny_hot_pop.inc.h (Phase 2D-1)
// ============================================================================
// Functions: tiny_hot_pop_class0(), tiny_hot_pop_class1(), tiny_hot_pop_class2(), tiny_hot_pop_class3()
// 88 lines (lines 407-494)
// ============================================================================
// Legacy Slow Allocation Path - EXTRACTED to hakmem_tiny_legacy_slow_box.inc
// ============================================================================
#include "hakmem_tiny_legacy_slow_box.inc"
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Function: tiny_fast_refill_and_take() - 39 lines (lines 584-622)
// ============================================================================
// TLS/Frontend State & Configuration - EXTRACTED to hakmem_tiny_tls_state_box.inc
// ============================================================================
#include "hakmem_tiny_tls_state_box.inc"
#include "hakmem_tiny_intel.inc"
// ============================================================================
// EXTRACTED TO hakmem_tiny_rss.c (Phase 2B-2)
// ============================================================================
// EXTRACTED: static int get_rss_kb_self(void) {
// EXTRACTED: FILE* f = fopen("/proc/self/status", "r");
// EXTRACTED: if (!f) return 0;
// EXTRACTED: char buf[256];
// EXTRACTED: int kb = 0;
// EXTRACTED: while (fgets(buf, sizeof(buf), f)) {
// EXTRACTED: if (strncmp(buf, "VmRSS:", 6) == 0) {
// EXTRACTED: char* p = buf;
// EXTRACTED: while (*p && (*p < '0' || *p > '9')) {
// EXTRACTED: p++;
// EXTRACTED: }
// EXTRACTED: kb = atoi(p);
// EXTRACTED: break;
// EXTRACTED: }
// EXTRACTED: }
// EXTRACTED: fclose(f);
// EXTRACTED: return kb;
// EXTRACTED: }
// Miss時にマガジンへ大量リフィルせず、1個だけ確保して即返すオプション
// Env: HAKMEM_TINY_REFILL_ONE_ON_MISS=1 で有効(デフォルト: 0
int g_refill_one_on_miss = 0;
// Frontend fill target per class (adaptive)
// NOTE: Non-static because used in hakmem_tiny_refill.inc.h
_Atomic uint32_t g_frontend_fill_target[TINY_NUM_CLASSES];
// Adaptive CAS: Active thread counter (for single-threaded optimization)
// Incremented on thread init, decremented on thread shutdown
_Atomic uint32_t g_hakmem_active_threads = 0;
// Per-thread registration flag (TLS variable)
static __thread int g_thread_registered = 0;
// Adaptive CAS: Register current thread (called on first allocation)
// NOTE: Non-static for cross-TU visibility (called from hak_alloc_api.inc.h)
__attribute__((always_inline))
inline void hakmem_thread_register(void) {
if (__builtin_expect(g_thread_registered == 0, 0)) {
g_thread_registered = 1;
atomic_fetch_add_explicit(&g_hakmem_active_threads, 1, memory_order_relaxed);
}
}
// SLL capacity override array (moved from deleted hakmem_tiny_ultra_batch_box.inc)
static int g_ultra_batch_override[TINY_NUM_CLASSES] = {0};
static int g_ultra_sll_cap_override[TINY_NUM_CLASSES] = {0};
// Helper function for batch size (moved from deleted hakmem_tiny_ultra_batch_box.inc)
static inline int ultra_batch_for_class(int class_idx) {
int ov = g_ultra_batch_override[class_idx];
if (ov > 0) return ov;
switch (class_idx) {
case 0: return 64; // 8B
case 1: return 96; // 16B
case 2: return 96; // 32B
case 3: return 224; // 64B
case 4: return 96; // 128B
case 5: return 64; // 256B
case 6: return 64; // 512B
default: return 32; // 1024B and others
}
}
// Helper function for SLL capacity (moved from deleted hakmem_tiny_ultra_batch_box.inc)
static inline int ultra_sll_cap_for_class(int class_idx) {
int ov = g_ultra_sll_cap_override[class_idx];
if (ov > 0) return ov;
switch (class_idx) {
case 0: return 256; // 8B
case 1: return 384; // 16B
case 2: return 384; // 32B
case 3: return 768; // 64B
case 4: return 256; // 128B
default: return 128; // others
}
}
enum { HAK_TIER_SLL=1, HAK_TIER_MAG=2, HAK_TIER_SLAB=3, HAK_TIER_SUPER=4, HAK_TIER_FRONT=5 };
// Event Queue & Telemetry Helpers - EXTRACTED to hakmem_tiny_eventq_box.inc
#include "hakmem_tiny_eventq_box.inc"
// Background refill workers and intelligence engine
#include "hakmem_tiny_background.inc"
// ============================================================================
// EXTRACTED TO hakmem_tiny_fastcache.inc.h (Phase 2D-1)
// ============================================================================
// Functions: fastcache_pop(), fastcache_push(), quick_pop() - 25 lines (lines 873-896)
// Ultra-fast try-only variant: attempt a direct SuperSlab bump/freelist pop
// without any refill or slow-path work. Returns NULL on miss.
static inline void* hak_tiny_alloc_superslab_try_fast(int class_idx) {
if (!g_use_superslab) return NULL;
TinyTLSSlab* tls = &g_tls_slabs[class_idx];
TinySlabMeta* meta = tls->meta;
if (!meta) return NULL;
// Try linear (bump) allocation first when freelist is empty
if (meta->freelist == NULL && meta->used < meta->capacity && tls->slab_base) {
// Use per-slab class_idx to get stride
size_t block_size = tiny_stride_for_class(meta->class_idx);
void* block = tls->slab_base + ((size_t)meta->used * block_size);
meta->used++;
// Track active blocks in SuperSlab for conservative reclamation
ss_active_inc(tls->ss);
return block;
}
// Do not pop freelist here (keep magazine/SLL handling consistent)
return NULL;
}
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Functions: quick_refill_from_sll(), quick_refill_from_mag() - 31 lines (lines 918-949)
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Function: sll_refill_small_from_ss() - 45 lines (lines 952-996)
// Phase 2C-3: TLS operations module (included after helper function definitions)
#include "hakmem_tiny_tls_ops.h"
// New TLS list refill: owner-only bulk take from TLS-cached SuperSlab slab
// ============================================================================
// EXTRACTED TO hakmem_tiny_tls_ops.h (Phase 2C-3)
// ============================================================================
// Function: tls_refill_from_tls_slab() - 101 lines
// Hot path refill operation, moved to inline function in header
// ============================================================================
// EXTRACTED TO hakmem_tiny_tls_ops.h (Phase 2C-3)
// ============================================================================
// Function: tls_list_spill_excess() - 97 lines
// Hot path spill operation, moved to inline function in header
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Function: superslab_tls_bump_fast() - 45 lines (lines 1016-1060)
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Function: frontend_refill_fc() - 44 lines (lines 1063-1106)
// SLL capacity policy: for hot tiny classes (0..3), allow larger SLL up to multiplier * mag_cap
// for >=4 keep current conservative half (to limit footprint).
// SLL Capacity Policy - EXTRACTED to hakmem_tiny_sll_cap_box.inc
#include "hakmem_tiny_sll_cap_box.inc"
// ============================================================================
// EXTRACTED TO hakmem_tiny_refill.inc.h (Phase 2D-1)
// ============================================================================
// Function: bulk_mag_to_sll_if_room() - 22 lines (lines 1133-1154)
// Ultra-Mode Batch Configuration - REMOVED (dead code cleanup 2025-11-27)
#include "hakmem_tiny_remote.inc"
// ============================================================================
// Internal Helpers
// ============================================================================
// Step 2: Slab Registry Operations
// Hash function for slab_base (64KB aligned)
// ============================================================================
// EXTRACTED TO hakmem_tiny_registry.c (Phase 2B-3)
// ============================================================================
// EXTRACTED: static inline int registry_hash(uintptr_t slab_base) {
// EXTRACTED: return (slab_base >> 16) & SLAB_REGISTRY_MASK;
// EXTRACTED: }
// Register slab in hash table (returns 1 on success, 0 on failure)
// EXTRACTED: static int registry_register(uintptr_t slab_base, TinySlab* owner) {
// EXTRACTED: pthread_mutex_lock(&g_tiny_registry_lock);
// EXTRACTED: int hash = registry_hash(slab_base);
// EXTRACTED:
// EXTRACTED: // Linear probing (max 8 attempts)
// EXTRACTED: for (int i = 0; i < SLAB_REGISTRY_MAX_PROBE; i++) {
// EXTRACTED: int idx = (hash + i) & SLAB_REGISTRY_MASK;
// EXTRACTED: SlabRegistryEntry* entry = &g_slab_registry[idx];
// EXTRACTED:
// EXTRACTED: if (entry->slab_base == 0) {
// EXTRACTED: // Empty slot found
// EXTRACTED: entry->slab_base = slab_base;
// EXTRACTED: atomic_store_explicit(&entry->owner, owner, memory_order_release);
// EXTRACTED: pthread_mutex_unlock(&g_tiny_registry_lock);
// EXTRACTED: return 1;
// EXTRACTED: }
// EXTRACTED: }
// EXTRACTED:
// EXTRACTED: // Registry full (collision limit exceeded)
// EXTRACTED: pthread_mutex_unlock(&g_tiny_registry_lock);
// EXTRACTED: return 0;
// EXTRACTED: }
// Unregister slab from hash table
// EXTRACTED: static void registry_unregister(uintptr_t slab_base) {
// EXTRACTED: pthread_mutex_lock(&g_tiny_registry_lock);
// EXTRACTED: int hash = registry_hash(slab_base);
// EXTRACTED:
// EXTRACTED: // Linear probing search
// EXTRACTED: for (int i = 0; i < SLAB_REGISTRY_MAX_PROBE; i++) {
// EXTRACTED: int idx = (hash + i) & SLAB_REGISTRY_MASK;
// EXTRACTED: SlabRegistryEntry* entry = &g_slab_registry[idx];
// EXTRACTED:
// EXTRACTED: if (entry->slab_base == slab_base) {
// EXTRACTED: // Found - clear entry (atomic store prevents TOCTOU race)
// EXTRACTED: atomic_store_explicit(&entry->owner, NULL, memory_order_release);
// EXTRACTED: entry->slab_base = 0;
// EXTRACTED: pthread_mutex_unlock(&g_tiny_registry_lock);
// EXTRACTED: return;
// EXTRACTED: }
// EXTRACTED:
// EXTRACTED: if (entry->slab_base == 0) {
// EXTRACTED: // Empty slot - not found
// EXTRACTED: pthread_mutex_unlock(&g_tiny_registry_lock);
// EXTRACTED: return;
// EXTRACTED: }
// EXTRACTED: }
// EXTRACTED: pthread_mutex_unlock(&g_tiny_registry_lock);
// EXTRACTED: }
// Lookup slab by base address (O(1) average)
// ============================================================================
// Registry Lookup & Owner Slab Discovery - EXTRACTED to hakmem_tiny_slab_lookup_box.inc
// ============================================================================
#include "hakmem_tiny_slab_lookup_box.inc"
// Function: move_to_full_list() - 20 lines (lines 1104-1123)
// Move slab to full list
// Function: move_to_free_list() - 20 lines (lines 1126-1145)
// Move slab to free list
// ============================================================================
// Public API
// ============================================================================
// ============================================================================
// Phase 2D-2: Initialization function (extracted to hakmem_tiny_init.inc)
// ============================================================================
#include "hakmem_tiny_init.inc"
// ============================================================================
// 3-Layer Architecture (2025-11-01 Simplification)
// ============================================================================
// Layer 1: TLS Bump Allocator (ultra-fast, 2-3 instructions/op)
#include "hakmem_tiny_bump.inc.h"
// Layer 2: TLS Small Magazine (fast, 5-10 instructions/op)
#include "hakmem_tiny_smallmag.inc.h"
// ============================================================================
// Phase 6 Fast Path Options (mutually exclusive)
// ============================================================================
// Choose ONE of the following Phase 6 optimizations:
//
// Phase 6-1.5: Alignment Guessing (LEGACY - committed 2025-11-02)
// - Enable: -DHAKMEM_TINY_PHASE6_ULTRA_SIMPLE=1
// - Speed: 235 M ops/sec
// - Memory: 0% overhead
// - Method: Guess size class from pointer alignment (__builtin_ctzl)
// - Risk: Alignment assumptions may break with future changes
//
// Phase 6-1.6: Metadata Header (NEW - recommended for production)
// - Enable: -DHAKMEM_TINY_PHASE6_METADATA=1
// - Speed: 450-480 M ops/sec (expected, Phase 6-1 level)
// - Memory: ~6-12% overhead (8 bytes/allocation)
// - Method: Store pool_type + size_class in 8-byte header
// - Benefit: Extends to ALL pools (Tiny/Mid/L25/Whale)
// - Eliminates: Registry lookups, mid_lookup, owner checks
// ============================================================================
// Forward declarations for Phase 6 alloc/free functions
#ifdef HAKMEM_TINY_PHASE6_ULTRA_SIMPLE
void* hak_tiny_alloc_ultra_simple(size_t size);
void hak_tiny_free_ultra_simple(void* ptr);
#endif
#if defined(HAKMEM_TINY_PHASE6_METADATA) && defined(HAKMEM_TINY_PHASE6_ULTRA_SIMPLE)
#error "Cannot enable both PHASE6_METADATA and PHASE6_ULTRA_SIMPLE"
#endif
// ============================================================================
// Phase 6 Wrapper Functions - EXTRACTED to hakmem_tiny_phase6_wrappers_box.inc
// ============================================================================
#include "hakmem_tiny_phase6_wrappers_box.inc"
// Layer 1-3: Main allocation function (simplified)
// Build-time configurable via: -DHAKMEM_TINY_USE_NEW_3LAYER=1
#ifndef HAKMEM_TINY_USE_NEW_3LAYER
#define HAKMEM_TINY_USE_NEW_3LAYER 0 // default OFF (legacy path)
#endif
#if HAKMEM_TINY_USE_NEW_3LAYER
#include "hakmem_tiny_alloc_new.inc"
#else
// Old 6-7 layer architecture (backup)
#include "hakmem_tiny_alloc.inc"
#endif
#include "hakmem_tiny_slow.inc"
// Free path implementations
#include "hakmem_tiny_free.inc"
// ---- Phase 1: Provide default batch-refill symbol (fallback to small refill)
// Allows runtime gate HAKMEM_TINY_REFILL_BATCH=1 without requiring a rebuild.
#ifndef HAKMEM_TINY_P0_BATCH_REFILL
int sll_refill_small_from_ss(int class_idx, int max_take);
__attribute__((weak)) int sll_refill_batch_from_ss(int class_idx, int max_take)
{
return sll_refill_small_from_ss(class_idx, max_take);
}
#endif
// ============================================================================
// EXTRACTED TO hakmem_tiny_lifecycle.inc (Phase 2D-3)
// ============================================================================
// Function: hak_tiny_trim() - 116 lines (lines 1164-1279)
// Public trim and cleanup operation for lifecycle management
// Forward decl for internal registry lookup used by ultra safety validation
static TinySlab* registry_lookup(uintptr_t slab_base);
// ultra_sll_cap_for_class moved earlier in file (before hakmem_tiny_free.inc)
static inline int ultra_validate_sll_head(int class_idx, void* head) {
uintptr_t base = ((uintptr_t)head) & ~(TINY_SLAB_SIZE - 1);
TinySlab* owner = registry_lookup(base);
if (!owner) return 0;
uintptr_t start = (uintptr_t)owner->base;
if ((uintptr_t)head < start || (uintptr_t)head >= start + TINY_SLAB_SIZE) return 0;
return (owner->class_idx == class_idx);
}
// Optional: wrapper TLS guardラッパー再入検知をTLSカウンタで
#ifndef HAKMEM_WRAPPER_TLS_GUARD
#define HAKMEM_WRAPPER_TLS_GUARD 0
#endif
#if HAKMEM_WRAPPER_TLS_GUARD
extern __thread int g_tls_in_wrapper;
#endif
// ============================================================================
// EXTRACTED TO hakmem_tiny_lifecycle.inc (Phase 2D-3)
// ============================================================================
// Function: tiny_tls_cache_drain() - 90 lines (lines 1314-1403)
// Static function for draining TLS caches
//
// Function: tiny_apply_mem_diet() - 20 lines (lines 1405-1424)
// Static function for memory diet mode application
//
// Phase 2D-3: Lifecycle management functions (226 lines total)
#include "hakmem_tiny_lifecycle.inc"
// Phase 2D-4 (FINAL): Slab management functions (142 lines total)
#include "hakmem_tiny_slab_mgmt.inc"
// Tiny Heap v2 stats dump (opt-in)
void tiny_heap_v2_print_stats(void) {
const char* env = getenv("HAKMEM_TINY_HEAP_V2_STATS");
if (!(env && *env && *env != '0')) return;
fprintf(stderr, "\n[HeapV2] TLS magazine stats (per class, thread-local)\n");
for (int cls = 0; cls < TINY_NUM_CLASSES; cls++) {
TinyHeapV2Mag* mag = &g_tiny_heap_v2_mag[cls];
TinyHeapV2Stats* st = &g_tiny_heap_v2_stats[cls];
fprintf(stderr,
"C%d: top=%d alloc_calls=%llu mag_hits=%llu refill_calls=%llu refill_blocks=%llu backend_oom=%llu\n",
cls,
mag->top,
(unsigned long long)st->alloc_calls,
(unsigned long long)st->mag_hits,
(unsigned long long)st->refill_calls,
(unsigned long long)st->refill_blocks,
(unsigned long long)st->backend_oom);
}
}
static void tiny_heap_v2_stats_atexit(void) __attribute__((destructor));
static void tiny_heap_v2_stats_atexit(void) {
tiny_heap_v2_print_stats();
}
// Size→class routing for >=1024B (env: HAKMEM_TINY_ALLOC_1024_METRIC)
_Atomic uint64_t g_tiny_alloc_ge1024[TINY_NUM_CLASSES] = {0};
static void tiny_alloc_1024_diag_atexit(void) __attribute__((destructor));
static void tiny_alloc_1024_diag_atexit(void) {
const char* env = getenv("HAKMEM_TINY_ALLOC_1024_METRIC");
if (!(env && *env && *env != '0')) return;
fprintf(stderr, "\n[ALLOC_GE1024] per-class counts (size>=1024)\n");
for (int cls = 0; cls < TINY_NUM_CLASSES; cls++) {
uint64_t v = atomic_load_explicit(&g_tiny_alloc_ge1024[cls], memory_order_relaxed);
if (v) {
fprintf(stderr, " C%d=%llu", cls, (unsigned long long)v);
}
}
fprintf(stderr, "\n");
}
// TLS SLL pointer diagnostics (optional)
extern _Atomic uint64_t g_tls_sll_invalid_head[TINY_NUM_CLASSES];
extern _Atomic uint64_t g_tls_sll_invalid_push[TINY_NUM_CLASSES];
static void tiny_tls_sll_diag_atexit(void) __attribute__((destructor));
static void tiny_tls_sll_diag_atexit(void) {
const char* env = getenv("HAKMEM_TINY_SLL_DIAG");
if (!(env && *env && *env != '0')) return;
fprintf(stderr, "\n[TLS_SLL_DIAG] invalid head/push counts per class\n");
for (int cls = 0; cls < TINY_NUM_CLASSES; cls++) {
uint64_t ih = atomic_load_explicit(&g_tls_sll_invalid_head[cls], memory_order_relaxed);
uint64_t ip = atomic_load_explicit(&g_tls_sll_invalid_push[cls], memory_order_relaxed);
if (ih || ip) {
fprintf(stderr, " C%d: invalid_head=%llu invalid_push=%llu\n",
cls, (unsigned long long)ih, (unsigned long long)ip);
}
}
}
// ============================================================================
// ACE Learning Layer & Tiny Guard - EXTRACTED to hakmem_tiny_ace_guard_box.inc
// ============================================================================
#include "hakmem_tiny_ace_guard_box.inc"