refactor(lifecycle): Phase 285 P2.1 hygiene - lifecycle.rs 箱化完了
責務分離により KeepAlive 処理を handlers/lifecycle.rs に隔離: - handlers/lifecycle.rs 新規作成(47行) - handle_keepalive() で drop_after 判定 - release_strong_refs() で Arc 同一性探索を集約 - HashSet による O(1) 検索最適化 - handlers/mod.rs を dispatch 専用化(49行削除→1行呼び出し) - README.md に P2.1 完了状態を記載(SKIP→PASS) - phase-29y 将来設計相談パケット追加(NyRT ABI/RC insertion pass) Test: 154/154 PASS ✅ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,173 @@
|
||||
Status: Active
|
||||
Date: 2025-12-26
|
||||
Scope: Self-host後に “脱Rustランタイム(NyRT/.hako)” を進めるため、MIR命令語彙と runtime ABI(lifecycle/RC/weak)の境界をどう固めるべきか相談するパケット
|
||||
Related:
|
||||
- docs/reference/language/lifecycle.md
|
||||
- docs/development/current/main/phases/phase-285/README.md
|
||||
- docs/development/current/main/design/edgecfg-fragments.md
|
||||
- docs/development/current/main/investigations/phase-286-plan-normalization-consult.md
|
||||
|
||||
# Phase 29y (future): MIR lifecycle vocab freeze 相談パケット
|
||||
|
||||
## 0. 相談の意図
|
||||
|
||||
この文書は「今すぐ MIR 命令を増やす」提案を求めない。
|
||||
self-host後に脱Rustを進める前提で、**MIRのどこまでを語彙として固定し、どこからを runtime ABI(NyRT/.hako)に委譲するか**を設計SSOT化するための相談パケット。
|
||||
|
||||
強調:
|
||||
- “脱Rust” はゴールだが、**実装移行(NyRT/.hako化)は別フェーズ**でやる(この文書はその設計SSOTの下敷き)。
|
||||
- Phase 285(weak conformance / hidden root 根治)が未解決なら、先に Phase 285 を優先する。
|
||||
|
||||
## 1. 背景(いま分かったこと)
|
||||
|
||||
- weak/strong の意味論は言語SSOT(`docs/reference/language/lifecycle.md`)で定義されている。
|
||||
- VM 実装では “hidden root” が起きうる(例: SSA値を保持する `regs` / `mem` 等が strong を保持しうる)。
|
||||
- LLVM/wasm/他言語へ広げるには、Rust VM の内部構造に依存しない **共通の境界(ABI/観測点)**が必要。
|
||||
|
||||
## 2. 相談したい焦点
|
||||
|
||||
### Q1. MIRに参照カウンタ(retain/release)を載せるべきか?
|
||||
|
||||
候補:
|
||||
- A) **MIRは寿命を語らず**、runtime ABI で retain/release/weak を表現する(MIR→loweringがABI呼び出しへ)
|
||||
- B) MIRに **薄い寿命effect**(Retain/Release等)を追加し、後段で最適化する(liveness/use-count由来)
|
||||
|
||||
求める回答:
|
||||
- “移植性(LLVM/wasm)” と “実装コスト/破綻リスク(PHI/early-exit/例外)” の観点で、段階移行のおすすめ。
|
||||
|
||||
### Q2. “観測点” をどこに置くべきか?
|
||||
|
||||
目的は「weak_to_strong が成功する理由(strong root の残留)」を追えること。
|
||||
|
||||
候補:
|
||||
- runtime 側で root summary API(regs/mem/obj_fields/handlesの強参照数)
|
||||
- MIR 側で liveness の契約を固定し、VMがそれに従って解放する
|
||||
|
||||
## 2.1 推奨の設計分離(相談ベースライン)
|
||||
|
||||
相談の叩き台(推奨):
|
||||
- **参照カウンタの実体(カウンタ値)は runtime(NyRT)**に置く(MIRは“値”として持たない)。
|
||||
- **retain/release/weak_* の“発火点”はコンパイラ側が決める**が、語彙の増殖を避けるため “1箇所” に寄せる。
|
||||
- 候補: `CorePlan → Frag → emit_frag()` の流れの **Frag直前/直後に 1 回だけ**走る RC insertion pass。
|
||||
- backend(VM/LLVM/wasm)は、その RC event 列を **NyRT ABI 呼び出し**へ落とすだけにする。
|
||||
|
||||
狙い:
|
||||
- MIR/CorePlan は “意味論の語彙(BoxRef/WeakRef/weak_to_strong)” に留め、RC 実装の詳細を押し込めない。
|
||||
- RC の発火点は “見える” ようにしつつ、分散実装を防ぐ(hidden root の再発を減らす)。
|
||||
- self-host後に NyRT を `.hako runtime` に置換しても、ABIがSSOTなら導線が崩れにくい。
|
||||
|
||||
## 2.2 最小 NyRT ABI(相談先に提示したい候補)
|
||||
|
||||
### strong(参照カウント)
|
||||
|
||||
- `nyrt_retain(BoxRef)`
|
||||
- `nyrt_release(BoxRef)`
|
||||
|
||||
注意:
|
||||
- `release` が strong==0 になったとき “物理解放” は runtime の責務。
|
||||
- `fini()` は言語SSOT上 “論理終端” であり、GC/RCで勝手に呼ばない(`docs/reference/language/lifecycle.md`)。
|
||||
|
||||
### weak(弱参照)
|
||||
|
||||
- `nyrt_weak_new(BoxRef) -> WeakRef`
|
||||
- `nyrt_weak_drop(WeakRef)`
|
||||
- `nyrt_weak_to_strong(WeakRef) -> BoxRef | null`
|
||||
|
||||
SSOT整合:
|
||||
- `weak_to_strong()` は Alive のみ成功し、Dead/Freed は `null` を返す(`docs/reference/language/lifecycle.md`)。
|
||||
|
||||
### optional(診断/可観測性)
|
||||
|
||||
実装は後でよいが、相談では “観測点” を固定しておきたい。
|
||||
- `nyrt_debug_roots_summary()`(カテゴリ別の strong root 数など)
|
||||
- `nyrt_debug_refcounts(BoxRef)`(単体の strong/weak 数など)
|
||||
|
||||
制約:
|
||||
- 診断は意味論を変えない(ON/OFFで挙動が変わらない)。
|
||||
- env sprawl を防ぐため、既存の verbose/trace と統合する(Phase 285 の方針と整合)。
|
||||
|
||||
## 2.3 関数 ABI(owned/borrowed の最小規約)
|
||||
|
||||
相談したい焦点(推奨案):
|
||||
- 引数は **borrowed**(呼び出し中は alive を呼び出し側が保証、callee は retain/release しない)。
|
||||
- 戻り値は **owned**(callee は +1 を返し、caller が release 責務を持つ)。
|
||||
|
||||
この規約の狙い:
|
||||
- 関数境界の retain/release を最小語彙で固定できる。
|
||||
- VM/LLVM/wasm で ABI を揃えやすい。
|
||||
|
||||
## 2.4 “RC insertion pass” の置き場所(SSOT候補)
|
||||
|
||||
目的:
|
||||
- retain/release/weak_drop を “分散実装” させず、**1箇所**で決める。
|
||||
|
||||
候補(相談):
|
||||
- `Frag` に入る直前(CorePlan から “CFGが確定した後”)に、RC event 列を挿入する。
|
||||
- `PHI/loop/early-exit/cleanup` を見た上で挿入できる(誤りが減る)。
|
||||
- Plan/Frag SSOT の “出口語彙(return/break/continue)” と整合しやすい。
|
||||
|
||||
相談したい点:
|
||||
- “RC event” を MIR 命令として持つか(`Retain/Release/WeakDrop`)、あるいは `Frag` の effect として表すか。
|
||||
- 最初は正しさを優先し、冗長操作削除(最適化)は別フェーズに分離するのが安全か。
|
||||
|
||||
## 3. 非目標(今回はやらない)
|
||||
|
||||
- MIR語彙の大改造(型システムへ所有モデルを埋め込む等)
|
||||
- GCアルゴリズム刷新
|
||||
- self-host前に NyRT を .hako 化する実装
|
||||
|
||||
## 4. 期待するアウトプット(相談先に求める形式)
|
||||
|
||||
- 最終形ではなく **段階移行(1フェーズ=小差分)**のマイルストーン
|
||||
- 各フェーズの受け入れ条件(smoke/verify/contract)
|
||||
- “やると破綻しやすい罠” の列挙(PHI/early return/exception/cleanup)
|
||||
|
||||
## 4.1 マイルストーン案(相談先に求めたい “小刻み” の形)
|
||||
|
||||
Milestone A(docs-first):
|
||||
- NyRT ABI(最小セット)と関数 ABI(owned/borrowed)を SSOT 化
|
||||
- 受け入れ: doc が `lifecycle.md` と矛盾しない、smoke の観測点が明確
|
||||
|
||||
Milestone B(conformance-first):
|
||||
- Phase 285 の weak-fail(hidden root)を根治し、VM で conformance を固定
|
||||
- 受け入れ: weak-fail fixture が PASS、quick gate が green
|
||||
|
||||
Milestone C(compiler-side SSOT):
|
||||
- RC insertion pass の設計SSOT(どこで何を挿入するか)を確定(まだ実装しない)
|
||||
- 受け入れ: PHI/loop/return/cleanup のケース分類がある、破綻ポイントが明文化されている
|
||||
|
||||
Milestone D(implementation):
|
||||
- RC insertion pass を実装し、VM/LLVM/wasm が同じ ABI を呼ぶ形にする
|
||||
- 受け入れ: 既存 fixture を使って VM/LLVM parity を維持、診断が意味論を変えない
|
||||
|
||||
## 4.2 罠リスト(相談先に “やらない方がいい” として確認したい)
|
||||
|
||||
- “SSAの last-use = 言語寿命” を意味論にしてしまう(weak_to_strong で観測できて破綻しやすい)。
|
||||
- by-name で例外処理(Box名/関数名の文字列一致で retain/release を変える)。
|
||||
- 環境変数で挙動を分岐し、既定が揺れる(env sprawl)。
|
||||
- RC と `fini()` を混ぜる(GC/RC で勝手に `fini()` を呼ぶ等)。
|
||||
- “万能 struct(Optionだらけ)” で語彙統合し、結局デバッグできなくなる。
|
||||
|
||||
## 5. 参考(現時点のSSOT)
|
||||
|
||||
- lifecycle semantics SSOT: `docs/reference/language/lifecycle.md`
|
||||
- Phase 285 conformance: `docs/development/current/main/phases/phase-285/README.md`
|
||||
|
||||
## 6. 相談先に渡すための最小質問テンプレ
|
||||
|
||||
「ソースコードを見なくても回答できる」ことを重視する。
|
||||
|
||||
1) 推奨の分離は A/B のどれか?
|
||||
- A: MIRは寿命を語らず、NyRT ABI を呼ぶ
|
||||
- B: MIR/Frag に薄い寿命effect(Retain/Release)を載せて“見える化”する
|
||||
|
||||
2) 関数 ABI は “args borrowed / return owned” が妥当か?
|
||||
- もし違うなら、最小で安全な代替案は何か?
|
||||
|
||||
3) RC insertion pass を置く場所はどこが安全か?
|
||||
- CorePlan→Frag 直前/直後/emit直前など、PHI/loop/cleanup を踏まえて推奨を教えてほしい
|
||||
|
||||
4) weak_to_strong の失敗条件(Dead/Freed)を実装間で揃えるための “観測点” はどこが良いか?
|
||||
- runtime に root summary API を置くのが妥当か?
|
||||
|
||||
5) 破綻しやすい罠(特に PHI/early return/cleanup)を列挙してほしい
|
||||
Reference in New Issue
Block a user