mmtk/plan/lxr/
mutator.rs

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}