Phase 10.10: GC Switchable Runtime & Unified Debug System 実装完了
Phase 10.10の主要実装: - GcConfigBox: GC設定の実行時制御(counting/trace/barrier_strict) - DebugConfigBox: デバッグ設定の統一管理(JIT events/stats/dump/dot) - メソッドディスパッチ: system_methods.rsで両Boxのメソッド実装 - CountingGC動作確認: write_barriers正常カウント(VM実行時) 技術的詳細: - BoxCore/BoxBase統一アーキテクチャを活用 - setFlag/getFlag/apply/summaryメソッドで統一API提供 - 環境変数経由でVM/JITランタイムと連携 - GcConfigBox.apply()は次回実行から有効(ランタイム作成前に環境変数参照) テスト済み: - examples/gc_counting_demo.nyash: CountingGCの動作確認 - write_barriers=3でArray.push/set, Map.setを正しくカウント - NYASH_GC_TRACE=1でGC統計出力確認 Box-First哲学の体現: 設定も制御も観測もすべてBox! 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,84 @@
|
||||
# Phase 10.10 – Python→Nyash→MIR→VM/Native ラインの実用化整備(Box-First 継続)
|
||||
|
||||
目的: Nyash→MIR→VM/Native の実行ラインを日常運用レベルに引き上げ、GC/デバッグ/HostCallの柱を整備する。
|
||||
|
||||
## ゴール(DoD)
|
||||
- エンドツーエンド実行ライン(Parser→AST→MIR→VM→JIT)がビルトインBoxで安定(RO/一部WO)
|
||||
- GC切替(Null/Counting)をCLI/Boxから操作可能、root領域APIが一箇所化
|
||||
- デバッグ/可視化の旗振り(DebugConfig/Box)でJIT/VM/イベント/DOTを一本化
|
||||
- HostCall: 読み取り系はparam受けでJIT直実行(allow)。書き込み系はポリシー/whitelistでopt-in可能
|
||||
- 最小ベンチと回帰(サンプル)でラインの劣化を検知
|
||||
|
||||
## 事前整備(現状)
|
||||
- HostCall基盤: Registry/Policy/Events/Boundary(10.9-β/δ完了)
|
||||
- JITイベント: `NYASH_JIT_EVENTS=1` 時に `threshold=1` 自動適用でLower確実実行
|
||||
- 戻り境界: CallBoundaryBox で JitValue→VMValue を一元化(ハンドル復元含む)
|
||||
|
||||
## ワークストリーム
|
||||
1) GC Switchable Runtime(phase_10_4_gc_switchable_runtime.md)
|
||||
- 目標: NullGc/CountingGc の切替、root領域/バリアAPIの一本化
|
||||
- タスク:
|
||||
- NyashRuntimeBuilder: GC選択をCLI/Box反映(NYASH_GC=none|counting など)
|
||||
- ScopeTracker/enter_root_region()/pin_roots() の公開インターフェース確認
|
||||
- CountingGcの統計出力(roots/reads/writes/safepoints)
|
||||
- 書き込み系HostCallにバリアサイトのフック(Map/Array set/push)
|
||||
- 受入: GC切替コマンドで統計差分が取れる/HostCall書き込みでバリアサイトが加算される
|
||||
|
||||
2) Unified Debug System(phase_10_8_unified_debug_system.md)
|
||||
- 目標: デバッグ/観測フラグを DebugConfig/Box に統合(CLI/env/Boxの単一路)
|
||||
- タスク:
|
||||
- DebugConfig(Rust側): dump/events/stats/dot/phi_min 等を集約
|
||||
- DebugConfigBox: Boxから get/set/apply/toJson/fromJson
|
||||
- Runner: CLI→DebugConfig→env/Box の一本化(env直読み排除)
|
||||
- イベント出力先: stdout/file 切替の設定(NYASH_JIT_EVENTS_PATH のBox反映)
|
||||
- 受入: Boxから apply 後、JIT/VM/DOTの挙動が即時反映/JSONLが指定先に出力
|
||||
|
||||
3) E2Eラインの実用化(builtin→pluginの足場)
|
||||
- 目標: ビルトインBoxで日常運用レベル、プラグインBoxはTLV HostCallの足場を準備
|
||||
- タスク:
|
||||
- Lowerカバレッジの整理(BoxCall/RO/WO・param/非paramの分岐ダンプ)
|
||||
- 署名管理: レジストリのオーバーロード運用方針(canonical idと派生idの整理)
|
||||
- 返り型推論: MIR Builderのreturn_type推定を確認(main/補助関数とも)
|
||||
- Plugin PoC: TLV/handle経由のread-onlyメソッド1つをHostCall経由で通す(allowログまで)
|
||||
- 受入: 代表サンプル(math/map/array/string)でallow/fallbackが意図通り、plugin PoCでallowイベントが出る
|
||||
|
||||
4) ドキュメントと例の整理
|
||||
- 目標: 例の最小集合化(param/非param/RO/WO/HH/Hの代表)、手順の簡潔化
|
||||
- タスク:
|
||||
- examples/: 重複の削減、README(実行コマンド付き)
|
||||
- phase_10_9/10_10 のガイドをCURRENT_TASKと相互参照
|
||||
- 受入: 主要ケースが examples/README からそのまま実行可
|
||||
|
||||
5) ベンチと回帰(最小)
|
||||
- 目標: ラインの性能/退行の早期検知
|
||||
- タスク:
|
||||
- ny_bench.nyash のケース整理(関数呼出/Map set-get/branch)
|
||||
- compare: VM vs JIT(ウォームアップ付き)
|
||||
- 受入: ベンチ出力に JIT/VM の比較が出る(改善/退行が見える)
|
||||
|
||||
## リスクと対策
|
||||
- param/非param 分岐の混乱: イベントに reason を必ず出す/docsにベストプラクティス(受け手をparam化)
|
||||
- mutatingの誤許可: JitPolicyBox の whitelist/プリセットのみで許可、既定はread_only
|
||||
- 署名の散逸: canonical id(例: nyash.map.get_h)と派生(_hh)の方針を明示
|
||||
|
||||
## 受け入れ基準(サマリ)
|
||||
- DebugConfig/Box/CLIの一貫挙動(apply後の即時反映)
|
||||
- GC切替とバリアサイト観測が可能
|
||||
- HostCall(RO/一部WO)が param でallow、非paramでfallback(イベントで確認可)
|
||||
- 代表サンプルが examples/README の手順で成功
|
||||
|
||||
## すぐ試せるコマンド(抜粋)
|
||||
```bash
|
||||
# math.min(関数スタイル)
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.nyash
|
||||
|
||||
# Map.get HH直実行
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_map_get_param_hh.nyash
|
||||
|
||||
# Mutating opt-in(Array.push)
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_policy_optin_mutating.nyash
|
||||
```
|
||||
|
||||
@ -85,6 +85,35 @@
|
||||
- b1正規化カウンタ: `b1_norm_count`(分岐条件/PHI)
|
||||
- HostCallイベント: `argc`/`arg_types`/`reason`でデバッグ容易化(mutatingは `policy_denied_mutating`)
|
||||
|
||||
### 🔎 HostCallイベントの基準(10.9-β)
|
||||
- 受け手が関数パラメータ(param)の場合は JIT直実行(allow/sig_ok)を基本にイベント出力
|
||||
- Map.get(Handle, I64): `id: nyash.map.get_h`, `arg_types: ["Handle","I64"]`
|
||||
- Map.get(Handle, Handle): `id: nyash.map.get_hh`, `arg_types: ["Handle","Handle"]`
|
||||
- length/isEmpty/charCodeAt/size 等も `*_h`(Handle受け)でallow
|
||||
- 受け手がparamでない場合は VMへフォールバック(fallback/receiver_not_param)をイベントで記録(読み取り系の可視化を保証)
|
||||
- 例: `id: nyash.any.length_h`, `decision: fallback`, `reason: receiver_not_param`
|
||||
- 数値緩和: `NYASH_JIT_HOSTCALL_RELAX_NUMERIC=1` または `NYASH_JIT_NATIVE_F64=1` で `I64→F64` コアーションを許容(sig_okに影響)
|
||||
|
||||
### 🧪 代表サンプル(E2E)
|
||||
```bash
|
||||
# math.*(関数スタイル): 署名一致でallow、戻りFloat表示
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.nyash
|
||||
|
||||
# Map.get(パラメータ受け+Handleキー → HH直実行)
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_map_get_param_hh.nyash
|
||||
|
||||
# Map.get(非パラメータ受け → fallback記録)
|
||||
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
|
||||
./target/release/nyash --backend vm examples/jit_hostcall_map_get_handle.nyash
|
||||
```
|
||||
|
||||
### ⚙️ Quick flags(イベント観測を確実に)
|
||||
- `NYASH_JIT_EVENTS=1` のとき Runner が `NYASH_JIT_THRESHOLD=1` を自動適用(未指定の場合)
|
||||
- 1回目からLowerが走り、allow/fallbackのイベントが必ず出る
|
||||
- 明示的に `NYASH_JIT_THRESHOLD` を指定した場合はそちらを優先
|
||||
|
||||
## ⚠️ リスクとその箱での緩和
|
||||
- 署名不一致(args/ret)
|
||||
- HostcallRegistryBox で一元検査。不一致は `sig_mismatch` でイベント記録→VMへ
|
||||
@ -107,6 +136,20 @@
|
||||
- HostCallブリッジの拡大(Map.getの多型キー、String操作の追加)
|
||||
- CallBoundaryBox経由の `new`/副作用命令の段階的JIT化
|
||||
|
||||
## ✳️ 10.9-δ 書き込みの導線(運用)
|
||||
- 既定ポリシー: read_only(`NYASH_JIT_READ_ONLY=1`)で mutating はフォールバック(`reason: policy_denied_mutating`)。
|
||||
- JitPolicyBox でopt-in:
|
||||
```nyash
|
||||
P = new JitPolicyBox()
|
||||
P.set("read_only", true)
|
||||
P.addWhitelist("nyash.array.push_h") // 個別に許可
|
||||
// またはプリセット:
|
||||
P.enablePreset("mutating_minimal") // Array.push_h を許可
|
||||
```
|
||||
- イベント方針:
|
||||
- 受け手=param: allow/sig_ok(whitelist/オフ時はfallback/policy_denied_mutating)
|
||||
- 受け手≠param: fallback/receiver_not_param(可視化を保証)
|
||||
|
||||
---
|
||||
|
||||
最短ルート: 箱(Policy/Events/Registry/Boundary)を先に置き、読み取り系でJITを安全に通す→観測を増やす→署名とポリシーの一本化で切替点を固定→必要最小限のネイティブ型(f64/b1)を段階導入。
|
||||
|
||||
Reference in New Issue
Block a user