mmtk/plan/compressor/
gc_work.rs

1use super::global::Compressor;
2use crate::policy::compressor::{CompressorSpace, TRACE_KIND_FORWARD_ROOT, TRACE_KIND_MARK};
3use crate::policy::largeobjectspace::LargeObjectSpace;
4use crate::scheduler::gc_work::PlanProcessEdges;
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 [`CompressorSpace`].
12pub struct GenerateWork<VM: VMBinding, F: Fn(&'static CompressorSpace<VM>) + Send + 'static> {
13    compressor_space: &'static CompressorSpace<VM>,
14    f: F,
15}
16
17impl<VM: VMBinding, F: Fn(&'static CompressorSpace<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.compressor_space);
22    }
23}
24
25impl<VM: VMBinding, F: Fn(&'static CompressorSpace<VM>) + Send + 'static> GenerateWork<VM, F> {
26    pub fn new(compressor_space: &'static CompressorSpace<VM>, f: F) -> Self {
27        Self {
28            compressor_space,
29            f,
30        }
31    }
32}
33
34/// Create another round of root scanning work packets
35/// to update object references.
36pub struct UpdateReferences<VM: VMBinding> {
37    p: PhantomData<VM>,
38}
39
40unsafe impl<VM: VMBinding> Send for UpdateReferences<VM> {}
41
42impl<VM: VMBinding> GCWork<VM> for UpdateReferences<VM> {
43    fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
44        // The following needs to be done right before the second round of root scanning
45        VM::VMScanning::prepare_for_roots_re_scanning();
46        mmtk.state.prepare_for_stack_scanning();
47        #[cfg(feature = "extreme_assertions")]
48        mmtk.slot_logger.reset();
49
50        for mutator in VM::VMActivePlan::mutators() {
51            mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots].add(ScanMutatorRoots::<
52                CompressorForwardingWorkContext<VM>,
53            >(mutator));
54        }
55
56        mmtk.scheduler.work_buckets[WorkBucketStage::SecondRoots]
57            .add(ScanVMSpecificRoots::<CompressorForwardingWorkContext<VM>>::new());
58    }
59}
60
61impl<VM: VMBinding> UpdateReferences<VM> {
62    pub fn new() -> Self {
63        Self { p: PhantomData }
64    }
65}
66
67/// Reset the allocator and update references in large object space.
68pub struct AfterCompact<VM: VMBinding> {
69    compressor_space: &'static CompressorSpace<VM>,
70    los: &'static LargeObjectSpace<VM>,
71}
72
73impl<VM: VMBinding> GCWork<VM> for AfterCompact<VM> {
74    fn do_work(&mut self, worker: &mut GCWorker<VM>, _mmtk: &'static MMTK<VM>) {
75        self.compressor_space.after_compact(worker, self.los);
76    }
77}
78
79impl<VM: VMBinding> AfterCompact<VM> {
80    pub fn new(
81        compressor_space: &'static CompressorSpace<VM>,
82        los: &'static LargeObjectSpace<VM>,
83    ) -> Self {
84        Self {
85            compressor_space,
86            los,
87        }
88    }
89}
90
91/// Marking trace
92pub type MarkingProcessEdges<VM> = PlanProcessEdges<VM, Compressor<VM>, TRACE_KIND_MARK>;
93/// Forwarding trace
94pub type ForwardingProcessEdges<VM> = PlanProcessEdges<VM, Compressor<VM>, TRACE_KIND_FORWARD_ROOT>;
95
96pub struct CompressorWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
97impl<VM: VMBinding> crate::scheduler::GCWorkContext for CompressorWorkContext<VM> {
98    type VM = VM;
99    type PlanType = Compressor<VM>;
100    type DefaultProcessEdges = MarkingProcessEdges<VM>;
101    type PinningProcessEdges = UnsupportedProcessEdges<VM>;
102}
103
104pub struct CompressorForwardingWorkContext<VM: VMBinding>(std::marker::PhantomData<VM>);
105impl<VM: VMBinding> crate::scheduler::GCWorkContext for CompressorForwardingWorkContext<VM> {
106    type VM = VM;
107    type PlanType = Compressor<VM>;
108    type DefaultProcessEdges = ForwardingProcessEdges<VM>;
109    type PinningProcessEdges = UnsupportedProcessEdges<VM>;
110}