diff --git a/mmtk/src/abi.rs b/mmtk/src/abi.rs index 4876e31..35bd24c 100644 --- a/mmtk/src/abi.rs +++ b/mmtk/src/abi.rs @@ -142,6 +142,34 @@ impl GCThreadTLS { } } +#[repr(C)] +#[derive(Clone)] +pub struct RawVecOfObjRef { + pub ptr: *mut ObjectReference, + pub len: usize, + pub capa: usize, +} + +impl RawVecOfObjRef { + pub fn from_vec(vec: Vec) -> RawVecOfObjRef { + // Note: Vec::into_raw_parts is unstable. We implement it manually. + let mut vec = std::mem::ManuallyDrop::new(vec); + let (ptr, len, capa) = (vec.as_mut_ptr(), vec.len(), vec.capacity()); + + RawVecOfObjRef { ptr, len, capa } + } + + pub unsafe fn into_vec(self) -> Vec { + Vec::from_raw_parts(self.ptr, self.len, self.capa) + } +} + +impl Into for Vec { + fn into(self) -> RawVecOfObjRef { + RawVecOfObjRef::from_vec(self) + } +} + #[repr(C)] #[derive(Clone)] pub struct RubyUpcalls { diff --git a/mmtk/src/api.rs b/mmtk/src/api.rs index 530f248..8ce37ed 100644 --- a/mmtk/src/api.rs +++ b/mmtk/src/api.rs @@ -4,6 +4,7 @@ use std::ffi::CStr; use crate::abi; +use crate::abi::RawVecOfObjRef; use crate::binding::RubyBinding; use crate::mmtk; use crate::Ruby; @@ -208,16 +209,21 @@ pub extern "C" fn mmtk_last_heap_address() -> Address { } #[no_mangle] -pub extern "C" fn mmtk_register_finalizable(reff: ObjectReference) { - crate::binding() - .finalizer_processor - .register_finalizable(reff); +pub extern "C" fn mmtk_add_finalizer(reff: ObjectReference) { + memory_manager::add_finalizer(crate::mmtk(), reff) } #[no_mangle] -pub extern "C" fn mmtk_poll_finalizable(include_live: bool) -> ObjectReference { - crate::binding() - .finalizer_processor - .poll_finalizable(include_live) - .unwrap_or_else(|| unsafe { Address::zero().to_object_reference() }) +pub extern "C" fn mmtk_get_finalized_object() -> ObjectReference { + memory_manager::get_finalized_object(crate::mmtk()).unwrap_or(ObjectReference::NULL) +} + +#[no_mangle] +pub extern "C" fn mmtk_get_all_finalizers() -> RawVecOfObjRef { + memory_manager::get_all_finalizers(crate::mmtk()).into() +} + +#[no_mangle] +pub extern "C" fn mmtk_free_raw_vec_of_obj_ref(raw_vec: RawVecOfObjRef) { + unsafe { raw_vec.into_vec() }; } diff --git a/mmtk/src/binding.rs b/mmtk/src/binding.rs index d2699cc..c0ddd70 100644 --- a/mmtk/src/binding.rs +++ b/mmtk/src/binding.rs @@ -4,13 +4,11 @@ use std::sync::Mutex; use mmtk::MMTK; use crate::abi; -use crate::finalize; use crate::Ruby; pub struct RubyBinding { pub mmtk: &'static MMTK, pub upcalls: *const abi::RubyUpcalls, - pub finalizer_processor: finalize::FinalizerProcessor, pub plan_name: Mutex>, } @@ -22,7 +20,6 @@ impl RubyBinding { Self { mmtk, upcalls, - finalizer_processor: finalize::FinalizerProcessor::new(), plan_name: Mutex::new(None), } } diff --git a/mmtk/src/finalize.rs b/mmtk/src/finalize.rs deleted file mode 100644 index 69948c8..0000000 --- a/mmtk/src/finalize.rs +++ /dev/null @@ -1,37 +0,0 @@ -use mmtk::util::ObjectReference; - -use std::{sync::Mutex, vec}; - -/// TODO: This is a workaround to support Ruby's semantics that finalizes everything on exit. -/// In the future, it should be supported to upstream. -pub struct FinalizerProcessor { - candidates: Mutex>, -} - -impl FinalizerProcessor { - pub fn new() -> Self { - Self { - candidates: Mutex::new(vec![]), - } - } - - pub(crate) fn with_candidates(&self, callback: F) -> T - where - F: FnOnce(&Vec) -> T, - { - let guard = self.candidates.lock().unwrap(); - callback(&guard) - } - - pub fn register_finalizable(&self, reff: ObjectReference) { - self.candidates.lock().unwrap().push(reff); - } - - pub fn poll_finalizable(&self, include_live: bool) -> Option { - if include_live { - self.candidates.lock().unwrap().pop() - } else { - None - } - } -} diff --git a/mmtk/src/lib.rs b/mmtk/src/lib.rs index d69a01d..e1a2a74 100644 --- a/mmtk/src/lib.rs +++ b/mmtk/src/lib.rs @@ -14,7 +14,6 @@ pub mod active_plan; pub mod api; pub mod binding; pub mod collection; -pub mod finalize; pub mod object_model; pub mod reference_glue; pub mod scanning; diff --git a/mmtk/src/scanning.rs b/mmtk/src/scanning.rs index f6e4c72..6eb0b97 100644 --- a/mmtk/src/scanning.rs +++ b/mmtk/src/scanning.rs @@ -66,15 +66,6 @@ impl Scanning for VMScanning { Self::collect_object_roots_in("scan_vm_specific_roots", gc_tls, &mut factory, || { (upcalls().scan_vm_specific_roots)(); }); - { - // FIXME: This is a workaround. Obviously it will keep all finalizable objects alive until program exits. - debug!("[scan_vm_specific_roots] Enqueueing candidates."); - let candidates = crate::binding() - .finalizer_processor - .with_candidates(|v| v.to_vec()); - factory.create_process_node_roots_work(candidates); - debug!("[scan_vm_specific_roots] Finished Enqueueing candidates."); - } } fn supports_return_barrier() -> bool {