mmtk/plan/lxr/gc_work/
nursery_sweeping.rs1use atomic::Ordering;
2
3use crate::plan::lxr::{LazySweepingJobsCounter, LXR};
4use crate::policy::immix::block::Block;
5use crate::scheduler::WorkBucketStage;
6use crate::scheduler::{GCWork, GCWorker};
7use crate::vm::VMBinding;
8use crate::MMTK;
9
10pub struct RCLazySweepNurseryBlocks {
11 blocks: Vec<Block>,
12 _counter: LazySweepingJobsCounter,
13}
14
15impl RCLazySweepNurseryBlocks {
16 pub fn new(blocks: Vec<Block>) -> Self {
17 Self {
18 blocks,
19 _counter: LazySweepingJobsCounter::new_decs(),
20 }
21 }
22}
23
24impl<VM: VMBinding> GCWork<VM> for RCLazySweepNurseryBlocks {
25 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
26 let lxr = &mmtk.get_plan().downcast_ref::<LXR<VM>>().unwrap();
27 let mut released_blocks = 0;
28 for block in &self.blocks {
29 if block.rc_sweep_nursery(&lxr.immix_space) {
30 released_blocks += 1;
31 }
32 }
33 lxr.num_clean_blocks_released_lazy
34 .fetch_add(released_blocks, Ordering::SeqCst);
35 }
36}
37
38pub struct RCSTWSweepNurseryBlocks {
39 blocks: Vec<Block>,
40 _counter: LazySweepingJobsCounter,
41}
42
43impl RCSTWSweepNurseryBlocks {
44 pub fn new(blocks: Vec<Block>) -> Self {
45 Self {
46 blocks,
47 _counter: LazySweepingJobsCounter::new_decs(),
48 }
49 }
50}
51
52impl<VM: VMBinding> GCWork<VM> for RCSTWSweepNurseryBlocks {
53 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
54 let space = &mmtk
55 .get_plan()
56 .downcast_ref::<LXR<VM>>()
57 .unwrap()
58 .immix_space;
59 for block in &self.blocks {
60 block.rc_sweep_nursery(space);
61 }
62 }
63}
64
65pub struct SweepBlocksAfterDecs {
66 blocks: Vec<(Block, bool)>,
67 _counter: LazySweepingJobsCounter,
68}
69
70impl SweepBlocksAfterDecs {
71 pub fn new(blocks: Vec<(Block, bool)>, counter: LazySweepingJobsCounter) -> Self {
72 Self {
73 blocks,
74 _counter: counter,
75 }
76 }
77}
78
79impl<VM: VMBinding> GCWork<VM> for SweepBlocksAfterDecs {
80 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
81 let lxr = mmtk.get_plan().downcast_ref::<LXR<VM>>().unwrap();
82 if self.blocks.is_empty() {
83 return;
84 }
85 let mut count = 0;
86 for (block, defrag) in &self.blocks {
87 block.unlog();
88 if block.rc_sweep_mature::<VM>(&lxr.immix_space, *defrag) {
89 count += 1;
90 } else {
91 assert!(
92 !*defrag,
93 "defrag block is freed? {:?} {:?} {}",
94 block,
95 block.get_state(),
96 block.is_defrag_source()
97 );
98 }
99 }
100 if count != 0
101 && (lxr.current_pause().is_none()
102 || mmtk.scheduler.work_buckets[WorkBucketStage::STWRCDecsAndSweep].is_open())
103 {
104 lxr.num_clean_blocks_released_lazy
105 .fetch_add(count, Ordering::Relaxed);
106 }
107 }
108}
109
110pub struct ReleaseLOSNursery;
111
112impl<VM: VMBinding> GCWork<VM> for ReleaseLOSNursery {
113 fn do_work(&mut self, _worker: &mut GCWorker<VM>, mmtk: &'static MMTK<VM>) {
114 let lxr = mmtk.get_plan().downcast_ref::<LXR<VM>>().unwrap();
115 lxr.los().release_rc_nursery_objects();
116 }
117}