use std::marker::PhantomData;
use crate::{
plan::tracing::{gc_work::DefaultObjectTracerContext, Trace},
scheduler::{GCWork, GCWorker, WorkBucketStage},
vm::{Collection, Scanning, VMBinding},
MMTK,
};
pub struct VMProcessWeakRefs<T: Trace> {
phantom_data: PhantomData<T>,
}
impl<T: Trace> VMProcessWeakRefs<T> {
pub fn new() -> Self {
Self {
phantom_data: PhantomData,
}
}
}
impl<T: Trace> GCWork<T::VM> for VMProcessWeakRefs<T> {
fn do_work(&mut self, worker: &mut GCWorker<T::VM>, _mmtk: &'static MMTK<T::VM>) {
trace!("VMProcessWeakRefs");
let stage = WorkBucketStage::VMRefClosure;
let need_to_repeat = {
let tracer_factory = DefaultObjectTracerContext::<T>::new(stage);
<T::VM as VMBinding>::VMScanning::process_weak_refs(worker, tracer_factory)
};
if need_to_repeat {
let new_self = Box::new(Self::new());
worker.scheduler().work_buckets[stage].set_sentinel(new_self);
}
}
}
pub struct VMForwardWeakRefs<T: Trace> {
phantom_data: PhantomData<T>,
}
impl<T: Trace> VMForwardWeakRefs<T> {
pub fn new() -> Self {
Self {
phantom_data: PhantomData,
}
}
}
impl<T: Trace> GCWork<T::VM> for VMForwardWeakRefs<T> {
fn do_work(&mut self, worker: &mut GCWorker<T::VM>, _mmtk: &'static MMTK<T::VM>) {
trace!("VMForwardWeakRefs");
let stage = WorkBucketStage::VMRefForwarding;
let tracer_factory = DefaultObjectTracerContext::<T>::new(stage);
<T::VM as VMBinding>::VMScanning::forward_weak_refs(worker, tracer_factory)
}
}
#[derive(Default)]
pub struct VMPostForwarding<VM: VMBinding> {
phantom_data: PhantomData<VM>,
}
impl<VM: VMBinding> GCWork<VM> for VMPostForwarding<VM> {
fn do_work(&mut self, worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
trace!("VMPostForwarding start");
<VM as VMBinding>::VMCollection::post_forwarding(worker.tls);
trace!("VMPostForwarding end");
}
}