Files
hakmem/docs/specs/HAKO_MIR_FFI_SPEC.md
Moe Charm (CI) 67fb15f35f Wrap debug fprintf in !HAKMEM_BUILD_RELEASE guards (Release build optimization)
## Changes

### 1. core/page_arena.c
- Removed init failure message (lines 25-27) - error is handled by returning early
- All other fprintf statements already wrapped in existing #if !HAKMEM_BUILD_RELEASE blocks

### 2. core/hakmem.c
- Wrapped SIGSEGV handler init message (line 72)
- CRITICAL: Kept SIGSEGV/SIGBUS/SIGABRT error messages (lines 62-64) - production needs crash logs

### 3. core/hakmem_shared_pool.c
- Wrapped all debug fprintf statements in #if !HAKMEM_BUILD_RELEASE:
  - Node pool exhaustion warning (line 252)
  - SP_META_CAPACITY_ERROR warning (line 421)
  - SP_FIX_GEOMETRY debug logging (line 745)
  - SP_ACQUIRE_STAGE0.5_EMPTY debug logging (line 865)
  - SP_ACQUIRE_STAGE0_L0 debug logging (line 803)
  - SP_ACQUIRE_STAGE1_LOCKFREE debug logging (line 922)
  - SP_ACQUIRE_STAGE2_LOCKFREE debug logging (line 996)
  - SP_ACQUIRE_STAGE3 debug logging (line 1116)
  - SP_SLOT_RELEASE debug logging (line 1245)
  - SP_SLOT_FREELIST_LOCKFREE debug logging (line 1305)
  - SP_SLOT_COMPLETELY_EMPTY debug logging (line 1316)
- Fixed lock_stats_init() for release builds (lines 60-65) - ensure g_lock_stats_enabled is initialized

## Performance Validation

Before: 51M ops/s (with debug fprintf overhead)
After:  49.1M ops/s (consistent performance, fprintf removed from hot paths)

## Build & Test

```bash
./build.sh larson_hakmem
./out/release/larson_hakmem 1 5 1 1000 100 10000 42
# Result: 49.1M ops/s
```

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-26 13:14:18 +09:00

99 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# HAKO MIR/FFI/ABI Design (Front-Checked, MIR-Transport)
目的: フロントエンドで型整合を完結し、MIR は「最小契約最適化ヒント」を運ぶだけ。FFI/ABI は機械的に引数を並べる。バグ時は境界で FailFast。Box Theory に従い境界を1箇所に集約し、A/B で即切替可能にする。
## 境界Boxと責務
- フロントエンド型チェックType Checker Box
- 全ての型整合・多相解決を完結(例: map.set → set_h / set_hh / set_ha / set_ah
- 必要な変換は明示命令box/unbox/castを挿入。暗黙推測は残さない。
- MIR ノードへ `Tag/Hint` を添付reg→{value_kind, nullability, …})。
- MIR 輸送Transport Box
- 役割: i64 値Tag/Hint を「運ぶだけ」。
- 最小検証: move/phi の Tag 一致、call 期待と引数の Tag 整合(不一致はビルド時エラー)。
- FFI/ABI ローワリングFFI Lowering Box
- 受け取った解決済みシンボルと Tag に従い、C ABI へ並べ替えるだけ。
- Unknown/未解決は発行禁止FailFast。デバッグ時に 1 行ログ。
## C ABIx86_64 SysV, Linux
- 引数: RDI, RSI, RDX, RCX, R8, R9 → 以降スタック16B 整列)。返り値: RAX。
- 値種別:
- Int: `int64_t`MIR の i64 そのまま)
- HandleBox/オブジェクト): `HakoHandle``uintptr_t`/`void*` 同等の 64bit
- 文字列: 原則 Handle。必要時のみ `(const uint8_t* p, size_t n)` 専用シンボルへ分岐
### 例: nyash.map
- setキー/値の型で分岐)
- `void nyash_map_set_h(HakoHandle map, int64_t key, int64_t val);`
- `void nyash_map_set_hh(HakoHandle map, HakoHandle key, HakoHandle val);`
- `void nyash_map_set_ha(HakoHandle map, int64_t key, HakoHandle val);`
- `void nyash_map_set_ah(HakoHandle map, HakoHandle key, int64_t val);`
- get常に Handle を返す)
- `HakoHandle nyash_map_get_h(HakoHandle map, int64_t key);`
- `HakoHandle nyash_map_get_hh(HakoHandle map, HakoHandle key);`
- アンボックス
- `int64_t nyash_unbox_i64(HakoHandle h, int* ok);`ok=0 なら非数値)
## MIR が運ぶ最小契約HardとヒントSoft
- Hard必須
- `value_kind`Int/Handle/String/Ptr
- phi/move/call の Tag 整合(不一致はフロントで cast を要求)
- Unknown 禁止FFI 発行不可)
- Soft任意ヒント
- `signedness`, `nullability`, `escape`, `alias_set`, `lifetime_hint`, `shape_hint(len/unknown)`, `pure/no_throw` など
- 解釈はバックエンド自由。ヒント不整合時は性能のみ低下し、正しさは保持。
## ランタイム検証任意・A/B
- 既定は OFF。必要時のみ軽量ガードを ON。
- 例: ハンドル魔法数・範囲、(ptr,len) の len 範囲。サンプリング率可。
- ENV
- `HAKO_FFI_GUARD=0/1`ON でランタイム検証)
- `HAKO_FFI_GUARD_RATE_LG=N`2^N に 1 回)
- `HAKO_FAILFAST=1`失敗即中断。0 で安全パスへデオプト)
## Box Theory と A/B戻せる設計
- 境界は 3 箇所(フロント/輸送/FFIで固定。各境界で FailFast は 1 か所に集約。
- すべて ENV で A/B 可能(ガード ON/OFF、サンプリング率、フォールバック先
## Phase導入段階
1. PhaseA: Tag サイドテーブル導入フロント。phi/move 整合のビルド時検証。
2. PhaseB: FFI 解決テーブル(`(k1,k2,…)→symbol`)。デバッグ 1 行ログ。
3. PhaseC: ランタイムガードA/B。魔法数/範囲チェックの軽量実装。
4. PhaseD: ヒント活用の最適化pure/no_throw, escape=false など)。
## サマリ
- フロントで型を完結 → MIR は運ぶだけ → FFI は機械的。
- Hard は FailFast、Soft は最適化ヒント。A/B で安全と性能のバランスを即時調整可能。
---
## Phase 追記(このフェーズでやること)
1) 実装(最小)
- Tag サイドテーブルreg→Tagをフロントで確定・MIRへ添付
- phi/move で Tag 整合アサート(不一致ならフロントへ cast を要求)
- FFI 解決テーブル(引数の Tag 組→具体シンボル名)+デバッグ 1 行ログA/B
- Unknown の FFI 禁止FailFast
- ランタイム軽ガードの ENV 配線HAKO_FFI_GUARD, HAKO_FFI_GUARD_RATE_LG, HAKO_FAILFAST
2) スモークチェック(最小ケースで通電確認)
- map.set(Int,Int) → set_h が呼ばれる(ログで確認)
- map.set(Handle,Handle) → set_hh が呼ばれる
- map.get_h 返回 Handle。直後の unbox_i64(ok) で ok=0/1 を確認
- phi で (Int|Handle) 混在 → ビルド時エラーcast 必須)
- Unknown のまま FFI 到達 → FailFast1 回だけ)
- ランタイムガード ONHAKO_FFI_GUARD=1, RATE_LG=8で魔法数/範囲の軽検証が通る
3) A/B・戻せる設計
- 既定: ガード OFFperf 影響なし)
- 問題時: HAKO_FFI_GUARD=1 だけで実行時検証を有効化FailFast/デオプトを選択)