diff --git a/core/box/hak_wrappers.inc.h b/core/box/hak_wrappers.inc.h index abb250d6..41477c33 100644 --- a/core/box/hak_wrappers.inc.h +++ b/core/box/hak_wrappers.inc.h @@ -31,7 +31,8 @@ void* realloc(void* ptr, size_t size) { #include "../ptr_trace.h" // Debug: pointer trace immediate dump on libc fallback #include "front_gate_classifier.h" // Box FG: pointer classification (header/reg) #include "../hakmem_pool.h" // Mid registry lookup (failsafe for headerless Mid) -#include "../front/malloc_tiny_fast.h" // Phase 26: Front Gate Unification +#include "../front/malloc_tiny_fast.h" // Phase 26: Front Gate Unification (Tiny fast alloc) +#include "tiny_alloc_gate_box.h" // Tiny Alloc Gatekeeper Box (BASE/USER+Bridge 入口) #include "tiny_front_config_box.h" // Phase 4-Step3: Compile-time config for dead code elimination #include "wrapper_env_box.h" // Wrapper env cache (step trace / LD safe / free trace) #include "../hakmem_internal.h" // AllocHeader helpers for diagnostics @@ -194,7 +195,9 @@ void* malloc(size_t size) { if (wcfg->step_trace && size == 33000) write(2, "STEP:5 Unified Gate check\n", 26); if (size <= tiny_get_max_size()) { if (wcfg->step_trace && size == 33000) write(2, "STEP:5.1 Inside Unified\n", 24); - void* ptr = malloc_tiny_fast(size); + // Tiny Alloc Gate Box: malloc_tiny_fast() の薄いラッパ + // (診断 OFF 時は従来どおりの挙動・コスト) + void* ptr = tiny_alloc_gate_fast(size); if (__builtin_expect(ptr != NULL, 1)) { g_hakmem_lock_depth--; if (wcfg->step_trace && size == 33000) write(2, "RET:TinyFast\n", 13); diff --git a/core/box/tiny_alloc_gate_box.h b/core/box/tiny_alloc_gate_box.h new file mode 100644 index 00000000..110657df --- /dev/null +++ b/core/box/tiny_alloc_gate_box.h @@ -0,0 +1,163 @@ +// tiny_alloc_gate_box.h - Box: Tiny Alloc Gatekeeper +// +// 役割: +// - malloc 側の Tiny フロントエンドで、Tiny 向け割り当ての「入口箱」として振る舞う。 +// - いまは既存の malloc_tiny_fast(size) を薄くラップしつつ、 +// 将来の BASE/USER 変換・Bridge・Guard を 1 箱に集約できるフックを提供する。 +// +// Box 理論: +// - Single Responsibility: +// 「Tiny alloc の入口で、返す USER ポインタを一度だけ検査/正規化する」。 +// - Clear Boundary: +// malloc ラッパ (hak_wrappers) から Tiny Fast Path への入口を +// tiny_alloc_gate_fast() に一本化する。 +// - Reversible: +// 診断は ENV (HAKMEM_TINY_ALLOC_GATE_DIAG) で ON/OFF 切替可能。 +// OFF 時は従来どおり malloc_tiny_fast の挙動・コストを保つ。 + +#ifndef HAKMEM_TINY_ALLOC_GATE_BOX_H +#define HAKMEM_TINY_ALLOC_GATE_BOX_H + +#include "../hakmem_build_flags.h" + +#include +#include +#include + +#include "../hakmem_tiny.h" // hak_tiny_size_to_class +#include "ptr_type_box.h" +#include "ptr_conversion_box.h" // USER↔BASE 変換 +#include "tiny_ptr_bridge_box.h" // Tiny Superslab Bridge +#include "../tiny_region_id.h" // Header 読み出し +#include "../front/malloc_tiny_fast.h" // 既存 Tiny Fast Path + +// 将来の拡張用コンテキスト: +// - size : 要求サイズ +// - class_idx : サイズ→クラス写像(期待値) +// - user : 返された USER ポインタ +// - base : USER→BASE 変換後 +// - bridge : Superslab / slab / meta / class 情報 +typedef struct TinyAllocGateContext { + size_t size; + int class_idx; + hak_user_ptr_t user; + hak_base_ptr_t base; + TinyPtrBridgeInfo bridge; +} TinyAllocGateContext; + +// 診断用 Gatekeeper 拡張の ON/OFF(ENV: HAKMEM_TINY_ALLOC_GATE_DIAG) +static inline int tiny_alloc_gate_diag_enabled(void) +{ + static __thread int s_diag = -1; + if (__builtin_expect(s_diag == -1, 0)) { +#if !HAKMEM_BUILD_RELEASE + const char* e = getenv("HAKMEM_TINY_ALLOC_GATE_DIAG"); + s_diag = (e && *e && *e != '0') ? 1 : 0; +#else + (void)getenv; + s_diag = 0; +#endif + } + return s_diag; +} + +// 診断用: USER ポインタが Tiny Superslab 上で期待クラスに属しているかを検査。 +// 戻り値: +// 1: 検査 OK(Tiny 管理下で、class_idx との整合性あり) +// 0: 何らかの不整合(Bridge 失敗/クラス不一致など) +static inline int tiny_alloc_gate_validate(TinyAllocGateContext* ctx) +{ + if (!ctx) return 0; + void* user_raw = HAK_USER_TO_RAW(ctx->user); + if (!user_raw) return 0; + + // 範囲上明らかにおかしいものは Tiny 管理外扱い + uintptr_t addr = (uintptr_t)user_raw; + if (addr < 4096 || addr > 0x00007fffffffffffULL) { + return 0; + } + + // Bridge: Superslab / Slab / Meta / Class を一括取得 + TinyPtrBridgeInfo info = tiny_ptr_bridge_classify_raw(user_raw); + ctx->bridge = info; + if (!info.ss || !info.meta || info.slab_idx < 0) { + return 0; + } + + // 期待クラス (size 由来) と meta クラスの整合性チェック + uint8_t meta_cls = info.meta_cls; + if (meta_cls >= TINY_NUM_CLASSES) { + return 0; + } + if (ctx->class_idx >= 0 && (uint8_t)ctx->class_idx != meta_cls) { + static _Atomic uint32_t g_alloc_gate_cls_mis = 0; + uint32_t n = atomic_fetch_add_explicit(&g_alloc_gate_cls_mis, 1, memory_order_relaxed); + if (n < 8) { + fprintf(stderr, + "[TINY_ALLOC_GATE_CLASS_MISMATCH] size=%zu cls_expect=%d meta_cls=%u user=%p ss=%p slab=%d\n", + ctx->size, + ctx->class_idx, + (unsigned)meta_cls, + user_raw, + (void*)info.ss, + info.slab_idx); + fflush(stderr); + } + // クラス不一致自体は Fail-Fast せず、ログだけ残す(将来の Guard 差し込みポイント)。 + } + +#if !HAKMEM_BUILD_RELEASE + // Header 由来の class と meta class の整合性も確認 + int hdr_cls = tiny_region_id_read_header(user_raw); + if (hdr_cls >= 0 && hdr_cls != (int)meta_cls) { + static _Atomic uint32_t g_alloc_gate_hdr_meta_mis = 0; + uint32_t n = atomic_fetch_add_explicit(&g_alloc_gate_hdr_meta_mis, 1, memory_order_relaxed); + if (n < 8) { + fprintf(stderr, + "[TINY_ALLOC_GATE_HDR_META_MISMATCH] size=%zu hdr_cls=%d meta_cls=%u user=%p ss=%p slab=%d\n", + ctx->size, + hdr_cls, + (unsigned)meta_cls, + user_raw, + (void*)info.ss, + info.slab_idx); + fflush(stderr); + } + } +#endif + + // USER→BASE 変換(Box 経由)を一度だけ行い、将来 Base ベースの Guard に活用。 + ctx->base = ptr_user_to_base(ctx->user, meta_cls); + return 1; +} + +// Tiny Alloc Gatekeeper 本体: +// - malloc ラッパ (hak_wrappers) から呼ばれる Tiny fast alloc の入口。 +// - 現状は malloc_tiny_fast(size) の薄いラッパで、診断 ON のときだけ +// 返された USER ポインタに対して Bridge + Layout 検査を追加。 +static inline void* tiny_alloc_gate_fast(size_t size) +{ + // まずは従来どおり Tiny Fast Path で割り当て(USER ポインタを得る) + void* user_ptr = malloc_tiny_fast(size); + +#if !HAKMEM_BUILD_RELEASE + if (__builtin_expect(tiny_alloc_gate_diag_enabled(), 0) && user_ptr) { + TinyAllocGateContext ctx; + ctx.size = size; + ctx.user = HAK_USER_FROM_RAW(user_ptr); + ctx.class_idx = hak_tiny_size_to_class(size); + ctx.base = HAK_BASE_FROM_RAW(NULL); + ctx.bridge.ss = NULL; + ctx.bridge.meta = NULL; + ctx.bridge.slab_idx = -1; + ctx.bridge.meta_cls = 0xffu; + + (void)tiny_alloc_gate_validate(&ctx); + } +#endif + + return user_ptr; +} + +#endif // HAKMEM_TINY_ALLOC_GATE_BOX_H +