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