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 crate::MMTK;
19use enum_map::EnumMap;
20use mmtk_macros::HasSpaces;
21
22#[cfg(not(feature = "nogc_lock_free"))]
23use crate::policy::immortalspace::ImmortalSpace as NoGCImmortalSpace;
24#[cfg(feature = "nogc_lock_free")]
25use crate::policy::lockfreeimmortalspace::LockFreeImmortalSpace as NoGCImmortalSpace;
26
27#[derive(HasSpaces)]
28pub struct NoGC<VM: VMBinding> {
29    #[parent]
30    pub base: BasePlan<VM>,
31    #[space]
32    pub nogc_space: NoGCImmortalSpace<VM>,
33    #[space]
34    pub immortal: ImmortalSpace<VM>,
35    #[space]
36    pub los: ImmortalSpace<VM>,
37}
38
39/// The plan constraints for the no gc plan.
40pub const NOGC_CONSTRAINTS: PlanConstraints = PlanConstraints {
41    collects_garbage: false,
42    ..PlanConstraints::default()
43};
44
45impl<VM: VMBinding> Plan for NoGC<VM> {
46    fn constraints(&self) -> &'static PlanConstraints {
47        &NOGC_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 base(&self) -> &BasePlan<VM> {
55        &self.base
56    }
57
58    fn base_mut(&mut self) -> &mut BasePlan<Self::VM> {
59        &mut self.base
60    }
61
62    fn prepare(&mut self, _tls: VMWorkerThread) {
63        unreachable!()
64    }
65
66    fn release(&mut self, _tls: VMWorkerThread) {
67        unreachable!()
68    }
69
70    fn end_of_pause(&mut self, _mmtk: &'static MMTK<VM>, _tls: VMWorkerThread) {
71        unreachable!()
72    }
73
74    fn get_allocator_mapping(&self) -> &'static EnumMap<AllocationSemantics, AllocatorSelector> {
75        &ALLOCATOR_MAPPING
76    }
77
78    fn schedule_collection(&'static self, _scheduler: &GCWorkScheduler<VM>) {
79        unreachable!("GC triggered in nogc")
80    }
81
82    fn current_gc_may_move_object(&self) -> bool {
83        false
84    }
85
86    fn get_used_pages(&self) -> usize {
87        self.nogc_space.reserved_pages()
88            + self.immortal.reserved_pages()
89            + self.los.reserved_pages()
90            + self.base.get_used_pages()
91    }
92}
93
94impl<VM: VMBinding> NoGC<VM> {
95    pub fn new(args: CreateGeneralPlanArgs<VM>) -> Self {
96        let mut plan_args = CreateSpecificPlanArgs {
97            global_args: args,
98            constraints: &NOGC_CONSTRAINTS,
99            global_side_metadata_specs: SideMetadataContext::new_global_specs(&[]),
100        };
101
102        NoGC {
103            nogc_space: NoGCImmortalSpace::new(plan_args.get_normal_space_args(
104                "nogc_space",
105                cfg!(not(feature = "nogc_no_zeroing")),
106                false,
107                VMRequest::discontiguous(),
108            )),
109            immortal: ImmortalSpace::new(plan_args.get_normal_space_args(
110                "immortal",
111                true,
112                false,
113                VMRequest::discontiguous(),
114            )),
115            los: ImmortalSpace::new(plan_args.get_normal_space_args(
116                "los",
117                true,
118                false,
119                VMRequest::discontiguous(),
120            )),
121            base: BasePlan::new(plan_args),
122        }
123    }
124}