mmtk/plan/concurrent/immix/
mutator.rs

1use crate::plan::barriers::SATBBarrier;
2use crate::plan::concurrent::barrier::SATBBarrierSemantics;
3use crate::plan::concurrent::immix::ConcurrentImmix;
4use crate::plan::concurrent::Pause;
5use crate::plan::mutator_context::create_allocator_mapping;
6use crate::plan::mutator_context::create_space_mapping;
7
8use crate::plan::mutator_context::Mutator;
9use crate::plan::mutator_context::MutatorBuilder;
10use crate::plan::mutator_context::MutatorConfig;
11use crate::plan::mutator_context::ReservedAllocators;
12use crate::plan::AllocationSemantics;
13use crate::util::alloc::allocators::AllocatorSelector;
14use crate::util::alloc::ImmixAllocator;
15use crate::util::opaque_pointer::{VMMutatorThread, VMWorkerThread};
16use crate::vm::VMBinding;
17use crate::MMTK;
18use enum_map::EnumMap;
19
20type BarrierSemanticsType<VM> =
21    SATBBarrierSemantics<VM, ConcurrentImmix<VM>, { crate::policy::immix::TRACE_KIND_FAST }>;
22
23type BarrierType<VM> = SATBBarrier<BarrierSemanticsType<VM>>;
24
25pub fn concurrent_immix_mutator_release<VM: VMBinding>(
26    mutator: &mut Mutator<VM>,
27    _tls: VMWorkerThread,
28) {
29    // Release is not scheduled for initial mark pause
30    let current_pause = mutator.plan.concurrent().unwrap().current_pause().unwrap();
31    debug_assert_ne!(current_pause, Pause::InitialMark);
32
33    let immix_allocator = unsafe {
34        mutator
35            .allocators
36            .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
37    }
38    .downcast_mut::<ImmixAllocator<VM>>()
39    .unwrap();
40    immix_allocator.reset();
41
42    // Deactivate SATB
43    if current_pause == Pause::Full || current_pause == Pause::FinalMark {
44        debug!("Deactivate SATB barrier active for {:?}", mutator as *mut _);
45        mutator
46            .barrier
47            .downcast_mut::<BarrierType<VM>>()
48            .unwrap()
49            .set_weak_ref_barrier_enabled(false);
50    }
51}
52
53pub fn concurent_immix_mutator_prepare<VM: VMBinding>(
54    mutator: &mut Mutator<VM>,
55    _tls: VMWorkerThread,
56) {
57    // Prepare is not scheduled for final mark pause
58    let current_pause = mutator.plan.concurrent().unwrap().current_pause().unwrap();
59    debug_assert_ne!(current_pause, Pause::FinalMark);
60
61    let immix_allocator = unsafe {
62        mutator
63            .allocators
64            .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
65    }
66    .downcast_mut::<ImmixAllocator<VM>>()
67    .unwrap();
68    immix_allocator.reset();
69
70    // Activate SATB
71    if current_pause == Pause::InitialMark {
72        debug!("Activate SATB barrier active for {:?}", mutator as *mut _);
73        mutator
74            .barrier
75            .downcast_mut::<BarrierType<VM>>()
76            .unwrap()
77            .set_weak_ref_barrier_enabled(true);
78    }
79}
80
81pub(in crate::plan) const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
82    n_immix: 1,
83    ..ReservedAllocators::DEFAULT
84};
85
86lazy_static! {
87    pub static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
88        let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
89        map[AllocationSemantics::Default] = AllocatorSelector::Immix(0);
90        map
91    };
92}
93
94pub fn create_concurrent_immix_mutator<VM: VMBinding>(
95    mutator_tls: VMMutatorThread,
96    mmtk: &'static MMTK<VM>,
97) -> Mutator<VM> {
98    let immix = mmtk
99        .get_plan()
100        .downcast_ref::<ConcurrentImmix<VM>>()
101        .unwrap();
102    let config = MutatorConfig {
103        allocator_mapping: &ALLOCATOR_MAPPING,
104        space_mapping: Box::new({
105            let mut vec = create_space_mapping(RESERVED_ALLOCATORS, true, immix);
106            vec.push((AllocatorSelector::Immix(0), &immix.immix_space));
107            vec
108        }),
109
110        prepare_func: &concurent_immix_mutator_prepare,
111        release_func: &concurrent_immix_mutator_release,
112    };
113
114    let builder = MutatorBuilder::new(mutator_tls, mmtk, config);
115    let mut mutator = builder
116        .barrier(Box::new(SATBBarrier::new(BarrierSemanticsType::<VM>::new(
117            mmtk,
118            mutator_tls,
119        ))))
120        .build();
121
122    // Set barrier active, based on whether concurrent marking is in progress
123    mutator
124        .barrier
125        .downcast_mut::<BarrierType<VM>>()
126        .unwrap()
127        .set_weak_ref_barrier_enabled(immix.is_concurrent_marking_active());
128
129    mutator
130}