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:
Moe Charm
2025-08-28 22:31:51 +09:00
parent 4e1b595796
commit d67f27f4b8
27 changed files with 1341 additions and 63 deletions

View File

@ -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/Boundary10.9-β/δ完了)
- JITイベント: `NYASH_JIT_EVENTS=1` 時に `threshold=1` 自動適用でLower確実実行
- 戻り境界: CallBoundaryBox で JitValue→VMValue を一元化(ハンドル復元含む)
## ワークストリーム
1) GC Switchable Runtimephase_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 Systemphase_10_8_unified_debug_system.md
- 目標: デバッグ/観測フラグを DebugConfig/Box に統合CLI/env/Boxの単一路
- タスク:
- DebugConfigRust側: 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切替とバリアサイト観測が可能
- HostCallRO/一部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-inArray.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
```

View File

@ -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_okwhitelist/オフ時はfallback/policy_denied_mutating
- 受け手≠param: fallback/receiver_not_param可視化を保証
---
最短ルート: 箱Policy/Events/Registry/Boundaryを先に置き、読み取り系でJITを安全に通す→観測を増やす→署名とポリシーの一本化で切替点を固定→必要最小限のネイティブ型f64/b1を段階導入。