mmtk/plan/generational/
mod.rs

1//! Generational plans
2
3use enum_map::EnumMap;
4
5use crate::plan::barriers::BarrierSelector;
6use crate::plan::mutator_context::create_allocator_mapping;
7use crate::plan::AllocationSemantics;
8use crate::plan::PlanConstraints;
9use crate::policy::copyspace::CopySpace;
10use crate::policy::space::Space;
11use crate::util::alloc::AllocatorSelector;
12use crate::util::metadata::side_metadata::SideMetadataContext;
13use crate::util::metadata::side_metadata::SideMetadataSpec;
14use crate::vm::ObjectModel;
15use crate::vm::VMBinding;
16use crate::Plan;
17
18use super::mutator_context::create_space_mapping;
19use super::mutator_context::ReservedAllocators;
20
21// Generational plans:
22
23pub mod barrier;
24/// Generational copying (GenCopy)
25pub mod copying;
26/// Generational immix (GenImmix)
27pub mod immix;
28
29// Common generational code
30
31pub(super) mod gc_work;
32pub(super) mod global;
33
34/// # Barrier overhead measurement:
35///  - Set `FULL_NURSERY_GC` to `true`.
36/// ## 1. Baseline: No barrier
37///  - Set `ACTIVE_BARRIER` to `BarrierSelector::NoBarrier`.
38/// ## 2. Object barrier
39///  - Set `ACTIVE_BARRIER` to `BarrierSelector::ObjectBarrier`.
40pub const ACTIVE_BARRIER: BarrierSelector = BarrierSelector::ObjectBarrier;
41/// Full heap collection as nursery GC.
42pub const FULL_NURSERY_GC: bool = false;
43
44/// Constraints for generational plans. Each generational plan should overwrite based on this constant.
45pub const GEN_CONSTRAINTS: PlanConstraints = PlanConstraints {
46    moves_objects: true,
47    needs_log_bit: ACTIVE_BARRIER.equals(BarrierSelector::ObjectBarrier),
48    generational: true,
49    barrier: ACTIVE_BARRIER,
50    // We may trace duplicate edges in sticky immix (or any plan that uses object remembering barrier). See https://github.com/mmtk/mmtk-core/issues/743.
51    may_trace_duplicate_edges: ACTIVE_BARRIER.equals(BarrierSelector::ObjectBarrier),
52    max_non_los_default_alloc_bytes:
53        crate::plan::plan_constraints::MAX_NON_LOS_ALLOC_BYTES_COPYING_PLAN,
54    ..PlanConstraints::default()
55};
56
57/// Create global side metadata specs for generational plans. This will call SideMetadataContext::new_global_specs().
58/// So if a plan calls this, it should not call SideMetadataContext::new_global_specs() again.
59pub fn new_generational_global_metadata_specs<VM: VMBinding>() -> Vec<SideMetadataSpec> {
60    let specs = if ACTIVE_BARRIER == BarrierSelector::ObjectBarrier {
61        crate::util::metadata::extract_side_metadata(&[*VM::VMObjectModel::GLOBAL_LOG_BIT_SPEC])
62    } else {
63        vec![]
64    };
65    SideMetadataContext::new_global_specs(&specs)
66}
67
68const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
69    n_bump_pointer: 1,
70    ..ReservedAllocators::DEFAULT
71};
72
73lazy_static! {
74    static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
75        let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
76        map[AllocationSemantics::Default] = AllocatorSelector::BumpPointer(0);
77        map
78    };
79}
80
81fn create_gen_space_mapping<VM: VMBinding>(
82    plan: &'static dyn Plan<VM = VM>,
83    nursery: &'static CopySpace<VM>,
84) -> Vec<(AllocatorSelector, &'static dyn Space<VM>)> {
85    let mut vec = create_space_mapping(RESERVED_ALLOCATORS, true, plan);
86    vec.push((AllocatorSelector::BumpPointer(0), nursery));
87    vec
88}