mmtk/plan/nogc/
global.rs

1use crate::plan::global::BasePlan;
2use crate::plan::global::CreateGeneralPlanArgs;
3use crate::plan::global::CreateSpecificPlanArgs;
4use crate::plan::nogc::mutator::ALLOCATOR_MAPPING;
5use crate::plan::AllocationSemantics;
6use crate::plan::Plan;
7use crate::plan::PlanConstraints;
8use crate::policy::immortalspace::ImmortalSpace;
9use crate::policy::space::Space;
10use crate::scheduler::GCWorkScheduler;
11use crate::util::alloc::allocators::AllocatorSelector;
12use crate::util::heap::gc_trigger::SpaceStats;
13#[allow(unused_imports)]
14use crate::util::heap::VMRequest;
15use crate::util::metadata::side_metadata::SideMetadataContext;
16use crate::util::opaque_pointer::*;
17use crate::vm::VMBinding;
18use enum_map::EnumMap;
19use mmtk_macros::HasSpaces;
20
21#[cfg(not(feature = "nogc_lock_free"))]
22use crate::policy::immortalspace::ImmortalSpace as NoGCImmortalSpace;
23#[cfg(feature = "nogc_lock_free")]
24use crate::policy::lockfreeimmortalspace::LockFreeImmortalSpace as NoGCImmortalSpace;
25
26#[derive(HasSpaces)]
27pub struct NoGC<VM: VMBinding> {
28    #[parent]
29    pub base: BasePlan<VM>,
30    #[space]
31    pub nogc_space: NoGCImmortalSpace<VM>,
32    #[space]
33    pub immortal: ImmortalSpace<VM>,
34    #[space]
35    pub los: ImmortalSpace<VM>,
36}
37
38/// The plan constraints for the no gc plan.
39pub const NOGC_CONSTRAINTS: PlanConstraints = PlanConstraints {
40    collects_garbage: false,
41    ..PlanConstraints::default()
42};
43
44impl<VM: VMBinding> Plan for NoGC<VM> {
45    fn constraints(&self) -> &'static PlanConstraints {
46        &NOGC_CONSTRAINTS
47    }
48
49    fn collection_required(&self, space_full: bool, _space: Option<SpaceStats<Self::VM>>) -> bool {
50        self.base().collection_required(self, space_full)
51    }
52
53    fn base(&self) -> &BasePlan<VM> {
54        &self.base
55    }
56
57    fn base_mut(&mut self) -> &mut BasePlan<Self::VM> {
58        &mut self.base
59    }
60
61    fn prepare(&mut self, _tls: VMWorkerThread) {
62        unreachable!()
63    }
64
65    fn release(&mut self, _tls: VMWorkerThread) {
66        unreachable!()
67    }
68
69    fn end_of_gc(&mut self, _tls: VMWorkerThread) {
70        unreachable!()
71    }
72
73    fn get_allocator_mapping(&self) -> &'static EnumMap<AllocationSemantics, AllocatorSelector> {
74        &ALLOCATOR_MAPPING
75    }
76
77    fn schedule_collection(&'static self, _scheduler: &GCWorkScheduler<VM>) {
78        unreachable!("GC triggered in nogc")
79    }
80
81    fn current_gc_may_move_object(&self) -> bool {
82        false
83    }
84
85    fn get_used_pages(&self) -> usize {
86        self.nogc_space.reserved_pages()
87            + self.immortal.reserved_pages()
88            + self.los.reserved_pages()
89            + self.base.get_used_pages()
90    }
91}
92
93impl<VM: VMBinding> NoGC<VM> {
94    pub fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
95        let mut plan_args = CreateSpecificPlanArgs {
96            global_args: args,
97            constraints: &NOGC_CONSTRAINTS,
98            global_side_metadata_specs: SideMetadataContext::new_global_specs(&[]),
99        };
100
101        let res = NoGC {
102            nogc_space: NoGCImmortalSpace::new(plan_args.get_normal_space_args(
103                "nogc_space",
104                cfg!(not(feature = "nogc_no_zeroing")),
105                false,
106                VMRequest::discontiguous(),
107            )),
108            immortal: ImmortalSpace::new(plan_args.get_normal_space_args(
109                "immortal",
110                true,
111                false,
112                VMRequest::discontiguous(),
113            )),
114            los: ImmortalSpace::new(plan_args.get_normal_space_args(
115                "los",
116                true,
117                false,
118                VMRequest::discontiguous(),
119            )),
120            base: BasePlan::new(plan_args),
121        };
122
123        res.verify_side_metadata_sanity();
124
125        res
126    }
127}