mmtk/plan/lxr/gc_work/
prepare.rs1use super::super::LXR;
2use crate::policy::immix::block::{Block, BlockState};
3use crate::scheduler::{GCWork, GCWorker};
4use crate::util::heap::chunk_map::Chunk;
5use crate::util::linear_scan::Region;
6use crate::{vm::*, Plan, MMTK};
7use std::ops::Range;
8
9pub struct FastRCPrepare;
10
11impl<VM: VMBinding> GCWork<VM> for FastRCPrepare {
12 fn do_work(&mut self, worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
13 let lxr = unsafe { mmtk.get_plan_mut() }
14 .downcast_mut::<LXR<VM>>()
15 .unwrap();
16 lxr.prepare(worker.tls)
17 }
18}
19
20pub struct ConcurrentChunkMetadataZeroing {
21 pub chunks: Range<Chunk>,
22}
23
24impl ConcurrentChunkMetadataZeroing {
25 #[allow(unused)]
27 fn reset_object_mark<VM: VMBinding>(chunk: Chunk) {
28 VM::VMObjectModel::LOCAL_MARK_BIT_SPEC
29 .extract_side_spec()
30 .bzero_metadata(chunk.start(), Chunk::BYTES);
31 }
32}
33
34impl<VM: VMBinding> GCWork<VM> for ConcurrentChunkMetadataZeroing {
35 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
36 let num_chunks = (self.chunks.end.start() - self.chunks.start.start()) >> Chunk::LOG_BYTES;
37 let ix_space = &mmtk
38 .get_plan()
39 .downcast_ref::<LXR<VM>>()
40 .unwrap()
41 .immix_space;
42 for i in 0..num_chunks {
43 let chunk = self.chunks.start.next_nth(i);
44 if !ix_space.chunk_map.is_allocated(chunk) {
45 continue;
46 }
47 Self::reset_object_mark::<VM>(chunk);
48 }
49 }
50}
51
52pub struct PrepareChunksForFullGC {
55 pub chunks: Range<Chunk>,
56}
57
58impl PrepareChunksForFullGC {
59 #[allow(unused)]
61 fn reset_object_mark<VM: VMBinding>(chunk: Chunk) {
62 VM::VMObjectModel::LOCAL_MARK_BIT_SPEC
63 .extract_side_spec()
64 .bzero_metadata(chunk.start(), Chunk::BYTES);
65 }
66}
67
68impl<VM: VMBinding> GCWork<VM> for PrepareChunksForFullGC {
69 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
70 let num_chunks = (self.chunks.end.start() - self.chunks.start.start()) >> Chunk::LOG_BYTES;
71 let ix_space = &mmtk
72 .get_plan()
73 .downcast_ref::<LXR<VM>>()
74 .unwrap()
75 .immix_space;
76 for i in 0..num_chunks {
77 let chunk = self.chunks.start.next_nth(i);
78 if !ix_space.chunk_map.is_allocated(chunk) {
79 continue;
80 }
81 for block in chunk.iter_region::<Block>() {
83 let state = block.get_state();
84 if state == BlockState::Unallocated {
86 continue;
87 }
88 assert!(!block.is_defrag_source());
90 if block.get_state() != BlockState::Nursery {
92 block.set_state(BlockState::Unmarked);
93 }
94 debug_assert!(!block.get_state().is_reusable());
95 }
98 }
99 }
100}