feat: get rid of gc and cyclic thunk

This commit is contained in:
2025-06-05 16:43:47 +08:00
parent 51f8df9cca
commit 484cfa4610
17 changed files with 342 additions and 595 deletions

View File

@@ -1,7 +1,5 @@
use std::cell::Cell;
use gc_arena::lock::{GcRefLock, RefLock};
use gc_arena::{Collect, Gc, Mutation};
use std::cell::{Cell, OnceCell};
use std::rc::Rc;
use crate::bytecode::Func as BFunc;
use crate::env::VmEnv;
@@ -11,8 +9,7 @@ use crate::jit::JITFunc;
use crate::ty::internal::Value;
use crate::vm::VM;
#[derive(Debug, Clone, Collect)]
#[collect(no_drop)]
#[derive(Debug, Clone)]
pub enum Param {
Ident(usize),
Formals {
@@ -44,42 +41,25 @@ impl From<ir::Param> for Param {
pub struct Func<'gc> {
pub func: &'gc BFunc,
pub env: Gc<'gc, VmEnv<'gc>>,
pub compiled: GcRefLock<'gc, Option<JITFunc<'gc>>>,
pub env: Rc<VmEnv<'gc>>,
pub compiled: OnceCell<JITFunc<'gc>>,
pub count: Cell<usize>,
}
unsafe impl<'gc> Collect<'gc> for Func<'gc> {
fn trace<Tr: gc_arena::collect::Trace<'gc>>(&self, cc: &mut Tr) {
self.env.trace(cc);
self.compiled.trace(cc);
self.count.trace(cc);
}
}
impl<'gc> Func<'gc> {
pub fn new(func: &'gc BFunc, env: Gc<'gc, VmEnv<'gc>>, mc: &Mutation<'gc>) -> Self {
pub fn new(func: &'gc BFunc, env: Rc<VmEnv<'gc>>) -> Self {
Self {
func,
env,
compiled: Gc::new(mc, RefLock::new(None)),
compiled: OnceCell::new(),
count: Cell::new(0),
}
}
pub fn call_compile(
&self,
arg: Value<'gc>,
vm: &'gc VM<'gc>,
mc: &Mutation<'gc>,
) -> Result<Value<'gc>> {
let env = self.env.enter_arg(arg, mc);
let compiled = self
.compiled
.borrow_mut(mc)
.get_or_insert_with(|| vm.compile_func(self.func))
.clone();
let ret = unsafe { compiled(env.as_ref() as *const VmEnv, mc as *const _) };
pub fn call_compile(&self, arg: Value<'gc>, vm: &'gc VM<'gc>) -> Result<Value<'gc>> {
let env = self.env.clone().enter_arg(arg);
let compiled = self.compiled.get_or_init(|| vm.compile_func(self.func));
let ret = unsafe { compiled(env.as_ref() as *const VmEnv) };
Ok(ret.into())
}
}