mmtk/plan/marksweep/
mutator.rs1use crate::plan::marksweep::MarkSweep;
2use crate::plan::mutator_context::create_allocator_mapping;
3use crate::plan::mutator_context::Mutator;
4use crate::plan::mutator_context::MutatorBuilder;
5use crate::plan::mutator_context::MutatorConfig;
6use crate::plan::mutator_context::ReservedAllocators;
7use crate::plan::mutator_context::SpaceMapping;
8use crate::plan::AllocationSemantics;
9use crate::plan::Plan;
10use crate::util::alloc::allocators::AllocatorSelector;
11use crate::util::{VMMutatorThread, VMWorkerThread};
12use crate::vm::VMBinding;
13use crate::MMTK;
14
15use enum_map::EnumMap;
16
17#[cfg(feature = "malloc_mark_sweep")]
18mod malloc_mark_sweep {
19 use crate::plan::mutator_context::{common_prepare_func, common_release_func};
20
21 use super::*;
22
23 pub fn ms_mutator_prepare<VM: VMBinding>(mutator: &mut Mutator<VM>, tls: VMWorkerThread) {
26 common_prepare_func(mutator, tls);
27 }
28 pub fn ms_mutator_release<VM: VMBinding>(mutator: &mut Mutator<VM>, tls: VMWorkerThread) {
29 common_release_func(mutator, tls);
30 }
31
32 pub(crate) const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
35 n_malloc: 1,
36 ..ReservedAllocators::DEFAULT
37 };
38 lazy_static! {
39 pub static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
40 let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
41 map[AllocationSemantics::Default] = AllocatorSelector::Malloc(0);
42 map
43 };
44 }
45 pub(crate) fn create_space_mapping<VM: VMBinding>(
46 plan: &'static dyn Plan<VM = VM>,
47 ) -> Box<SpaceMapping<VM>> {
48 let ms = plan.downcast_ref::<MarkSweep<VM>>().unwrap();
49 Box::new({
50 let mut vec =
51 crate::plan::mutator_context::create_space_mapping(RESERVED_ALLOCATORS, true, plan);
52 vec.push((AllocatorSelector::Malloc(0), ms.ms_space()));
53 vec
54 })
55 }
56}
57
58#[cfg(not(feature = "malloc_mark_sweep"))]
59mod native_mark_sweep {
60 use super::*;
61 use crate::util::alloc::FreeListAllocator;
62
63 fn get_freelist_allocator_mut<VM: VMBinding>(
64 mutator: &mut Mutator<VM>,
65 ) -> &mut FreeListAllocator<VM> {
66 unsafe {
67 mutator
68 .allocators
69 .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
70 }
71 .downcast_mut::<FreeListAllocator<VM>>()
72 .unwrap()
73 }
74
75 #[cfg(not(feature = "malloc_mark_sweep"))]
78 pub fn ms_mutator_prepare<VM: VMBinding>(mutator: &mut Mutator<VM>, tls: VMWorkerThread) {
79 use crate::plan::mutator_context::common_prepare_func;
80
81 get_freelist_allocator_mut::<VM>(mutator).prepare();
82 common_prepare_func(mutator, tls);
83 }
84
85 #[cfg(not(feature = "malloc_mark_sweep"))]
86 pub fn ms_mutator_release<VM: VMBinding>(mutator: &mut Mutator<VM>, tls: VMWorkerThread) {
87 use crate::plan::mutator_context::common_release_func;
88
89 get_freelist_allocator_mut::<VM>(mutator).release();
90
91 common_release_func(mutator, tls);
92 }
93
94 pub(crate) const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
97 n_free_list: 1,
98 ..ReservedAllocators::DEFAULT
99 };
100 lazy_static! {
101 pub static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
102 let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
103 map[AllocationSemantics::Default] = AllocatorSelector::FreeList(0);
104 map
105 };
106 }
107 pub(crate) fn create_space_mapping<VM: VMBinding>(
108 plan: &'static dyn Plan<VM = VM>,
109 ) -> Box<SpaceMapping<VM>> {
110 let ms = plan.downcast_ref::<MarkSweep<VM>>().unwrap();
111 Box::new({
112 let mut vec =
113 crate::plan::mutator_context::create_space_mapping(RESERVED_ALLOCATORS, true, plan);
114 vec.push((AllocatorSelector::FreeList(0), ms.ms_space()));
115 vec
116 })
117 }
118}
119
120#[cfg(feature = "malloc_mark_sweep")]
121pub use malloc_mark_sweep::*;
122
123#[cfg(not(feature = "malloc_mark_sweep"))]
124pub use native_mark_sweep::*;
125
126pub fn create_ms_mutator<VM: VMBinding>(
127 mutator_tls: VMMutatorThread,
128 mmtk: &'static MMTK<VM>,
129) -> Mutator<VM> {
130 let config = MutatorConfig {
131 allocator_mapping: &ALLOCATOR_MAPPING,
132 space_mapping: create_space_mapping(mmtk.get_plan()),
133 prepare_func: &ms_mutator_prepare,
134 release_func: &ms_mutator_release,
135 };
136
137 let builder = MutatorBuilder::new(mutator_tls, mmtk, config);
138 builder.build()
139}