// smallobject_mid_v35.c // Phase v11a-3: MID v3.5 HotBox implementation // // Design: // - TLS-cached page for fast allocation // - Refill via ColdIface when page exhausted // - Retire via ColdIface when page is full // - Stats/Learner integration for observability #include #include #include #include "box/smallobject_mid_v35_box.h" #include "box/smallobject_segment_mid_v3_box.h" #include "box/smallobject_cold_iface_mid_v3_box.h" #include "box/smallobject_mid_v35_geom_box.h" // Phase MID-V35-HOTPATH-OPT-1: geometry SSOT #include "box/mid_v35_hotpath_env_box.h" // Phase MID-V35-HOTPATH-OPT-1: Step 1-3 ENV gates #include "tiny_region_id.h" // For tiny_region_id_write_header // SmallPageMeta is defined in smallobject_segment_mid_v3_box.h // (included via smallobject_cold_iface_mid_v3_box.h) // ============================================================================ // TLS Context (per-thread fast path state) // ============================================================================ typedef struct { void *page[8]; // Current page per class uint32_t offset[8]; // Allocation offset (slot index) uint32_t capacity[8]; // Slots per page per class SmallPageMeta_MID_v3 *meta[8]; // Page metadata for retire check } SmallMidV35TlsCtx; static __thread SmallMidV35TlsCtx tls_mid_v35_ctx = {0}; // ============================================================================ // Slot Configuration (C5/C6/C7) // ============================================================================ // Phase MID-V35-HOTPATH-OPT-1: Use geom_box as Single Source of Truth // See: core/box/smallobject_mid_v35_geom_box.h // ============================================================================ // Init // ============================================================================ void small_mid_v35_init(void) { // Initialize any global state if needed // For v11a-3: nothing to do (TLS is zero-initialized) } // ============================================================================ // Alloc // ============================================================================ void* small_mid_v35_alloc(uint32_t class_idx, size_t size) { (void)size; // Unused for now if (class_idx < 5 || class_idx > 7) return NULL; // Only C5-C7 SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx; // ======================================================================== // Step 3: C6 specialized fast path (constant slot size = 512) // ======================================================================== if (mid_v35_c6_fastpath_enabled() && class_idx == 6) { void *page = ctx->page[6]; uint32_t off = ctx->offset[6]; if (page && off < ctx->capacity[6]) { // C6: slot_size = 512 (constant, compiler can optimize) void *base = (char*)page + off * 512; ctx->offset[6] = off + 1; // Step 2: HOT_COUNTS gate if (mid_v35_hot_counts_enabled() && ctx->meta[6]) { ctx->meta[6]->alloc_count++; } // Step 1: HEADER_PREFILL gate if (!mid_v35_header_prefill_enabled()) { tiny_region_id_write_header(base, 6); } return (char*)base + 1; } // Fall through to slow path } // ======================================================================== // Generic fast path: allocate from TLS cached page // ======================================================================== if (ctx->page[class_idx] && ctx->offset[class_idx] < ctx->capacity[class_idx]) { size_t slot_size = mid_v35_slot_size(class_idx); void *base = (char*)ctx->page[class_idx] + ctx->offset[class_idx] * slot_size; ctx->offset[class_idx]++; // Step 2: HOT_COUNTS gate - Update page metadata if (mid_v35_hot_counts_enabled() && ctx->meta[class_idx]) { ctx->meta[class_idx]->alloc_count++; } // Step 1: HEADER_PREFILL gate - Write header if not prefilled if (!mid_v35_header_prefill_enabled()) { tiny_region_id_write_header(base, class_idx); } // Return USER pointer (BASE + 1 byte header) return (char*)base + 1; } // ======================================================================== // Slow path: need new page via ColdIface // ======================================================================== SmallPageMeta_MID_v3 *page = small_cold_mid_v3_refill_page(class_idx); if (!page) { // Fallback to legacy or return NULL return NULL; } // Update TLS cache ctx->page[class_idx] = page->ptr; ctx->offset[class_idx] = 1; // First slot already allocated ctx->capacity[class_idx] = mid_v35_slots_per_page(class_idx); ctx->meta[class_idx] = page; // Step 2: HOT_COUNTS gate - Record first allocation in page metadata if (mid_v35_hot_counts_enabled()) { page->alloc_count = 1; } // Step 1: HEADER_PREFILL gate - Write header for first slot if not prefilled if (!mid_v35_header_prefill_enabled()) { tiny_region_id_write_header(page->ptr, class_idx); } // Return first slot (USER pointer) return (char*)page->ptr + 1; } // ============================================================================ // Free (Simplified: just count, no freelist yet) // ============================================================================ void small_mid_v35_free(void *ptr, uint32_t class_idx) { if (!ptr || class_idx < 5 || class_idx > 7) return; // For v11a-3: simplified free (just increment free_count) // In future phases: implement freelist for reuse // Calculate BASE from USER pointer void *base = (char*)ptr - 1; // Find page metadata via simple calculation // Note: Assumes 64KB pages aligned to 64KB boundary size_t page_size = 64 * 1024; // 64KB void *page_base = (void*)((uintptr_t)base & ~(page_size - 1)); // Check if this is the current TLS page SmallMidV35TlsCtx *ctx = &tls_mid_v35_ctx; SmallPageMeta_MID_v3 *meta = ctx->meta[class_idx]; if (meta && meta->ptr == page_base) { // Free to current TLS page meta->free_count++; // Check if page is fully empty if (meta->free_count >= meta->capacity) { // Retire page via ColdIface small_cold_mid_v3_retire_page(meta); // Clear TLS cache for this class ctx->page[class_idx] = NULL; ctx->offset[class_idx] = 0; ctx->meta[class_idx] = NULL; } } else { // Different page: need RegionIdBox lookup // For v11a-3: simple fallback - just count the free // Real implementation needs proper page lookup // TODO: Implement cross-page free via RegionIdBox in v11b } }