From 9830eff6ccd36448cb60941675b4342a069ec876 Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Thu, 11 Dec 2025 18:47:21 +0900 Subject: [PATCH] Phase FREE-LEGACY-OPT-4-4: C6 ULTRA free+alloc integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parasitic TLS cache: alloc now pops from the TLS freelist filled by free. Implementation: - malloc_tiny_fast(): C6 class-specific TLS pop check before route switch - if (class_idx == 6 && tiny_c6_ultra_free_enabled()) - pop from TinyC6UltraFreeTLS.freelist[--count] - return USER pointer (BASE + 1) - FreePathStats: Added c6_ultra_alloc_hit counter for observability Results (Mixed 16-1024B): - OFF: 40.2M ops/s baseline - ON: 42.2M ops/s (+4.9%) stable Per-profile: - Mixed: +4.9% (40.2M → 42.2M) - C6-heavy: +7.6% (40.7M → 43.8M) Free-alloc loop: - free: TLS push (all C6 frees) - alloc: TLS pop (all C6 allocs in steady state) - Cache never fills, no legacy overflow - C6 legacy_by_class reduced from 137K to 0 (100% elimination) Key insight: - Free-only TLS cache fails without alloc integration - Once integrated, creates perfect load-balancing loop - Alloc drains exactly what free fills 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- core/box/free_path_stats_box.c | 3 ++- core/box/free_path_stats_box.h | 3 ++- core/front/malloc_tiny_fast.h | 13 +++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/core/box/free_path_stats_box.c b/core/box/free_path_stats_box.c index 730eced9..7510767a 100644 --- a/core/box/free_path_stats_box.c +++ b/core/box/free_path_stats_box.c @@ -16,10 +16,11 @@ static void free_path_stats_dump(void) { return; } - fprintf(stderr, "[FREE_PATH_STATS] total=%lu c7_ultra=%lu c6_ultra_free=%lu small_v3=%lu v6=%lu tiny_v1=%lu pool_v1=%lu remote=%lu super_lookup=%lu legacy_fb=%lu\n", + fprintf(stderr, "[FREE_PATH_STATS] total=%lu c7_ultra=%lu c6_ultra_free=%lu c6_ultra_alloc=%lu small_v3=%lu v6=%lu tiny_v1=%lu pool_v1=%lu remote=%lu super_lookup=%lu legacy_fb=%lu\n", g_free_path_stats.total_calls, g_free_path_stats.c7_ultra_fast, g_free_path_stats.c6_ultra_free_fast, // Phase 4-2 + g_free_path_stats.c6_ultra_alloc_hit, // Phase 4-4 g_free_path_stats.smallheap_v3_fast, g_free_path_stats.smallheap_v6_fast, g_free_path_stats.tiny_heap_v1_fast, diff --git a/core/box/free_path_stats_box.h b/core/box/free_path_stats_box.h index 9c5843b7..b3487a23 100644 --- a/core/box/free_path_stats_box.h +++ b/core/box/free_path_stats_box.h @@ -9,7 +9,8 @@ typedef struct FreePathStats { uint64_t total_calls; uint64_t c7_ultra_fast; - uint64_t c6_ultra_free_fast; // Phase 4-2: C6 ULTRA-free + uint64_t c6_ultra_free_fast; // Phase 4-2: C6 ULTRA-free + uint64_t c6_ultra_alloc_hit; // Phase 4-4: C6 ULTRA-alloc (TLS pop) uint64_t smallheap_v3_fast; uint64_t smallheap_v6_fast; uint64_t tiny_heap_v1_fast; diff --git a/core/front/malloc_tiny_fast.h b/core/front/malloc_tiny_fast.h index dbcc38af..ee3a5968 100644 --- a/core/front/malloc_tiny_fast.h +++ b/core/front/malloc_tiny_fast.h @@ -188,6 +188,19 @@ static inline void* malloc_tiny_fast(size_t size) { // fallback to existing route on miss } + // Phase 4-4: C6 ULTRA free+alloc integration (寄生型 TLS キャッシュ pop) + if (class_idx == 6 && tiny_c6_ultra_free_enabled()) { + TinyC6UltraFreeTLS* ctx = tiny_c6_ultra_free_tls(); + if (TINY_HOT_LIKELY(ctx->count > 0)) { + void* base = ctx->freelist[--ctx->count]; + // Phase 4-4: カウンタ散布 (TLS pop) + FREE_PATH_STAT_INC(c6_ultra_alloc_hit); + // BASE pointer のまま、USER pointer に変換して返す + // (header は既に base[0] にある前提) + return (uint8_t*)base + 1; + } + } + switch (route) { case TINY_ROUTE_SMALL_HEAP_V6: { // Phase FREE-LEGACY-BREAKDOWN-1: v6 は既存のビルドエラーがあるため一時的にスキップ