mmtk/plan/concurrent/immix/
mutator.rs1use 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 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 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 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 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 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}