Files
hakorune/src/backend/gc_helpers.rs

65 lines
2.1 KiB
Rust

//! GC-related small helpers for VM-side use
use crate::backend::vm::VMValue;
/// Return true if the BoxCall is a known mutating builtin call (e.g., Array/Map set/push)
pub fn is_mutating_builtin_call(recv: &VMValue, method: &str) -> bool {
// Lightweight table of mutating methods by builtin box type
// Array: set, push
// Map: set, put, insert, remove (superset to future-proof)
const ARRAY_METHODS: &[&str] = &["set", "push"];
const MAP_METHODS: &[&str] = &["set", "put", "insert", "remove"]; // tolerate aliases
match recv {
VMValue::BoxRef(b) => {
if b.as_any()
.downcast_ref::<crate::boxes::array::ArrayBox>()
.is_some()
{
return ARRAY_METHODS.iter().any(|m| *m == method);
}
if b.as_any()
.downcast_ref::<crate::boxes::map_box::MapBox>()
.is_some()
{
return MAP_METHODS.iter().any(|m| *m == method);
}
false
}
_ => false,
}
}
/// Unified trigger for GC Write-Barrier with site logging
pub fn gc_write_barrier_site(runtime: &crate::runtime::NyashRuntime, site: &str) {
let trace = crate::config::env::gc_trace();
let strict = crate::config::env::gc_barrier_strict();
let before = if strict {
runtime.gc.snapshot_counters()
} else {
None
};
if trace {
eprintln!("[GC] barrier: Write @{}", site);
}
runtime.gc.barrier(crate::runtime::gc::BarrierKind::Write);
if strict {
let after = runtime.gc.snapshot_counters();
match (before, after) {
(Some((_, _, bw)), Some((_, _, aw))) if aw > bw => {}
(Some(_), Some(_)) => {
panic!(
"[GC][STRICT] write barrier did not increment at site='{}'",
site
);
}
_ => {
panic!(
"[GC][STRICT] CountingGc required for strict verification at site='{}'",
site
);
}
}
}
}