Phase FREE-LEGACY-OPT-4-4: C6 ULTRA free+alloc integration

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 <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-11 18:47:21 +09:00
parent 1b196b3ac0
commit 9830eff6cc
3 changed files with 17 additions and 2 deletions

View File

@ -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 は既存のビルドエラーがあるため一時的にスキップ