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 mutator.reset_nonmoving_allocator();
45
46 if current_pause == Pause::Full || current_pause == Pause::FinalMark {
48 debug!("Deactivate SATB barrier active for {:?}", mutator as *mut _);
49 mutator
50 .barrier
51 .downcast_mut::<BarrierType<VM>>()
52 .unwrap()
53 .set_weak_ref_barrier_enabled(false);
54 }
55}
56
57pub fn concurent_immix_mutator_prepare<VM: VMBinding>(
58 mutator: &mut Mutator<VM>,
59 _tls: VMWorkerThread,
60) {
61 let current_pause = mutator.plan.concurrent().unwrap().current_pause().unwrap();
63 debug_assert_ne!(current_pause, Pause::FinalMark);
64
65 let immix_allocator = unsafe {
66 mutator
67 .allocators
68 .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
69 }
70 .downcast_mut::<ImmixAllocator<VM>>()
71 .unwrap();
72 immix_allocator.reset();
73
74 mutator.reset_nonmoving_allocator();
77
78 if current_pause == Pause::InitialMark {
80 debug!("Activate SATB barrier active for {:?}", mutator as *mut _);
81 mutator
82 .barrier
83 .downcast_mut::<BarrierType<VM>>()
84 .unwrap()
85 .set_weak_ref_barrier_enabled(true);
86 }
87}
88
89pub(in crate::plan) const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
90 n_immix: 1,
91 ..ReservedAllocators::DEFAULT
92};
93
94lazy_static! {
95 pub static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
96 let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
97 map[AllocationSemantics::Default] = AllocatorSelector::Immix(0);
98 map
99 };
100}
101
102pub fn create_concurrent_immix_mutator<VM: VMBinding>(
103 mutator_tls: VMMutatorThread,
104 mmtk: &'static MMTK<VM>,
105) -> Mutator<VM> {
106 let immix = mmtk
107 .get_plan()
108 .downcast_ref::<ConcurrentImmix<VM>>()
109 .unwrap();
110 let config = MutatorConfig {
111 allocator_mapping: &ALLOCATOR_MAPPING,
112 space_mapping: Box::new({
113 let mut vec = create_space_mapping(RESERVED_ALLOCATORS, true, immix);
114 vec.push((AllocatorSelector::Immix(0), &immix.immix_space));
115 vec
116 }),
117
118 prepare_func: &concurent_immix_mutator_prepare,
119 release_func: &concurrent_immix_mutator_release,
120 };
121
122 let builder = MutatorBuilder::new(mutator_tls, mmtk, config);
123 let mut mutator = builder
124 .barrier(Box::new(SATBBarrier::new(BarrierSemanticsType::<VM>::new(
125 mmtk,
126 mutator_tls,
127 ))))
128 .build();
129
130 mutator
132 .barrier
133 .downcast_mut::<BarrierType<VM>>()
134 .unwrap()
135 .set_weak_ref_barrier_enabled(immix.is_concurrent_marking_active());
136
137 mutator
138}