mmtk/plan/lxr/gc_work/
mod.rs1use super::global::LXR;
2#[cfg(feature = "non_moving_root")]
3use super::{MATURE_EVACUATION, NURSERY_EVACUATION};
4use crate::plan::tracing::UnsupportedTrace;
5use crate::plan::VectorObjectQueue;
6use crate::scheduler::gc_work::RootKind;
7use crate::scheduler::{GCWorker, WorkBucketStage};
8#[cfg(feature = "non_moving_root")]
9use crate::util::ObjectReference;
10use crate::vm::{RootsWorkFactory, VMBinding};
11use crate::{Plan, MMTK};
12use std::marker::PhantomData;
13
14pub mod mature_evac;
15pub mod mature_sweeping;
16pub mod nursery_sweeping;
17pub mod prepare;
18pub mod rc;
19pub mod tracing;
20
21#[cfg(feature = "non_moving_root")]
22use rc::CollectNodeRoots;
23use rc::CollectSlotRoots;
24
25pub struct ProcessEdgesBase<VM: VMBinding> {
31 pub slots: Vec<VM::VMSlot>,
32 pub nodes: VectorObjectQueue,
33 mmtk: &'static MMTK<VM>,
34 worker: *mut GCWorker<VM>,
37 pub roots: bool,
38 pub root_kind: Option<RootKind>,
39 pub bucket: WorkBucketStage,
40}
41
42unsafe impl<VM: VMBinding> Send for ProcessEdgesBase<VM> {}
43
44impl<VM: VMBinding> ProcessEdgesBase<VM> {
45 pub fn new(
46 slots: Vec<VM::VMSlot>,
47 roots: bool,
48 mmtk: &'static MMTK<VM>,
49 bucket: WorkBucketStage,
50 ) -> Self {
51 #[cfg(feature = "extreme_assertions")]
52 if crate::util::slot_logger::should_check_duplicate_slots(mmtk.get_plan()) {
53 for slot in &slots {
54 mmtk.slot_logger.log_slot(*slot);
56 }
57 }
58 Self {
59 slots,
60 nodes: VectorObjectQueue::new(),
61 mmtk,
62 worker: std::ptr::null_mut(),
63 roots,
64 root_kind: if roots { Some(RootKind::Strong) } else { None },
65 bucket,
66 }
67 }
68
69 pub fn set_worker(&mut self, worker: &mut GCWorker<VM>) {
70 self.worker = worker;
71 }
72
73 pub fn worker(&self) -> &'static mut GCWorker<VM> {
74 unsafe { &mut *self.worker }
75 }
76
77 pub fn mmtk(&self) -> &'static MMTK<VM> {
78 self.mmtk
79 }
80
81 pub fn plan(&self) -> &'static dyn Plan<VM = VM> {
82 self.mmtk.get_plan()
83 }
84}
85
86pub struct LXRGCWorkContext<VM: VMBinding>(PhantomData<VM>);
92
93impl<VM: VMBinding> crate::scheduler::GCWorkContext for LXRGCWorkContext<VM> {
94 type VM = VM;
95 type PlanType = LXR<VM>;
96 type DefaultTrace = UnsupportedTrace<VM>;
97 type PinningTrace = UnsupportedTrace<VM>;
98
99 fn make_roots_work_factory(
100 mmtk: &'static MMTK<VM>,
101 ) -> impl RootsWorkFactory<<VM as VMBinding>::VMSlot> {
102 LXRRootsWorkFactory::new(mmtk)
103 }
104}
105
106pub struct LXRRootsWorkFactory<VM: VMBinding> {
113 mmtk: &'static MMTK<VM>,
114}
115
116impl<VM: VMBinding> Clone for LXRRootsWorkFactory<VM> {
117 fn clone(&self) -> Self {
118 Self { mmtk: self.mmtk }
119 }
120}
121
122impl<VM: VMBinding> LXRRootsWorkFactory<VM> {
123 fn new(mmtk: &'static MMTK<VM>) -> Self {
124 Self { mmtk }
125 }
126}
127
128impl<VM: VMBinding> RootsWorkFactory<VM::VMSlot> for LXRRootsWorkFactory<VM> {
129 fn create_process_roots_work_with_root_kind(&mut self, slots: Vec<VM::VMSlot>, kind: RootKind) {
130 let stage = WorkBucketStage::RCProcessIncs;
133 let mut w = CollectSlotRoots::new(slots, true, self.mmtk, stage);
134 w.root_kind = Some(kind);
135 crate::memory_manager::add_work_packet(self.mmtk, stage, w);
136 }
137
138 #[cfg(feature = "non_moving_root")]
139 fn create_process_pinning_roots_work(&mut self, nodes: Vec<ObjectReference>) {
140 if nodes.is_empty() {
141 return;
142 }
143 crate::memory_manager::add_work_packet(
144 self.mmtk,
145 WorkBucketStage::RCProcessIncsNonMoving,
146 CollectNodeRoots::<VM>::new(nodes),
147 );
148 }
149
150 #[cfg(feature = "non_moving_root")]
151 fn create_process_tpinning_roots_work(&mut self, nodes: Vec<ObjectReference>) {
152 if NURSERY_EVACUATION || MATURE_EVACUATION {
155 unimplemented!(
156 "LXR does not support transitive pinning roots unless evacuation is compiled out"
157 );
158 }
159 self.create_process_pinning_roots_work(nodes);
160 }
161}