// smallobject_cold_iface_v6.c - SmallObject ColdIface v6 実装(Phase v6-3) #include #include #include #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 }