Add v4 C7/C6 fast classify and small-segment v4 scaffolding
This commit is contained in:
@ -5,8 +5,9 @@
|
||||
// - 挙動はまだ v3/v1 のまま。alloc/free 本体は後続フェーズで実装する。
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tiny_geometry_box.h"
|
||||
|
||||
@ -46,3 +47,4 @@ small_heap_ctx_v4* small_heap_ctx_v4_get(void);
|
||||
// Hot path API (C7-only stub; later phases will expand)
|
||||
void* small_heap_alloc_fast_v4(small_heap_ctx_v4* ctx, int class_idx);
|
||||
void small_heap_free_fast_v4(small_heap_ctx_v4* ctx, int class_idx, void* ptr);
|
||||
int smallobject_hotbox_v4_can_own(int class_idx, void* ptr);
|
||||
|
||||
@ -47,3 +47,7 @@ static inline int small_heap_v4_c7_enabled(void) {
|
||||
static inline int small_heap_v4_c6_enabled(void) {
|
||||
return small_heap_v4_class_enabled(6);
|
||||
}
|
||||
|
||||
static inline int small_heap_v4_c5_enabled(void) {
|
||||
return small_heap_v4_class_enabled(5);
|
||||
}
|
||||
|
||||
11
core/box/smallsegment_v4_box.h
Normal file
11
core/box/smallsegment_v4_box.h
Normal file
@ -0,0 +1,11 @@
|
||||
// smallsegment_v4_box.h - Small-object専用 Segment Box の宣言だけを置く足場
|
||||
// Phase PF2: 挙動はまだ変えず、型と API だけを先行定義する。
|
||||
#pragma once
|
||||
|
||||
typedef struct small_segment_v4 small_segment_v4;
|
||||
|
||||
// class_idx ごとに小さな Segment を確保/再利用する想定。
|
||||
// まだ実装はなく、次フェーズで Superslab/OS との接続を決める。
|
||||
small_segment_v4* smallsegment_v4_acquire(int class_idx);
|
||||
void* smallsegment_v4_alloc_page(small_segment_v4* seg, int class_idx);
|
||||
void smallsegment_v4_release_if_empty(small_segment_v4* seg);
|
||||
28
core/box/smallsegment_v4_env_box.h
Normal file
28
core/box/smallsegment_v4_env_box.h
Normal file
@ -0,0 +1,28 @@
|
||||
// smallsegment_v4_env_box.h - small-object segment v4 の ENV ゲート
|
||||
// Phase PF2: ENV を宣言するだけ。実装は次フェーズで追加。
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline int smallsegment_v4_enabled(void) {
|
||||
static int g = -1;
|
||||
if (__builtin_expect(g == -1, 0)) {
|
||||
const char* e = getenv("HAKMEM_SMALL_SEGMENT_V4_ENABLED");
|
||||
if (e && *e && *e != '0') {
|
||||
g = 1;
|
||||
} else {
|
||||
g = 0;
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
static inline const char* smallsegment_v4_size_env(void) {
|
||||
static int g_init = 0;
|
||||
static const char* g_val = NULL;
|
||||
if (__builtin_expect(!g_init, 0)) {
|
||||
g_val = getenv("HAKMEM_SMALL_SEGMENT_V4_SIZE");
|
||||
g_init = 1;
|
||||
}
|
||||
return g_val;
|
||||
}
|
||||
@ -77,6 +77,16 @@ static inline bool tiny_ptr_fast_classify_enabled(void) {
|
||||
return g != 0;
|
||||
}
|
||||
|
||||
// C7/C6 v4 free 用 fast classify gate (default OFF)
|
||||
static inline bool tiny_ptr_fast_classify_v4_enabled(void) {
|
||||
static int g = -1;
|
||||
if (__builtin_expect(g == -1, 0)) {
|
||||
const char* e = getenv("HAKMEM_TINY_PTR_FAST_CLASSIFY_V4_ENABLED");
|
||||
g = (e && *e && *e != '0') ? 1 : 0;
|
||||
}
|
||||
return g != 0;
|
||||
}
|
||||
|
||||
// Optional stats gate
|
||||
static inline bool tiny_front_v3_stats_enabled(void) {
|
||||
static int g = -1;
|
||||
|
||||
@ -252,6 +252,15 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
}
|
||||
|
||||
tiny_route_kind_t route = tiny_route_for_class((uint8_t)class_idx);
|
||||
|
||||
if ((class_idx == 7 || class_idx == 6) &&
|
||||
route == TINY_ROUTE_SMALL_HEAP_V4 &&
|
||||
tiny_ptr_fast_classify_v4_enabled() &&
|
||||
smallobject_hotbox_v4_can_own(class_idx, base)) {
|
||||
small_heap_free_fast_v4(small_heap_ctx_v4_get(), class_idx, base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const int use_tiny_heap = tiny_route_is_heap_kind(route);
|
||||
const TinyFrontV3Snapshot* front_snap =
|
||||
__builtin_expect(tiny_front_v3_enabled(), 0) ? tiny_front_v3_snapshot_get() : NULL;
|
||||
@ -319,7 +328,7 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
if (__builtin_expect(use_tiny_heap, 0)) {
|
||||
switch (route) {
|
||||
case TINY_ROUTE_SMALL_HEAP_V4:
|
||||
if (class_idx == 7 || class_idx == 6) {
|
||||
if (class_idx == 7 || class_idx == 6 || class_idx == 5) {
|
||||
small_heap_free_fast_v4(small_heap_ctx_v4_get(), class_idx, base);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// smallobject_hotbox_v4.c - SmallObject HotHeap v4 (C7-only real path)
|
||||
// smallobject_hotbox_v4.c - SmallObject HotHeap v4 (C5/C6/C7 opt-in)
|
||||
//
|
||||
// Phase v4-3: C7 クラスについては v4 独自の freelist/current/partial で完結させる。
|
||||
// Phase v4-3.1: C7 は v4 独自の freelist/current/partial で完結。C6/C5 は強ゲート付きで同形パスを使う。
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -17,8 +17,6 @@
|
||||
// TLS context
|
||||
static __thread small_heap_ctx_v4 g_ctx_v4;
|
||||
|
||||
#define V4_MAX_PARTIAL_PAGES 1
|
||||
|
||||
small_heap_ctx_v4* small_heap_ctx_v4_get(void) {
|
||||
return &g_ctx_v4;
|
||||
}
|
||||
@ -27,6 +25,10 @@ small_heap_ctx_v4* small_heap_ctx_v4_get(void) {
|
||||
// helpers
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static inline int v4_class_supported(int class_idx) {
|
||||
return class_idx == 7 || class_idx == 6 || class_idx == 5;
|
||||
}
|
||||
|
||||
static inline void v4_page_push_partial(small_class_heap_v4* h, small_page_v4* page) {
|
||||
if (!h || !page) return;
|
||||
page->next = h->partial_head;
|
||||
@ -53,6 +55,11 @@ static inline void v4_page_push_full(small_class_heap_v4* h, small_page_v4* page
|
||||
h->full_head = page;
|
||||
}
|
||||
|
||||
static inline uint32_t v4_partial_limit(int class_idx) {
|
||||
// C7 は refill/retire を抑えるため少し広めに保持
|
||||
return (class_idx == 7) ? 2u : 1u;
|
||||
}
|
||||
|
||||
static inline int v4_ptr_in_page(const small_page_v4* page, const uint8_t* ptr) {
|
||||
if (!page || !ptr) return 0;
|
||||
uint8_t* base = page->base;
|
||||
@ -97,16 +104,32 @@ static small_page_v4* v4_find_page(small_class_heap_v4* h, const uint8_t* ptr, v
|
||||
return p;
|
||||
}
|
||||
}
|
||||
// full リストは探さない(v4 C7 は partial/current だけで完結する想定)
|
||||
for (small_page_v4* p = h->full_head; p; prev = p, p = p->next) {
|
||||
if (v4_ptr_in_page(p, ptr)) {
|
||||
if (loc) *loc = V4_LOC_FULL;
|
||||
if (prev_out) *prev_out = prev;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int smallobject_hotbox_v4_can_own(int class_idx, void* ptr) {
|
||||
if (__builtin_expect(!v4_class_supported(class_idx), 0)) return 0;
|
||||
if (!small_heap_v4_class_enabled((uint8_t)class_idx)) return 0;
|
||||
if (!ptr) return 0;
|
||||
small_heap_ctx_v4* ctx = small_heap_ctx_v4_get();
|
||||
if (!ctx) return 0;
|
||||
small_class_heap_v4* h = &ctx->cls[class_idx];
|
||||
return v4_find_page(h, (const uint8_t*)ptr, NULL, NULL) != NULL;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Cold iface (C7-only, Tiny v1 経由)
|
||||
// Cold iface (C5/C6/C7, Tiny v1 経由)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
static small_page_v4* cold_refill_page_v4(small_heap_ctx_v4* hot_ctx, uint32_t class_idx) {
|
||||
if (__builtin_expect(class_idx != 7 && class_idx != 6, 0)) return NULL;
|
||||
if (__builtin_expect(!v4_class_supported((int)class_idx), 0)) return NULL;
|
||||
(void)hot_ctx;
|
||||
tiny_heap_ctx_t* tctx = tiny_heap_ctx_for_thread();
|
||||
if (!tctx) return NULL;
|
||||
@ -163,13 +186,14 @@ const SmallColdIfaceV4* small_cold_iface_v4_get(void) {
|
||||
|
||||
static small_page_v4* small_alloc_slow_v4(small_heap_ctx_v4* ctx, int class_idx) {
|
||||
small_class_heap_v4* h = &ctx->cls[class_idx];
|
||||
const uint32_t partial_limit = v4_partial_limit(class_idx);
|
||||
small_page_v4* cur = h->current;
|
||||
if (cur && cur->freelist) {
|
||||
return cur; // usable current
|
||||
}
|
||||
if (cur && !cur->freelist) {
|
||||
// current をいったん partial/full に退避(partial を優先)
|
||||
if (h->partial_count < V4_MAX_PARTIAL_PAGES) {
|
||||
if (h->partial_count < partial_limit) {
|
||||
v4_page_push_partial(h, cur);
|
||||
} else {
|
||||
v4_page_push_full(h, cur);
|
||||
@ -193,8 +217,8 @@ static small_page_v4* small_alloc_slow_v4(small_heap_ctx_v4* ctx, int class_idx)
|
||||
}
|
||||
|
||||
void* small_heap_alloc_fast_v4(small_heap_ctx_v4* ctx, int class_idx) {
|
||||
if (__builtin_expect(class_idx != 7 && class_idx != 6, 0)) {
|
||||
return NULL; // C6/C7 専用
|
||||
if (__builtin_expect(!v4_class_supported(class_idx), 0)) {
|
||||
return NULL; // C5/C6/C7 以外は未対応
|
||||
}
|
||||
if (!small_heap_v4_class_enabled((uint8_t)class_idx)) return NULL;
|
||||
small_class_heap_v4* h = &ctx->cls[class_idx];
|
||||
@ -240,7 +264,7 @@ static void v4_unlink_from_list(small_class_heap_v4* h, v4_loc_t loc, small_page
|
||||
}
|
||||
|
||||
void small_heap_free_fast_v4(small_heap_ctx_v4* ctx, int class_idx, void* ptr) {
|
||||
if (__builtin_expect(class_idx != 7 && class_idx != 6, 0)) {
|
||||
if (__builtin_expect(!v4_class_supported(class_idx), 0)) {
|
||||
return;
|
||||
}
|
||||
if (!small_heap_v4_class_enabled((uint8_t)class_idx)) return;
|
||||
@ -252,6 +276,8 @@ void small_heap_free_fast_v4(small_heap_ctx_v4* ctx, int class_idx, void* ptr) {
|
||||
small_page_v4* page = v4_find_page(h, (const uint8_t*)ptr, &loc, &prev);
|
||||
if (!page) return;
|
||||
|
||||
const uint32_t partial_limit = v4_partial_limit(class_idx);
|
||||
|
||||
// freelist push
|
||||
void* head = page->freelist;
|
||||
memcpy(ptr, &head, sizeof(void*));
|
||||
@ -274,7 +300,7 @@ void small_heap_free_fast_v4(small_heap_ctx_v4* ctx, int class_idx, void* ptr) {
|
||||
page->next = NULL;
|
||||
return;
|
||||
}
|
||||
if (h->partial_count < V4_MAX_PARTIAL_PAGES) {
|
||||
if (h->partial_count < partial_limit) {
|
||||
v4_page_push_partial(h, page);
|
||||
return;
|
||||
}
|
||||
@ -296,7 +322,7 @@ void small_heap_free_fast_v4(small_heap_ctx_v4* ctx, int class_idx, void* ptr) {
|
||||
} else if (loc == V4_LOC_FULL && page->freelist) {
|
||||
// full → partial に戻す(current があっても partial 上限までは復帰)
|
||||
v4_unlink_from_list(h, loc, prev, page);
|
||||
if (h->partial_count < V4_MAX_PARTIAL_PAGES) {
|
||||
if (h->partial_count < partial_limit) {
|
||||
v4_page_push_partial(h, page);
|
||||
} else {
|
||||
v4_page_push_full(h, page); // 上限超なら戻す
|
||||
|
||||
Reference in New Issue
Block a user