Files
hakmem/docs/specs/HAKO_MIR_FFI_SPEC.md

99 lines
5.0 KiB
Markdown
Raw Normal View History

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
# 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/デオプトを選択)