refactor: merge GcRoot & Vm

This commit is contained in:
2026-04-19 13:07:07 +08:00
parent df9664f5c4
commit 74866ec1d3
2 changed files with 40 additions and 43 deletions
+39 -41
View File
@@ -112,27 +112,25 @@ impl<T: VmContext> VmContextExt for T {
}
}
#[allow(dead_code)]
pub struct Vm<C: VmContext> {
arena: Arena<Rootable![GcRoot<'_>]>,
error_context: Vec<ErrorFrame>,
ctx: C,
pc: usize,
force_mode: ForceMode,
}
#[derive(Collect)]
#[collect(no_drop)]
struct GcRoot<'gc> {
pub struct Vm<'gc> {
stack: Vec<Value<'gc>>,
call_stack: Vec<CallFrame<'gc>>,
call_depth: usize,
#[collect(require_static)]
error_context: Vec<ErrorFrame>,
env: GcEnv<'gc>,
with_env: Option<Gc<'gc, WithEnv<'gc>>>,
import_cache: HashMap<PathBuf, Value<'gc>>,
builtins: Value<'gc>,
empty_list: Value<'gc>,
empty_attrs: Value<'gc>,
import_cache: HashMap<PathBuf, Value<'gc>>,
env: GcEnv<'gc>,
force_mode: ForceMode,
}
fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc> {
@@ -179,7 +177,7 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc
entries.push((name, val));
}
let self_ref_thunk: Gc<'gc, Thunk<'gc>> = Gc::new(mc, RefLock::new(ThunkState::Blackhole));
let self_ref_thunk = Gc::new(mc, RefLock::new(ThunkState::Blackhole));
let sym = ctx.intern_string("builtins");
entries.push((sym, Value::new_gc(self_ref_thunk)));
@@ -189,19 +187,25 @@ fn init_builtins<'gc>(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Value<'gc
Value::new_gc(builtins_set)
}
impl<'gc> GcRoot<'gc> {
fn new(mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self {
impl<'gc> Vm<'gc> {
fn new(force_mode: ForceMode, mc: &Mutation<'gc>, ctx: &mut impl VmContext) -> Self {
let builtins = init_builtins(mc, ctx);
GcRoot {
Vm {
stack: Vec::with_capacity(8192),
call_stack: Vec::with_capacity(1024),
call_depth: 0,
error_context: Vec::with_capacity(1024),
env: Gc::new(mc, RefLock::new(Env::empty())),
with_env: None,
import_cache: HashMap::new(),
builtins,
empty_list: Value::new_gc(Gc::new(mc, List::default())),
empty_attrs: Value::new_gc(Gc::new(mc, AttrSet::default())),
import_cache: HashMap::new(),
env: Gc::new(mc, RefLock::new(Env::empty())),
force_mode,
}
}
@@ -277,7 +281,7 @@ enum OperandData {
}
impl OperandData {
fn resolve<'gc>(&self, mc: &Mutation<'gc>, root: &GcRoot<'gc>) -> Value<'gc> {
fn resolve<'gc>(&self, mc: &Mutation<'gc>, root: &Vm<'gc>) -> Value<'gc> {
match *self {
OperandData::Const(sv) => sv.into(),
OperandData::Local { layer, idx } => {
@@ -313,36 +317,30 @@ macro_rules! try_vm {
($self:ident; $expr:expr) => {
match $expr {
Ok(v) => v,
Err(e) => return GcRoot::handle_vm_error($self, e),
Err(e) => return Vm::handle_vm_error($self, e),
}
};
}
impl<C: VmContext> Vm<C> {
pub fn new(mut ctx: C, ip: InstructionPtr, force_mode: ForceMode) -> Self {
Self {
arena: Arena::new(|mc| GcRoot::new(mc, &mut ctx)),
ctx,
force_mode,
pc: ip.0,
error_context: Vec::new(),
}
}
impl Vm<'_> {
pub fn run<C: VmContext>(
mut ctx: C,
ip: InstructionPtr,
force_mode: ForceMode,
) -> Result<fix_common::Value> {
let mut arena: Arena<Rootable![Vm<'_>]> =
Arena::new(|mc| Vm::new(force_mode, mc, &mut ctx));
pub fn run(mut self) -> Result<fix_common::Value> {
const COLLECTOR_GRANULARITY: f64 = 1024.0;
let mut pc = self.pc;
let mut pc = ip.0;
loop {
match self
.arena
.mutate_root(|mc, root| root.execute_batch(&mut self.ctx, &mut pc, mc))
{
match arena.mutate_root(|mc, root| root.execute_batch(&mut ctx, &mut pc, mc)) {
Action::Continue => {
if self.arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY {
if self.arena.collection_phase() == CollectionPhase::Sweeping {
self.arena.collect_debt();
} else if let Some(marked) = self.arena.mark_debt() {
if arena.metrics().allocation_debt() > COLLECTOR_GRANULARITY {
if arena.collection_phase() == CollectionPhase::Sweeping {
arena.collect_debt();
} else if let Some(marked) = arena.mark_debt() {
marked.start_sweeping();
}
}
@@ -353,7 +351,7 @@ impl<C: VmContext> Vm<C> {
}
}
impl<'gc> GcRoot<'gc> {
impl<'gc> Vm<'gc> {
#[inline(always)]
fn execute_batch(
&mut self,