mmtk/plan/compressor/
global.rs1use super::gc_work::CompressorWorkContext;
2use super::gc_work::{AfterCompact, ForwardingTrace, GenerateWork, MarkingTrace, UpdateReferences};
3use crate::plan::compressor::mutator::ALLOCATOR_MAPPING;
4use crate::plan::global::CreateGeneralPlanArgs;
5use crate::plan::global::CreateSpecificPlanArgs;
6use crate::plan::global::{BasePlan, CommonPlan};
7use crate::plan::plan_constraints::MAX_NON_LOS_ALLOC_BYTES_COPYING_PLAN;
8use crate::plan::tracing::gc_work::weakref::{
9 VMForwardWeakRefs, VMPostForwarding, VMProcessWeakRefs,
10};
11use crate::plan::{AllocationSemantics, Plan, PlanConstraints};
12use crate::policy::compressor::CompressorSpace;
13use crate::policy::space::Space;
14use crate::scheduler::gc_work::*;
15use crate::scheduler::{GCWorkScheduler, WorkBucketStage};
16use crate::util::alloc::allocators::AllocatorSelector;
17use crate::util::heap::gc_trigger::SpaceStats;
18#[allow(unused_imports)]
19use crate::util::heap::VMRequest;
20use crate::util::metadata::side_metadata::SideMetadataContext;
21use crate::util::opaque_pointer::*;
22use crate::vm::VMBinding;
23use enum_map::EnumMap;
24use mmtk_macros::{HasSpaces, PlanTraceObject};
25
26#[derive(HasSpaces, PlanTraceObject)]
30pub struct Compressor<VM: VMBinding> {
31 #[parent]
32 pub common: CommonPlan<VM>,
33 #[space]
34 pub compressor_space: CompressorSpace<VM>,
35}
36
37pub const COMPRESSOR_CONSTRAINTS: PlanConstraints = PlanConstraints {
39 max_non_los_default_alloc_bytes: MAX_NON_LOS_ALLOC_BYTES_COPYING_PLAN,
40 moves_objects: true,
41 needs_forward_after_liveness: true,
42 ..PlanConstraints::default()
43};
44
45impl<VM: VMBinding> Plan for Compressor<VM> {
46 fn constraints(&self) -> &'static PlanConstraints {
47 &COMPRESSOR_CONSTRAINTS
48 }
49
50 fn collection_required(&self, space_full: bool, _space: Option<SpaceStats<Self::VM>>) -> bool {
51 self.base().collection_required(self, space_full)
52 }
53
54 fn common(&self) -> &CommonPlan<VM> {
55 &self.common
56 }
57
58 fn base(&self) -> &BasePlan<VM> {
59 &self.common.base
60 }
61
62 fn base_mut(&mut self) -> &mut BasePlan<Self::VM> {
63 &mut self.common.base
64 }
65
66 fn prepare(&mut self, tls: VMWorkerThread) {
67 self.common.prepare(tls, true);
68 self.compressor_space.prepare();
69 }
70
71 fn release(&mut self, tls: VMWorkerThread) {
72 self.common.release(tls, true);
73 self.compressor_space.release();
74 }
75
76 fn end_of_gc(&mut self, tls: VMWorkerThread) {
77 self.common.end_of_gc(tls);
78 }
79
80 fn get_allocator_mapping(&self) -> &'static EnumMap<AllocationSemantics, AllocatorSelector> {
81 &ALLOCATOR_MAPPING
82 }
83
84 fn schedule_collection(&'static self, scheduler: &GCWorkScheduler<VM>) {
85 scheduler.work_buckets[WorkBucketStage::Unconstrained]
90 .add(StopMutators::<CompressorWorkContext<VM>>::new());
91
92 scheduler.work_buckets[WorkBucketStage::Prepare]
94 .add(Prepare::<CompressorWorkContext<VM>>::new(self));
95
96 scheduler.work_buckets[WorkBucketStage::CalculateForwarding].add(GenerateWork::new(
97 &self.compressor_space,
98 CompressorSpace::<VM>::add_offset_vector_tasks,
99 ));
100
101 scheduler.work_buckets[WorkBucketStage::SecondRoots].add(UpdateReferences::<VM>::new());
103
104 scheduler.work_buckets[WorkBucketStage::Compact].add(GenerateWork::new(
105 &self.compressor_space,
106 CompressorSpace::<VM>::add_compact_tasks,
107 ));
108
109 scheduler.work_buckets[WorkBucketStage::Compact].set_sentinel(Box::new(
110 AfterCompact::<VM>::new(&self.compressor_space, &self.common.los),
111 ));
112
113 scheduler.work_buckets[WorkBucketStage::Release]
115 .add(Release::<CompressorWorkContext<VM>>::new(self));
116
117 if !*self.base().options.no_reference_types {
119 use crate::util::reference_processor::{
120 PhantomRefProcessing, SoftRefProcessing, WeakRefProcessing,
121 };
122 scheduler.work_buckets[WorkBucketStage::SoftRefClosure]
123 .add(SoftRefProcessing::<MarkingTrace<VM>>::new());
124 scheduler.work_buckets[WorkBucketStage::WeakRefClosure]
125 .add(WeakRefProcessing::<VM>::new());
126 scheduler.work_buckets[WorkBucketStage::PhantomRefClosure]
127 .add(PhantomRefProcessing::<VM>::new());
128
129 use crate::util::reference_processor::RefForwarding;
130 scheduler.work_buckets[WorkBucketStage::RefForwarding]
131 .add(RefForwarding::<ForwardingTrace<VM>>::new());
132
133 use crate::util::reference_processor::RefEnqueue;
134 scheduler.work_buckets[WorkBucketStage::Release].add(RefEnqueue::<VM>::new());
135 }
136
137 if !*self.base().options.no_finalizer {
139 use crate::util::finalizable_processor::{Finalization, ForwardFinalization};
140 scheduler.work_buckets[WorkBucketStage::FinalRefClosure]
144 .add(Finalization::<MarkingTrace<VM>>::new());
145 scheduler.work_buckets[WorkBucketStage::FinalizableForwarding]
148 .add(ForwardFinalization::<ForwardingTrace<VM>>::new());
149 }
150
151 scheduler.work_buckets[WorkBucketStage::VMRefClosure]
153 .set_sentinel(Box::new(VMProcessWeakRefs::<MarkingTrace<VM>>::new()));
154
155 scheduler.work_buckets[WorkBucketStage::VMRefForwarding]
157 .add(VMForwardWeakRefs::<ForwardingTrace<VM>>::new());
158
159 scheduler.work_buckets[WorkBucketStage::Release].add(VMPostForwarding::<VM>::default());
161
162 #[cfg(feature = "analysis")]
164 {
165 use crate::util::analysis::GcHookWork;
166 scheduler.work_buckets[WorkBucketStage::Unconstrained].add(GcHookWork);
167 }
168 #[cfg(feature = "sanity")]
169 scheduler.work_buckets[WorkBucketStage::Final]
170 .add(crate::util::sanity::sanity_checker::ScheduleSanityGC::<Self>::new(self));
171 }
172
173 fn current_gc_may_move_object(&self) -> bool {
174 true
175 }
176
177 fn get_used_pages(&self) -> usize {
178 self.compressor_space.reserved_pages() + self.common.get_used_pages()
179 }
180}
181
182impl<VM: VMBinding> Compressor<VM> {
183 pub fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
184 let mut plan_args = CreateSpecificPlanArgs {
185 global_args: args,
186 constraints: &COMPRESSOR_CONSTRAINTS,
187 global_side_metadata_specs: SideMetadataContext::new_global_specs(&[]),
188 };
189
190 Compressor {
191 compressor_space: CompressorSpace::new(plan_args.get_normal_space_args(
192 "compressor_space",
193 true,
194 false,
195 VMRequest::discontiguous(),
196 )),
197 common: CommonPlan::new(plan_args),
198 }
199 }
200}