Guard madvise ENOMEM and stabilize pool/tiny front v3
This commit is contained in:
@ -40,6 +40,8 @@
|
||||
#include "../box/tiny_c7_hotbox.h" // Optional: C7 専用ホットボックス
|
||||
#include "../box/tiny_heap_box.h" // TinyHeap 汎用 Box
|
||||
#include "../box/tiny_hotheap_v2_box.h" // TinyHotHeap v2 (Phase31 A/B)
|
||||
#include "../box/smallobject_hotbox_v3_box.h" // SmallObject HotHeap v3 skeleton
|
||||
#include "../box/tiny_front_v3_env_box.h" // Tiny front v3 snapshot gate
|
||||
#include "../box/tiny_heap_env_box.h" // ENV gate for TinyHeap front (A/B)
|
||||
#include "../box/tiny_route_env_box.h" // Route snapshot (Heap vs Legacy)
|
||||
#include "../box/tiny_front_stats_box.h" // Front class distribution counters
|
||||
@ -102,24 +104,58 @@ static inline int front_gate_unified_enabled(void) {
|
||||
//
|
||||
__attribute__((always_inline))
|
||||
static inline void* malloc_tiny_fast(size_t size) {
|
||||
// size → class_idx を 1 回だけ決定
|
||||
int class_idx = hak_tiny_size_to_class(size);
|
||||
if (__builtin_expect(class_idx < 0 || class_idx >= TINY_NUM_CLASSES, 0)) {
|
||||
return NULL;
|
||||
const int front_v3_on = tiny_front_v3_enabled();
|
||||
const TinyFrontV3Snapshot* front_snap =
|
||||
__builtin_expect(front_v3_on, 0) ? tiny_front_v3_snapshot_get() : NULL;
|
||||
const bool route_fast_on = front_v3_on && tiny_front_v3_lut_enabled() &&
|
||||
tiny_front_v3_route_fast_enabled();
|
||||
|
||||
int class_idx = -1;
|
||||
tiny_route_kind_t route = TINY_ROUTE_LEGACY;
|
||||
bool route_trusted = false;
|
||||
|
||||
if (front_v3_on && tiny_front_v3_lut_enabled()) {
|
||||
const TinyFrontV3SizeClassEntry* e = tiny_front_v3_lut_lookup(size);
|
||||
if (e && e->class_idx != TINY_FRONT_V3_INVALID_CLASS) {
|
||||
class_idx = (int)e->class_idx;
|
||||
route = (tiny_route_kind_t)e->route_kind;
|
||||
route_trusted = route_fast_on;
|
||||
}
|
||||
}
|
||||
|
||||
if (__builtin_expect(class_idx < 0 || class_idx >= TINY_NUM_CLASSES, 0)) {
|
||||
class_idx = hak_tiny_size_to_class(size);
|
||||
if (__builtin_expect(class_idx < 0 || class_idx >= TINY_NUM_CLASSES, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
route = tiny_route_for_class((uint8_t)class_idx);
|
||||
route_trusted = false;
|
||||
} else if (!route_trusted &&
|
||||
route != TINY_ROUTE_LEGACY && route != TINY_ROUTE_HEAP &&
|
||||
route != TINY_ROUTE_HOTHEAP_V2 && route != TINY_ROUTE_SMALL_HEAP_V3) {
|
||||
route = tiny_route_for_class((uint8_t)class_idx);
|
||||
}
|
||||
|
||||
tiny_front_alloc_stat_inc(class_idx);
|
||||
|
||||
tiny_route_kind_t route = tiny_route_for_class((uint8_t)class_idx);
|
||||
switch (route) {
|
||||
case TINY_ROUTE_HOTHEAP_V2: {
|
||||
if (class_idx == 7) {
|
||||
void* v2p = tiny_hotheap_v2_alloc(7);
|
||||
if (TINY_HOT_LIKELY(v2p != NULL)) {
|
||||
return v2p;
|
||||
}
|
||||
tiny_hotheap_v2_record_route_fallback();
|
||||
case TINY_ROUTE_SMALL_HEAP_V3: {
|
||||
void* v3p = so_alloc((uint32_t)class_idx);
|
||||
if (TINY_HOT_LIKELY(v3p != NULL)) {
|
||||
return v3p;
|
||||
}
|
||||
so_v3_record_alloc_fallback((uint8_t)class_idx);
|
||||
// fallthrough to v2/v1
|
||||
__attribute__((fallthrough));
|
||||
}
|
||||
case TINY_ROUTE_HOTHEAP_V2: {
|
||||
void* v2p = tiny_hotheap_v2_alloc((uint8_t)class_idx);
|
||||
if (TINY_HOT_LIKELY(v2p != NULL)) {
|
||||
return v2p;
|
||||
}
|
||||
tiny_hotheap_v2_record_route_fallback((uint8_t)class_idx);
|
||||
// fallthrough to TinyHeap v1
|
||||
__attribute__((fallthrough));
|
||||
}
|
||||
case TINY_ROUTE_HEAP: {
|
||||
void* heap_ptr = NULL;
|
||||
@ -139,7 +175,10 @@ static inline void* malloc_tiny_fast(size_t size) {
|
||||
}
|
||||
|
||||
// Legacy Tiny front
|
||||
void* ptr = tiny_hot_alloc_fast(class_idx);
|
||||
void* ptr = NULL;
|
||||
if (!front_snap || front_snap->unified_cache_on) {
|
||||
ptr = tiny_hot_alloc_fast(class_idx);
|
||||
}
|
||||
if (TINY_HOT_LIKELY(ptr != NULL)) {
|
||||
return ptr;
|
||||
}
|
||||
@ -192,6 +231,8 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
tiny_front_free_stat_inc(class_idx);
|
||||
tiny_route_kind_t route = tiny_route_for_class((uint8_t)class_idx);
|
||||
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;
|
||||
|
||||
// TWO-SPEED: SuperSlab registration check is DEBUG-ONLY to keep HOT PATH fast.
|
||||
// In Release builds, we trust header magic (0xA0) as sufficient validation.
|
||||
@ -255,6 +296,9 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
// Same-thread + TinyHeap route → route-based free
|
||||
if (__builtin_expect(use_tiny_heap, 0)) {
|
||||
switch (route) {
|
||||
case TINY_ROUTE_SMALL_HEAP_V3:
|
||||
so_free((uint32_t)class_idx, base);
|
||||
return 1;
|
||||
case TINY_ROUTE_HOTHEAP_V2:
|
||||
tiny_hotheap_v2_free((uint8_t)class_idx, base, meta);
|
||||
return 1;
|
||||
@ -276,7 +320,9 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
if (use_tiny_heap) {
|
||||
// fallback: lookup failed but TinyHeap front is ON → use generic TinyHeap free
|
||||
if (route == TINY_ROUTE_HOTHEAP_V2) {
|
||||
tiny_hotheap_v2_record_free_fallback();
|
||||
tiny_hotheap_v2_record_free_fallback((uint8_t)class_idx);
|
||||
} else if (route == TINY_ROUTE_SMALL_HEAP_V3) {
|
||||
so_v3_record_free_fallback((uint8_t)class_idx);
|
||||
}
|
||||
tiny_heap_free_class_fast(tiny_heap_ctx_for_thread(), class_idx, ptr);
|
||||
return 1;
|
||||
@ -300,7 +346,10 @@ static inline int free_tiny_fast(void* ptr) {
|
||||
}
|
||||
#endif
|
||||
|
||||
int pushed = unified_cache_push(class_idx, HAK_BASE_FROM_RAW(base));
|
||||
int pushed = 0;
|
||||
if (!front_snap || front_snap->unified_cache_on) {
|
||||
pushed = unified_cache_push(class_idx, HAK_BASE_FROM_RAW(base));
|
||||
}
|
||||
if (__builtin_expect(pushed, 1)) {
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user