From 51f8df9ccad73945c138a27f6f1f1253dea5534f Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Mon, 2 Jun 2025 14:18:59 +0800 Subject: [PATCH] feat: less gc (WIP) --- Cargo.lock | 7 ++ Cargo.toml | 1 + src/builtins/mod.rs | 16 ++-- src/env.rs | 22 ++--- src/jit/helpers.rs | 14 ++-- src/jit/mod.rs | 23 +++--- src/ty/internal/attrset.rs | 9 ++- src/ty/internal/list.rs | 9 ++- src/ty/internal/mod.rs | 162 +++++++++---------------------------- src/ty/internal/primop.rs | 13 +-- src/vm/mod.rs | 28 +++---- 11 files changed, 125 insertions(+), 179 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9388206..7868885 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,6 +324,7 @@ dependencies = [ "inkwell", "itertools", "regex", + "replace_with", "rnix", "rustyline", "thiserror 2.0.12", @@ -398,6 +399,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "replace_with" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51743d3e274e2b18df81c4dc6caf8a5b8e15dbe799e0dca05c7617380094e884" + [[package]] name = "rnix" version = "0.12.0" diff --git a/Cargo.toml b/Cargo.toml index 5032109..1bf29d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ derive_more = { version = "2.0", features = ["full"] } ecow = "0.2" regex = "1.11" hashbrown = "0.15" +replace_with = "0.1" inkwell = { version = "0.6.0", features = ["llvm18-1"] } gc-arena = { git = "https://github.com/kyren/gc-arena", rev = "d651e3b4363d525a2d502c2305bc73e291835c84", features= ["hashbrown"] } diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index 817b2c0..e4b8e67 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -1,10 +1,12 @@ +use std::rc::Rc; + use gc_arena::{Gc, Mutation}; use hashbrown::HashMap; use crate::env::VmEnv; use crate::ir::{DowngradeContext, Ir}; use crate::ty::common::Const; -use crate::ty::internal::{AttrSet, CoW, PrimOp, Value}; +use crate::ty::internal::{AttrSet, PrimOp, Value}; use crate::vm::VM; pub fn ir_env(ctx: &mut DowngradeContext) -> HashMap { @@ -21,7 +23,7 @@ pub fn vm_env<'gc>(vm: &VM, mc: &Mutation<'gc>) -> Gc<'gc, VmEnv<'gc>> { let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else { unreachable!() }; - first.add(second, mc); + first.add(second); first.ok() }), PrimOp::new("sub", 2, |args, _, mc| { @@ -29,7 +31,7 @@ pub fn vm_env<'gc>(vm: &VM, mc: &Mutation<'gc>) -> Gc<'gc, VmEnv<'gc>> { unreachable!() }; second.neg(); - first.add(second, mc); + first.add(second); first.ok() }), PrimOp::new("mul", 2, |args, _, _| { @@ -75,15 +77,15 @@ pub fn vm_env<'gc>(vm: &VM, mc: &Mutation<'gc>) -> Gc<'gc, VmEnv<'gc>> { let mut map = HashMap::new(); for primop in primops { - let primop = Gc::new(mc, primop); + let primop = Rc::new(primop); env_map.insert( vm.new_sym(format!("__{}", primop.name)), - Value::PrimOp(primop), + Value::PrimOp(primop.clone()), ); map.insert(vm.new_sym(primop.name), Value::PrimOp(primop)); } let sym = vm.new_sym("builtins"); - let mut attrs = CoW::new(AttrSet::new(map), mc); + /* let mut attrs = CoW::new(AttrSet::new(map), mc); unsafe { attrs.make_cyclic(|attrs, this| { let _ = attrs.push_attr(sym, Value::AttrSet(this)); @@ -91,7 +93,7 @@ pub fn vm_env<'gc>(vm: &VM, mc: &Mutation<'gc>) -> Gc<'gc, VmEnv<'gc>> { } let builtins = Value::AttrSet(attrs); - env_map.insert(sym, builtins); + env_map.insert(sym, builtins); */ // TODO: // VmEnv::new(Gc::new(mc, env_map), mc) VmEnv::new(Vec::new(), mc) diff --git a/src/env.rs b/src/env.rs index 7d54dc2..2a30ac2 100644 --- a/src/env.rs +++ b/src/env.rs @@ -11,7 +11,7 @@ pub struct Env<'gc, K: Hash + Eq + Collect<'gc>, V: Collect<'gc>> { let_: Gc<'gc, LetEnv<'gc, V>>, with: Gc<'gc, With<'gc, K, V>>, args: Vec, - gc_alloced: Vec>, + jit_store: Vec>, last: Option>>, } @@ -60,7 +60,7 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc, }, ), args: Vec::new(), - gc_alloced: Vec::new(), + jit_store: Vec::new(), last: None, }, ) @@ -92,7 +92,7 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc, let_: self.let_, with: self.with, last: Some(self), - gc_alloced: Vec::new(), + jit_store: Vec::new(), args }, ) @@ -110,7 +110,7 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc, let_: self.let_.enter_let(map, mc), with: self.with, args: self.args.clone(), - gc_alloced: Vec::new(), + jit_store: Vec::new(), last: Some(self), }, ) @@ -128,17 +128,21 @@ impl<'gc, K: Hash + Eq + Clone + Collect<'gc>, V: Clone + Collect<'gc>> Env<'gc, let_: self.let_, with: self.with.enter(map, mc), args: self.args.clone(), - gc_alloced: Vec::new(), + jit_store: Vec::new(), last: Some(self), }, ) } #[inline] - pub fn alloc_gc(&mut self, val: V, mc: &Mutation<'gc>) -> &'gc V { - let gc = Gc::new(mc, val); - self.gc_alloced.push(gc); - gc.as_ref() + pub fn jit_store(&'gc mut self, val: V) -> &'gc V { + self.jit_store.push(Box::new(val)); + &self.jit_store[self.jit_store.len() - 1] + } + + #[inline] + pub fn jit_stored(&self) -> usize { + self.jit_store.len() } pub fn leave(&self) -> Gc<'gc, Self> { diff --git a/src/jit/helpers.rs b/src/jit/helpers.rs index 8d8a24f..0474d14 100644 --- a/src/jit/helpers.rs +++ b/src/jit/helpers.rs @@ -361,7 +361,7 @@ extern "C" fn helper_call<'gc>( ValueTag::Function => { let func = Value::from(func).unwrap_func(); let env = unsafe { &mut *env }; - env.alloc_gc(func.call_compile(arg, vm, mc).unwrap(), mc).into() + func.call_compile(arg, vm, mc).unwrap().clone().into() } _ => todo!(), } @@ -369,19 +369,19 @@ extern "C" fn helper_call<'gc>( extern "C" fn helper_arg(idx: usize, env: *const VmEnv) -> JITValue { let env = unsafe { env.as_ref() }.unwrap(); - let val: JITValue = env.lookup_arg(idx).into(); + let val: JITValue = env.lookup_arg(idx).clone().into(); val } extern "C" fn helper_lookup_let(level: usize, idx: usize, env: *const VmEnv) -> JITValue { let env = unsafe { env.as_ref() }.unwrap(); - let val: JITValue = env.lookup_let(level, idx).into(); + let val: JITValue = env.lookup_let(level, idx).clone().into(); val } extern "C" fn helper_lookup(sym: usize, env: *const VmEnv) -> JITValue { let env = unsafe { env.as_ref() }.unwrap(); - let val: JITValue = env.lookup_with(&sym).unwrap().into(); + let val: JITValue = env.lookup_with(&sym).unwrap().clone().into(); val } @@ -399,7 +399,7 @@ extern "C" fn helper_force<'gc>( let mc = unsafe { mc.as_ref() }.unwrap(); let thunk = Value::from(thunk).unwrap_thunk(); if let Some(val) = thunk.get_value() { - return val.into(); + return val.clone().into(); } let (opcodes, env) = thunk.suspend(mc).unwrap(); let func = unsafe { jit.as_ref() } @@ -414,9 +414,9 @@ extern "C" fn helper_force<'gc>( extern "C" fn helper_new_thunk<'gc>(opcodes: *const OpCodes, env: *mut VmEnv<'gc>, mc: *const Mutation<'gc>) -> JITValue { let mc = unsafe { &*mc }; let env = unsafe { &mut *env }; - env.alloc_gc(Value::Thunk(Thunk::new( + Value::Thunk(Thunk::new( unsafe { opcodes.as_ref() }.unwrap(), mc - )), mc) + )) .into() } diff --git a/src/jit/mod.rs b/src/jit/mod.rs index 631a3dd..d30b947 100644 --- a/src/jit/mod.rs +++ b/src/jit/mod.rs @@ -1,4 +1,5 @@ use std::marker::PhantomData; +use std::rc::Rc; use std::ops::Deref; use gc_arena::{Collect, Gc, Mutation}; @@ -63,7 +64,7 @@ impl<'gc> From for Value<'gc> { match value.tag { Int => Value::Int(unsafe { value.data.int }), Null => Value::Null, - Function => Value::Func(unsafe { Gc::from_ptr(value.data.ptr as *const _) }), + Function => Value::Func(unsafe { Rc::from_raw(value.data.ptr as *const _) }), Thunk => Value::Thunk(self::Thunk { thunk: unsafe { Gc::from_ptr(value.data.ptr as *const _) }, }), @@ -72,19 +73,21 @@ impl<'gc> From for Value<'gc> { } } -impl From<&Value<'_>> for JITValue { - fn from(value: &Value) -> Self { +impl From> for JITValue { + fn from(value: Value) -> Self { match value { - &Value::Int(int) => JITValue { + Value::Int(int) => JITValue { tag: ValueTag::Int, data: JITValueData { int }, }, - &Value::Func(func) => JITValue { - tag: ValueTag::Function, - data: JITValueData { - ptr: Gc::as_ptr(func) as *const _, - }, - }, + Value::Func(func) => { + JITValue { + tag: ValueTag::Function, + data: JITValueData { + ptr: Rc::into_raw(func) as *const _, + }, + } + } Value::Thunk(thunk) => JITValue { tag: ValueTag::Thunk, data: JITValueData { diff --git a/src/ty/internal/attrset.rs b/src/ty/internal/attrset.rs index 04fdffe..83a1cf8 100644 --- a/src/ty/internal/attrset.rs +++ b/src/ty/internal/attrset.rs @@ -12,12 +12,17 @@ use super::super::public as p; use super::Value; #[repr(transparent)] -#[derive(Constructor, Clone, PartialEq, Collect)] -#[collect(no_drop)] +#[derive(Constructor, Clone, PartialEq)] pub struct AttrSet<'gc> { data: HashMap>, } +unsafe impl<'gc> Collect<'gc> for AttrSet<'gc> { + fn trace>(&self, cc: &mut T) { + self.data.trace(cc); + } +} + impl<'gc> From>> for AttrSet<'gc> { fn from(data: HashMap>) -> Self { Self { data } diff --git a/src/ty/internal/list.rs b/src/ty/internal/list.rs index 282ecc4..7ae0a09 100644 --- a/src/ty/internal/list.rs +++ b/src/ty/internal/list.rs @@ -7,12 +7,17 @@ use crate::env::VmEnv; use super::Value; -#[derive(Clone, PartialEq, Collect)] -#[collect(no_drop)] +#[derive(Clone, PartialEq)] pub struct List<'gc> { data: Vec>, } +unsafe impl<'gc> Collect<'gc> for List<'gc> { + fn trace>(&self, cc: &mut T) { + self.data.trace(cc); + } +} + impl<'gc> List<'gc> { pub fn new() -> Self { List { diff --git a/src/ty/internal/mod.rs b/src/ty/internal/mod.rs index 5b6a5aa..61d1dd6 100644 --- a/src/ty/internal/mod.rs +++ b/src/ty/internal/mod.rs @@ -1,12 +1,12 @@ -use std::cell::Cell; use std::hash::Hash; -use std::ops::Deref; +use std::rc::Rc; use derive_more::{IsVariant, Unwrap}; use gc_arena::Mutation; use gc_arena::lock::RefLock; use gc_arena::{Collect, Gc, lock::GcRefLock}; use hashbrown::HashSet; +use replace_with::replace_with_or_abort; use super::common::*; use super::public as p; @@ -27,95 +27,22 @@ pub use func::*; pub use list::List; pub use primop::*; -#[derive(Collect)] -#[collect(unsafe_drop)] -pub struct CoW<'gc, T: Clone + Collect<'gc>> { - inner: Gc<'gc, CoWInner<'gc, T>>, -} - -#[derive(Collect)] -#[collect(no_drop)] -struct CoWInner<'gc, T: Clone + Collect<'gc>> { - ref_count: Cell, - data: GcRefLock<'gc, T>, -} - -#[allow(mutable_transmutes)] -impl<'gc, T: Clone + Collect<'gc>> CoW<'gc, T> { - pub fn new(data: T, mc: &Mutation<'gc>) -> Self { - Self { - inner: Gc::new(mc, CoWInner::new(data, mc)), - } - } - - pub unsafe fn make_cyclic(&mut self, f: impl FnOnce(&mut T, Self), mc: &Mutation<'gc>) { - let inner = self.inner; - self.make_mut(|self_mut| f(self_mut, Self { inner }), mc); - self.inner.ref_count.set(self.inner.ref_count.get() + 1); - } - - pub fn make_mut(&mut self, f: impl FnOnce(&mut T) -> U, mc: &Mutation<'gc>) -> U { - if self.inner.ref_count.get() == 1 { - f(&mut *self.inner.data.borrow_mut(mc)) - } else { - *self = CoW::new(self.inner.data.borrow().clone(), mc); - f(&mut *self.inner.data.borrow_mut(mc)) - } - } - - pub fn as_ptr(&self) -> *const T { - &*self.as_ref() as *const T - } - - pub fn as_ref(&self) -> std::cell::Ref<'_, T> { - self.inner.data.borrow() - } -} - -impl<'gc, T: Clone + Collect<'gc>> Deref for CoW<'gc, T> { - type Target = T; - fn deref(&self) -> &Self::Target { - unsafe { self.as_ptr().as_ref() }.unwrap() - } -} - -impl<'gc, T: Clone + Collect<'gc>> Clone for CoW<'gc, T> { - fn clone(&self) -> Self { - self.inner.ref_count.set(self.inner.ref_count.get() + 1); - Self { inner: self.inner } - } -} - -impl<'gc, T: Clone + Collect<'gc>> Drop for CoW<'gc, T> { - fn drop(&mut self) { - self.inner.ref_count.set(self.inner.ref_count.get() - 1); - } -} - -impl<'gc, T: Clone + Collect<'gc>> CoWInner<'gc, T> { - fn new(data: T, mc: &Mutation<'gc>) -> Self { - Self { - ref_count: Cell::new(1), - data: Gc::new(mc, RefLock::new(data)) - } - } -} - #[derive(IsVariant, Unwrap, Clone, Collect)] #[collect(no_drop)] +// #[derive(IsVariant, Unwrap, Clone)] pub enum Value<'gc> { Int(i64), Float(f64), Bool(bool), - String(CoW<'gc, String>), + String(Rc), Null, Thunk(Thunk<'gc>), - AttrSet(CoW<'gc, AttrSet<'gc>>), - List(CoW<'gc, List<'gc>>), - Catchable(Gc<'gc, String>), - PrimOp(Gc<'gc, PrimOp>), - PartialPrimOp(CoW<'gc, PartialPrimOp<'gc>>), - Func(Gc<'gc, Func<'gc>>), + AttrSet(Rc>), + List(Rc>), + Catchable(Rc), + PrimOp(Rc), + PartialPrimOp(Rc>), + Func(Rc>), } impl Hash for Value<'_> { @@ -123,18 +50,9 @@ impl Hash for Value<'_> { use Value::*; std::mem::discriminant(self).hash(state); match self { - Int(x) => x.hash(state), - Float(x) => x.to_bits().hash(state), - Bool(x) => x.hash(state), - Null => (), - String(x) => x.as_ptr().hash(state), - Thunk(x) => (x as *const self::Thunk).hash(state), - AttrSet(x) => x.as_ptr().hash(state), - List(x) => x.as_ptr().hash(state), - Catchable(x) => x.hash(state), - PrimOp(x) => (x.as_ref() as *const self::PrimOp).hash(state), - PartialPrimOp(x) => x.as_ptr().hash(state), - Func(x) => (x.as_ref() as *const self::Func).hash(state), + AttrSet(x) => Rc::as_ptr(x).hash(state), + List(x) => Rc::as_ptr(x).hash(state), + _ => 0.hash(state), } } } @@ -161,8 +79,8 @@ impl<'gc> PartialEq for Value<'gc> { fn eq(&self, other: &Self) -> bool { use Value::*; match (self, other) { - (AttrSet(a), AttrSet(b)) => a.as_ptr().eq(&b.as_ptr()), - (List(a), List(b)) => a.as_ptr().eq(&b.as_ptr()), + (AttrSet(a), AttrSet(b)) => Rc::as_ptr(a).eq(&Rc::as_ptr(b)), + (List(a), List(b)) => Rc::as_ptr(a).eq(&Rc::as_ptr(b)), _ => false, } } @@ -318,22 +236,23 @@ impl<'gc> Value<'gc> { } } - pub fn add(&mut self, other: Self, mc: &Mutation<'gc>) { + pub fn add(&mut self, other: Self) { use Value::*; - *self = match (&*self, other) { - (Int(a), Int(b)) => Int(a + b), - (Int(a), Float(b)) => Float(*a as f64 + b), - (Float(a), Int(b)) => Float(a + b as f64), - (Float(a), Float(b)) => Float(a + b), - (String(a), String(b)) => { - let mut a = a.clone(); - a.make_mut(|a| a.push_str(b.as_str()), mc); - String(a) + replace_with_or_abort(self, |a| { + match (a, other) { + (Int(a), Int(b)) => Int(a + b), + (Int(a), Float(b)) => Float(a as f64 + b), + (Float(a), Int(b)) => Float(a + b as f64), + (Float(a), Float(b)) => Float(a + b), + (String(mut a), String(b)) => { + Rc::make_mut(&mut a).push_str(&b); + String(a) + } + (a @ Value::Catchable(_), _) => a, + (_, x @ Value::Catchable(_)) => x, + _ => todo!(), } - (Value::Catchable(_), _) => return, - (_, x @ Value::Catchable(_)) => x, - _ => todo!(), - } + }); } pub fn mul(&mut self, other: Self) { @@ -367,11 +286,10 @@ impl<'gc> Value<'gc> { Ok(()) } - pub fn concat_string(&mut self, mut other: Self, mc: &Mutation<'gc>) -> &mut Self { + pub fn concat_string(&mut self, mut other: Self) -> &mut Self { match (self.coerce_to_string(), other.coerce_to_string()) { (Value::String(a), Value::String(b)) => { - let mut a = a.clone(); - a.make_mut(|a| a.push_str(b.as_str()), mc); + Rc::make_mut(a).push_str(b.as_str()); } (_, Value::Catchable(_)) => *self = other, (Value::Catchable(_), _) => (), @@ -380,9 +298,9 @@ impl<'gc> Value<'gc> { self } - pub fn push(&mut self, elem: Self, mc: &Mutation<'gc>) -> &mut Self { + pub fn push(&mut self, elem: Self) -> &mut Self { if let Value::List(list) = self { - list.make_mut(|list| list.push(elem), mc); + Rc::make_mut(list).push(elem); } else if let Value::Catchable(_) = self { } else if let Value::Catchable(_) = elem { *self = elem; @@ -392,23 +310,23 @@ impl<'gc> Value<'gc> { self } - pub fn concat(&mut self, other: Self, mc: &Mutation<'gc>) { + pub fn concat(&mut self, other: Self) { if let x @ Value::Catchable(_) = other { *self = x; return; } match (self, other) { (Value::List(a), Value::List(b)) => { - a.make_mut(|a| a.concat(&b), mc); + Rc::make_mut(a).concat(&b); } (Value::Catchable(_), _) => (), _ => todo!(), } } - pub fn push_attr(&mut self, sym: usize, val: Self, mc: &Mutation<'gc>) -> &mut Self { + pub fn push_attr(&mut self, sym: usize, val: Self) -> &mut Self { if let Value::AttrSet(attrs) = self { - attrs.make_mut(|attrs| attrs.push_attr(sym, val), mc) + Rc::make_mut(attrs).push_attr(sym, val); } else if let Value::Catchable(_) = self { } else if let Value::Catchable(_) = val { *self = val @@ -418,14 +336,14 @@ impl<'gc> Value<'gc> { self } - pub fn update(&mut self, other: Self, mc: &Mutation<'gc>) { + pub fn update(&mut self, other: Self) { if let x @ Value::Catchable(_) = other { *self = x; return; } match (self, other) { (Value::AttrSet(a), Value::AttrSet(b)) => { - a.make_mut(|a| a.update(&b), mc) + Rc::make_mut(a).update(&b); } (Value::Catchable(_), _) => (), _ => todo!(), diff --git a/src/ty/internal/primop.rs b/src/ty/internal/primop.rs index cc0e018..51ae36d 100644 --- a/src/ty/internal/primop.rs +++ b/src/ty/internal/primop.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use derive_more::Constructor; use gc_arena::Collect; use gc_arena::Mutation; @@ -5,7 +7,6 @@ use gc_arena::Mutation; use crate::error::Result; use crate::vm::VM; -use super::CoW; use super::Value; #[derive(Debug, Clone, Constructor, Collect)] @@ -27,14 +28,13 @@ impl PrimOp { let mut args = Vec::with_capacity(self.arity); args.push(arg); if self.arity > 1 { - Value::PartialPrimOp(CoW::new( + Value::PartialPrimOp(Rc::new( PartialPrimOp { name: self.name, arity: self.arity - 1, args, func: self.func, }, - mc, )) .ok() } else { @@ -67,13 +67,14 @@ impl PartialEq for PartialPrimOp<'_> { impl<'gc> PartialPrimOp<'gc> { pub fn call( - self: &mut CoW<'gc, Self>, + self: &mut Rc, arg: Value<'gc>, vm: &VM, mc: &Mutation<'gc>, ) -> Result> { let func = self.func; - let Some(ret) = self.make_mut(|self_mut| { + let Some(ret) = ({ + let self_mut = Rc::make_mut(self); self_mut.args.push(arg); self_mut.arity -= 1; if self_mut.arity == 0 { @@ -81,7 +82,7 @@ impl<'gc> PartialPrimOp<'gc> { } else { None } - }, mc) else { + }) else { return Value::PartialPrimOp(self.clone()).ok(); }; ret diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 1509107..237921f 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -1,4 +1,5 @@ use std::cell::RefCell; +use std::rc::Rc; use gc_arena::arena::CollectionPhase; use gc_arena::{Arena, Collect, Gc, Mutation, Rootable}; @@ -123,7 +124,6 @@ pub fn eval FnOnce(Value<'gc>, &mut GcRoot<'gc>, &Mutation<'gc>) } } } - arena.collect_debt(); arena.mutate_root(|mc, root| { assert_eq!(root.stack.len(), 1); let ret = root.stack.pop(); @@ -158,7 +158,7 @@ fn single_op<'gc, const CAP: usize>( Const::Int(x) => Value::Int(x), Const::Float(x) => Value::Float(x), Const::Bool(x) => Value::Bool(x), - Const::String(x) => Value::String(CoW::new(x.into(), mc)), + Const::String(x) => Value::String(Rc::new(x.into())), Const::Null => Value::Null, })?, OpCode::LoadThunk { idx } => stack.push(Value::Thunk(Thunk::new(vm.get_thunk(idx), mc)))?, @@ -199,7 +199,7 @@ fn single_op<'gc, const CAP: usize>( } OpCode::Func { idx } => { let func = vm.get_func(idx); - stack.push(Value::Func(Gc::new(mc, Func::new(func, *env, mc))))?; + stack.push(Value::Func(Rc::new(Func::new(func, *env, mc))))?; } OpCode::Arg { level } => { stack.push(env.lookup_arg(level).clone())?; @@ -217,10 +217,10 @@ fn single_op<'gc, const CAP: usize>( let mut rhs = stack.pop(); let lhs = stack.tos_mut(); match op { - Add => lhs.add(rhs, mc), + Add => lhs.add(rhs), Sub => { rhs.neg(); - lhs.add(rhs, mc); + lhs.add(rhs); } Mul => lhs.mul(rhs), Div => lhs.div(rhs)?, @@ -228,26 +228,26 @@ fn single_op<'gc, const CAP: usize>( Or => lhs.or(rhs), Eq => Value::eq(lhs, rhs), Lt => lhs.lt(rhs), - Con => lhs.concat(rhs, mc), - Upd => lhs.update(rhs, mc), + Con => lhs.concat(rhs), + Upd => lhs.update(rhs), } } OpCode::ConcatString => { let rhs = stack.pop(); - stack.tos_mut().concat_string(rhs, mc); + stack.tos_mut().concat_string(rhs); } OpCode::Path => { todo!() } OpCode::List { cap } => { - stack.push(Value::List(CoW::new(List::with_capacity(cap), mc)))?; + stack.push(Value::List(Rc::new(List::with_capacity(cap))))?; } OpCode::PushElem => { let elem = stack.pop(); - stack.tos_mut().push(elem, mc); + stack.tos_mut().push(elem); } OpCode::AttrSet { cap } => { - stack.push(Value::AttrSet(CoW::new(AttrSet::with_capacity(cap), mc)))?; + stack.push(Value::AttrSet(Rc::new(AttrSet::with_capacity(cap))))?; } OpCode::FinalizeLet => { let mut list = stack.pop().unwrap_list(); @@ -256,17 +256,17 @@ fn single_op<'gc, const CAP: usize>( .clone() .into_inner(); *env = env.enter_let(map, mc); - list.make_mut(|list| list.capture(*env, mc), mc); + Rc::make_mut(&mut list).capture(*env, mc); } OpCode::PushStaticAttr { name } => { let val = stack.pop(); - stack.tos_mut().push_attr(name, val, mc); + stack.tos_mut().push_attr(name, val); } OpCode::PushDynamicAttr => { let val = stack.pop(); let sym = stack.pop(); let sym = vm.new_sym::<&str>(&sym.unwrap_string()); - stack.tos_mut().push_attr(sym, val, mc); + stack.tos_mut().push_attr(sym, val); } OpCode::Select { sym } => { stack.tos_mut().select(sym, vm)?;