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:
48
src/backend/mir_interpreter/handlers/lifecycle.rs
Normal file
48
src/backend/mir_interpreter/handlers/lifecycle.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl MirInterpreter {
|
||||
pub(super) fn handle_keepalive(
|
||||
&mut self,
|
||||
values: &[ValueId],
|
||||
drop_after: bool,
|
||||
) -> Result<(), VMError> {
|
||||
if drop_after {
|
||||
self.release_strong_refs(values);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release_strong_refs(&mut self, values: &[ValueId]) {
|
||||
let mut arc_ptrs: HashSet<*const dyn NyashBox> = HashSet::new();
|
||||
|
||||
for value_id in values {
|
||||
if let Some(VMValue::BoxRef(arc)) = self.regs.get(value_id) {
|
||||
arc_ptrs.insert(Arc::as_ptr(arc));
|
||||
}
|
||||
}
|
||||
|
||||
for value_id in values {
|
||||
self.regs.remove(value_id);
|
||||
}
|
||||
|
||||
if arc_ptrs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let to_remove: Vec<ValueId> = self
|
||||
.regs
|
||||
.iter()
|
||||
.filter_map(|(value_id, value)| match value {
|
||||
VMValue::BoxRef(arc) if arc_ptrs.contains(&Arc::as_ptr(arc)) => Some(*value_id),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
|
||||
for value_id in to_remove {
|
||||
self.regs.remove(&value_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ mod boxes_void_guards;
|
||||
mod calls;
|
||||
mod extern_provider;
|
||||
mod externals;
|
||||
mod lifecycle;
|
||||
mod memory;
|
||||
mod misc;
|
||||
mod type_ops;
|
||||
@ -135,49 +136,7 @@ impl MirInterpreter {
|
||||
| MirInstruction::Barrier { .. }
|
||||
| MirInstruction::Safepoint => {}
|
||||
MirInstruction::KeepAlive { values, drop_after } => {
|
||||
// Phase 285 P2.1: Handle KeepAlive based on drop_after flag
|
||||
// - drop_after=true: Release values (for variable overwrite, enables weak ref failure)
|
||||
// - drop_after=false: Just keep alive (for scope end, values may be needed for PHI)
|
||||
if *drop_after {
|
||||
// IMPORTANT: Due to SSA Copy instructions, a single Box may have multiple
|
||||
// ValueIds pointing to it (e.g., %5 = NewBox, %6 = Copy %5).
|
||||
// We need to find and remove ALL ValueIds that point to the same Arc.
|
||||
use std::sync::Arc;
|
||||
use super::super::vm_types::VMValue;
|
||||
|
||||
// Collect raw pointers of Arcs being released
|
||||
let mut arc_ptrs: Vec<*const dyn crate::box_trait::NyashBox> = Vec::new();
|
||||
for v in values {
|
||||
if let Some(VMValue::BoxRef(arc)) = self.regs.get(v) {
|
||||
arc_ptrs.push(Arc::as_ptr(arc));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the specified values first
|
||||
for v in values {
|
||||
self.regs.remove(v);
|
||||
}
|
||||
|
||||
// Find and remove ALL other ValueIds that point to the same Arcs
|
||||
if !arc_ptrs.is_empty() {
|
||||
let to_remove: Vec<crate::mir::ValueId> = self.regs
|
||||
.iter()
|
||||
.filter_map(|(vid, val)| {
|
||||
if let VMValue::BoxRef(arc) = val {
|
||||
let ptr = Arc::as_ptr(arc);
|
||||
if arc_ptrs.contains(&ptr) {
|
||||
return Some(*vid);
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect();
|
||||
for vid in to_remove {
|
||||
self.regs.remove(&vid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If drop_after=false, do nothing (values stay alive)
|
||||
self.handle_keepalive(values, *drop_after)?;
|
||||
}
|
||||
MirInstruction::Nop => {}
|
||||
other => {
|
||||
|
||||
Reference in New Issue
Block a user