Files
hakmem/core/box/front_gate_v2.h
Moe Charm (CI) cef99b311d Phase 15: Box Separation (partial) - Box headers completed, routing deferred
**Status**: Box FG V2 + ExternalGuard 実装完了、hak_free_at routing は Phase 14-C に revert

**Files Created**:
1. core/box/front_gate_v2.h (98 lines)
   - Ultra-fast 1-byte header classification (TINY/POOL/MIDCAND/EXTERNAL)
   - Performance: 2-5 cycles
   - Same-page guard added (防御的プログラミング)

2. core/box/external_guard_box.h (146 lines)
   - ENV-controlled mincore safety check
   - HAKMEM_EXTERNAL_GUARD_MINCORE=0/1 (default: OFF)
   - Uses __libc_free() to avoid infinite loop

**Routing**:
- hak_free_at reverted to Phase 14-C (classify_ptr-based, stable)
- Phase 15 routing caused SEGV on page-aligned pointers

**Performance**:
- Phase 14-C (mincore ON): 16.5M ops/s (stable)
- mincore: 841 calls/100K iterations
- mincore OFF: SEGV (unsafe AllocHeader deref)

**Next Steps** (deferred):
- Mid/Large/C7 registry consolidation
- AllocHeader safety validation
- ExternalGuard integration

**Recommendation**: Stick with Phase 14-C for now
- mincore overhead acceptable (~1.9ms / 100K)
- Focus on other bottlenecks (TLS SLL, SuperSlab churn)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-15 22:08:51 +09:00

98 lines
3.2 KiB
C

// front_gate_v2.h - Box FG (Front Gate V2): Domain Classification
// Purpose: Fast domain routing based on 1-byte header ONLY
// Design: ChatGPT consultation Phase 15 - Box Separation
//
// Responsibilities (ONLY):
// 1. Read 1-byte header (ptr-1)
// 2. Classify: TINY | POOL | MIDCAND | EXTERNAL
// 3. Extract class_idx for TINY/POOL
//
// Out of scope (delegated to other boxes):
// - NO mincore (Box ExternalGuard only)
// - NO AllocHeader (Box ExternalGuard only)
// - NO registry lookup (Box Tiny/Pool/Mid)
// - NO free/alloc logic (routing only)
//
// Performance: 2-5 cycles (single byte read + bitwise ops)
#ifndef HAK_BOX_FRONT_GATE_V2_H
#define HAK_BOX_FRONT_GATE_V2_H
#include <stdint.h>
// Domain types (粗い分類のみ)
typedef enum {
FG_DOMAIN_TINY, // 0xa0 | class_idx (C0-C7, 8B-1KB)
FG_DOMAIN_POOL, // 0xb0 | class_idx (Pool TLS, 8-52KB)
FG_DOMAIN_MIDCAND, // Candidate for Mid/Large (needs registry lookup)
FG_DOMAIN_EXTERNAL // Not hakmem managed (or NULL/invalid)
} fg_domain_t;
// Classification result
typedef struct {
fg_domain_t domain;
int class_idx; // Valid for TINY/POOL (-1 otherwise)
} fg_classification_t;
// Ultra-fast domain classification (1-byte header only)
// Contract:
// - Input: ptr (USER pointer, can be NULL)
// - Output: {domain, class_idx}
// - Safety: NULL-safe, no crashes on invalid pointers
// - Performance: 2-5 cycles
static inline fg_classification_t fg_classify_domain(void* ptr) {
fg_classification_t result = {.domain = FG_DOMAIN_EXTERNAL, .class_idx = -1};
// NULL check
if (!ptr) return result;
// Guard against low addresses (avoid segfault on ptr-1)
if ((uintptr_t)ptr < 4096) return result;
// CRITICAL: Same-page guard (header must be in same page as ptr)
// If ptr is page-aligned (offset_in_page == 0), header would be on previous page (unsafe)
uintptr_t offset_in_page = (uintptr_t)ptr & 0xFFF;
if (offset_in_page == 0) {
// Page-aligned pointer → no header in same page → must be MIDCAND or EXTERNAL
result.domain = FG_DOMAIN_MIDCAND;
return result;
}
// Safe to read header (same page guaranteed)
uint8_t header = *((uint8_t*)ptr - 1);
// Tiny: 0xa0 | class_idx (class_idx = 0-7)
if ((header & 0xf0) == 0xa0) {
result.domain = FG_DOMAIN_TINY;
result.class_idx = (int)(header & 0x0f);
return result;
}
// Pool TLS: 0xb0 | class_idx
if ((header & 0xf0) == 0xb0) {
result.domain = FG_DOMAIN_POOL;
result.class_idx = (int)(header & 0x0f);
return result;
}
// Mid/Large candidate (no 1-byte header, needs registry lookup)
// Note: Could be Mid/Large, or could be External (libc/mmap)
// Delegated to Box MidRouter for registry lookup
result.domain = FG_DOMAIN_MIDCAND;
result.class_idx = -1;
return result;
}
// Domain name (debug/logging)
static inline const char* fg_domain_name(fg_domain_t domain) {
switch (domain) {
case FG_DOMAIN_TINY: return "TINY";
case FG_DOMAIN_POOL: return "POOL";
case FG_DOMAIN_MIDCAND: return "MIDCAND";
case FG_DOMAIN_EXTERNAL: return "EXTERNAL";
default: return "UNKNOWN";
}
}
#endif // HAK_BOX_FRONT_GATE_V2_H