98 lines
3.2 KiB
C
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
|