mmtk/plan/markcompact/ovc/
gc_work.rs

1use super::global::OVC;
2use crate::plan::tracing::{PlanTrace, UnsupportedTrace};
3use crate::policy::largeobjectspace::LargeObjectSpace;
4use crate::policy::ovc::{OVCSpace, TRACE_KIND_FORWARD_ROOT, TRACE_KIND_MARK};
5use crate::scheduler::gc_work::*;
6use crate::scheduler::{GCWork, GCWorker, WorkBucketStage};
7use crate::vm::{ActivePlan, Scanning, VMBinding};
8use crate::MMTK;
9use std::marker::{PhantomData, Send};
10
11/// Generate more packets by calling a method on [`OVCSpace`].
12pub struct GenerateWork<VM: VMBinding, F: Fn(&'static OVCSpace<VM>) + Send + 'static> {
13    ovc_space: &'static OVCSpace<VM>,
14    f: F,
15}
16
17impl<VM: VMBinding, F: Fn(&'static OVCSpace<VM>) + Send + 'static> GCWork<VM>
18    for GenerateWork<VM, F>
19{
20    fn do_work(&mut self, _worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
21        (self.f)(self.ovc_space);
22    }
23}
24
25impl<VM: VMBinding, F: Fn(&'static OVCSpace<VM>) + Send + 'static> GenerateWork<VM, F> {
26    pub fn new(ovc_space: &'static OVCSpace<VM>, f: F) -> Self {
27        Self { ovc_space, f }
28    }
29}
30
31/// Create another round of root scanning work packets
32/// to update object references.
33pub struct UpdateReferences<VM: VMBinding> {
34    p: PhantomData<VM>,
35}
36
37unsafe impl<VM: VMBinding> Send for UpdateReferences<VM> {}
38
39impl<VM: VMBinding> GCWork<VM> for UpdateReferences<VM> {
40    fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
41        // The following needs to be done right before the second round of root scanning
42        VM::VMScanning::prepare_for_roots_re_scanning();
43        mmtk.state.prepare_for_stack_scanning();
44        #[cfg(feature = "extreme_assertions")]
45        mmtk.slot_logger.reset();
46
47        for mutator in VM::VMActivePlan::mutators() {
48            mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots]
49                .add(ScanMutatorRoots::<OVCForwardingWorkContext<VM>>(mutator));
50        }
51
52        mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots]
53            .add(ScanVMSpecificRoots::<OVCForwardingWorkContext<VM>>::new());
54    }
55}
56
57impl<VM: VMBinding> UpdateReferences<VM> {
58    pub fn new() -> Self {
59        Self { p: PhantomData }
60    }
61}
62
63/// Reset the allocator and update references in large object space.
64pub struct AfterCompact<VM: VMBinding> {
65    ovc_space: &'static OVCSpace<VM>,
66    los: &'static LargeObjectSpace<VM>,
67}
68
69impl<VM: VMBinding> GCWork<VM> for AfterCompact<VM> {
70    fn do_work(&mut self, worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
71        self.ovc_space.after_compact(worker, self.los);
72    }
73}
74
75impl<VM: VMBinding> AfterCompact<VM> {
76    pub fn new(ovc_space: &'static OVCSpace<VM>, los: &'static LargeObjectSpace<VM>) -> Self {
77        Self { ovc_space, los }
78    }
79}
80
81/// Marking trace
82pub type MarkingTrace<VM> = PlanTrace<OVC<VM>, TRACE_KIND_MARK>;
83/// Forwarding trace
84pub type ForwardingTrace<VM> = PlanTrace<OVC<VM>, TRACE_KIND_FORWARD_ROOT>;
85
86pub struct OVCWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
87impl<VM: VMBinding> crate::scheduler::GCWorkContext for OVCWorkContext<VM> {
88    type VM = VM;
89    type PlanType = OVC<VM>;
90    type DefaultTrace = MarkingTrace<VM>;
91    type PinningTrace = UnsupportedTrace<VM>;
92}
93
94pub struct OVCForwardingWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
95impl<VM: VMBinding> crate::scheduler::GCWorkContext for OVCForwardingWorkContext<VM> {
96    type VM = VM;
97    type PlanType = OVC<VM>;
98    type DefaultTrace = ForwardingTrace<VM>;
99    type PinningTrace = UnsupportedTrace<VM>;
100}