Files
hakmem/core/smallobject_cold_iface_v6.c
Moe Charm (CI) 7b7de53167 Phase FREE-FRONT-V3-1: Free route snapshot infrastructure + build fix
Summary:
========
Implemented Phase FREE-FRONT-V3 infrastructure to optimize free hotpath by:
1. Creating snapshot-based route decision table (consolidating route logic)
2. Removing redundant ENV checks from hot path
3. Preparing for future integration into hak_free_at()

Key Changes:
============

1. NEW FILES:
   - core/box/free_front_v3_env_box.h: Route snapshot definition & API
   - core/box/free_front_v3_env_box.c: Snapshot initialization & caching

2. Infrastructure Details:
   - FreeRouteSnapshotV3: Maps class_idx → free_route_kind for all 8 classes
   - Routes defined: LEGACY, TINY_V3, CORE_V6_C6, POOL_V1
   - ENV-gated initialization (HAKMEM_TINY_FREE_FRONT_V3_ENABLED, default OFF)
   - Per-thread TLS caching to avoid repeated ENV reads

3. Design Goals:
   - Consolidate tiny_route_for_class() results into snapshot table
   - Remove C7 ULTRA / v4 / v5 / v6 ENV checks from hot path
   - Limit lookup (ss_fast_lookup/slab_index_for) to paths that truly need it
   - Clear ownership boundary: front v3 handles routing, downstream handles free

4. Phase Plan:
   - v3-1  COMPLETE: Infrastructure (snapshot table, ENV initialization, TLS cache)
   - v3-2 (INFRASTRUCTURE ONLY): Placeholder integration in hak_free_api.inc.h
   - v3-3 (FUTURE): Full integration + benchmark A/B to measure hotpath improvement

5. BUILD FIX:
   - Added missing core/box/c7_meta_used_counter_box.o to OBJS_BASE in Makefile
   - This symbol was referenced but not linked, causing undefined reference errors
   - Benchmark targets now build cleanly without LTO

Status:
=======
- Build:  PASS (bench_allocators_hakmem builds without errors)
- Integration: Currently DISABLED (default OFF, ready for v3-2 phase)
- No performance impact: Infrastructure-only, hotpath unchanged

Future Work:
============
- Phase v3-2: Integrate snapshot routing into hak_free_at() main path
- Phase v3-3: Measure free hotpath performance improvement (target: 1-2% less branch mispredict)

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

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-11 19:17:30 +09:00

100 lines
2.8 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.

// smallobject_cold_iface_v6.c - SmallObject ColdIface v6 実装Phase v6-3
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "box/smallobject_cold_iface_v6.h"
#include "box/smallsegment_v6_box.h"
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// Refill page for given class (C6, C5, C4 in v6-6)
SmallPageMetaV6* small_cold_v6_refill_page(uint32_t class_idx) {
// v6-6: Support C4, C5, and C6
size_t block_size;
if (class_idx == SMALL_V6_C6_CLASS_IDX) {
block_size = SMALL_V6_C6_BLOCK_SIZE; // 512
} else if (class_idx == SMALL_V6_C5_CLASS_IDX) {
block_size = SMALL_V6_C5_BLOCK_SIZE; // 256
} else if (class_idx == SMALL_V6_C4_CLASS_IDX) {
block_size = SMALL_V6_C4_BLOCK_SIZE; // 128
} else {
return NULL; // Unsupported class
}
// Get or acquire TLS segment
SmallSegmentV6* seg = small_segment_v6_acquire_for_thread();
if (unlikely(!seg)) {
return NULL;
}
// Find an available page (simple linear scan)
SmallPageMetaV6* page = NULL;
for (uint32_t i = 0; i < seg->num_pages; i++) {
if (seg->page_meta[i].capacity == 0) {
page = &seg->page_meta[i];
break;
}
}
if (unlikely(!page)) {
return NULL; // All pages in use
}
// Initialize page metadata
page->class_idx = (uint8_t)class_idx;
page->capacity = SMALL_PAGE_V6_SIZE / block_size; // C6: 128, C5: 256
page->used = 0;
page->flags = 0;
// Build freelist for the page
uintptr_t page_offset = (uintptr_t)page->page_idx * SMALL_PAGE_V6_SIZE;
uintptr_t page_base = seg->base + page_offset;
uint8_t* base = (uint8_t*)page_base;
// Build intrusive freelist (last to first for cache locality)
void* freelist = NULL;
for (int i = (int)page->capacity - 1; i >= 0; i--) {
uint8_t* block = base + ((size_t)i * block_size);
// Build freelist using BASE pointers
void* next = freelist;
memcpy(block, &next, sizeof(void*));
freelist = block;
}
page->free_list = freelist;
return page;
}
// Retire page (simple reset for v6-2)
void small_cold_v6_retire_page(SmallPageMetaV6* page) {
if (unlikely(!page)) {
return;
}
// v6-2: Simple reset (no actual deallocation)
page->free_list = NULL;
page->used = 0;
page->capacity = 0;
page->class_idx = 0;
page->flags = 0;
}
// Remote operations (dummy for v6-2, C6-heavy is mostly same-thread)
void small_cold_v6_remote_push(SmallPageMetaV6* page, void* ptr, uint32_t tid) {
(void)page;
(void)ptr;
(void)tid;
// Not implemented in v6-2
}
void small_cold_v6_remote_drain(SmallHeapCtxV6* ctx) {
(void)ctx;
// Not implemented in v6-2
}