mmtk/plan/lxr/gc_work/
prepare.rs

1use 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    /// Clear object mark table
26    #[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
52/// A work packet to prepare each block for GC.
53/// Performs the action on a range of chunks.
54pub struct PrepareChunksForFullGC {
55    pub chunks: Range<Chunk>,
56}
57
58impl PrepareChunksForFullGC {
59    /// Clear object mark table
60    #[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            // Iterate over all blocks in this chunk
82            for block in chunk.iter_region::<Block>() {
83                let state = block.get_state();
84                // Skip unallocated blocks.
85                if state == BlockState::Unallocated {
86                    continue;
87                }
88                // Clear defrag state
89                assert!(!block.is_defrag_source());
90                // Clear block mark data.
91                if block.get_state() != BlockState::Nursery {
92                    block.set_state(BlockState::Unmarked);
93                }
94                debug_assert!(!block.get_state().is_reusable());
95                // debug_assert_ne!(block.get_state(), BlockState::Marked);
96                // debug_assert_ne!(block.get_state(), BlockState::Nursery);
97            }
98        }
99    }
100}