1use super::barrier::LXRFieldBarrierSemantics;
2use super::LXR;
3use crate::plan::barriers::FieldBarrier;
4use crate::plan::mutator_context::create_allocator_mapping;
5use crate::plan::mutator_context::create_space_mapping;
6use crate::plan::mutator_context::Mutator;
7use crate::plan::mutator_context::MutatorConfig;
8use crate::plan::mutator_context::ReservedAllocators;
9use crate::plan::AllocationSemantics;
10use crate::util::alloc::allocators::{AllocatorSelector, Allocators};
11use crate::util::alloc::ImmixAllocator;
12use crate::util::opaque_pointer::{VMMutatorThread, VMWorkerThread};
13use crate::vm::VMBinding;
14use crate::MMTK;
15use enum_map::EnumMap;
16
17pub fn lxr_mutator_prepare<VM: VMBinding>(mutator: &mut Mutator<VM>, _tls: VMWorkerThread) {
18 let immix_allocator = unsafe {
19 mutator
20 .allocators
21 .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
22 }
23 .downcast_mut::<ImmixAllocator<VM>>()
24 .unwrap();
25 immix_allocator.reset();
26}
27
28pub fn lxr_mutator_release<VM: VMBinding>(mutator: &mut Mutator<VM>, _tls: VMWorkerThread) {
29 let immix_allocator = unsafe {
30 mutator
31 .allocators
32 .get_allocator_mut(mutator.config.allocator_mapping[AllocationSemantics::Default])
33 }
34 .downcast_mut::<ImmixAllocator<VM>>()
35 .unwrap();
36 immix_allocator.reset();
37}
38
39const RESERVED_ALLOCATORS: ReservedAllocators = ReservedAllocators {
40 n_immix: 1,
41 ..ReservedAllocators::DEFAULT
42};
43
44lazy_static! {
45 pub static ref ALLOCATOR_MAPPING: EnumMap<AllocationSemantics, AllocatorSelector> = {
46 let mut map = create_allocator_mapping(RESERVED_ALLOCATORS, true);
47 map[AllocationSemantics::Default] = AllocatorSelector::Immix(0);
48 map
49 };
50}
51
52pub fn create_lxr_mutator<VM: VMBinding>(
53 mutator_tls: VMMutatorThread,
54 mmtk: &'static MMTK<VM>,
55) -> Mutator<VM> {
56 let lxr = mmtk.get_plan().downcast_ref::<LXR<VM>>().unwrap();
57 let config = MutatorConfig {
58 allocator_mapping: &ALLOCATOR_MAPPING,
59 space_mapping: Box::new({
60 let mut vec = create_space_mapping(RESERVED_ALLOCATORS, true, mmtk.get_plan());
61 vec.push((AllocatorSelector::Immix(0), &lxr.immix_space));
62 vec
63 }),
64 prepare_func: &lxr_mutator_prepare,
65 release_func: &lxr_mutator_release,
66 };
67
68 Mutator {
69 allocators: Allocators::<VM>::new(mutator_tls, mmtk, &config.space_mapping),
70 barrier: Box::new(FieldBarrier::new(LXRFieldBarrierSemantics::new(
71 mmtk,
72 mutator_tls,
73 ))),
74 mutator_tls,
75 config,
76 plan: mmtk.get_plan(),
77 }
78}