mmtk/util/
scanning_helper.rs

1//! This module provides some convenient functions for scanning objects.
2
3use crate::{
4    util::{ObjectReference, VMWorkerThread},
5    vm::{slot::Slot, ObjectTracer, Scanning, VMBinding},
6};
7
8/// Visit and potentially update the children of `object` using [`Scanning::scan_object`] or
9/// [`Scanning::scan_object_and_trace_edges`] depending on the result of
10/// [`Scanning::support_slot_enqueuing`].
11///
12/// This function is mainly used as a convenient function for simple node-enqueuing tracing loops.
13pub fn visit_children<VM, const MAY_MOVE_OBJECTS: bool>(
14    tls: VMWorkerThread,
15    object: ObjectReference,
16    object_tracer: &mut impl ObjectTracer,
17) where
18    VM: VMBinding,
19{
20    if VM::VMScanning::support_slot_enqueuing(tls, object) {
21        VM::VMScanning::scan_object(tls, object, &mut |slot: <VM as VMBinding>::VMSlot| {
22            if let Some(child) = slot.load() {
23                let new_child = object_tracer.trace_object(child);
24                if MAY_MOVE_OBJECTS {
25                    if new_child != child {
26                        slot.store(new_child);
27                    }
28                } else {
29                    debug_assert_eq!(new_child, child);
30                }
31            }
32        });
33    } else {
34        VM::VMScanning::scan_object_and_trace_edges(tls, object, &mut |child| {
35            let new_child = object_tracer.trace_object(object);
36            if !MAY_MOVE_OBJECTS {
37                debug_assert_eq!(new_child, child);
38            }
39            new_child
40        });
41    }
42}
43
44/// Convenient wrapper of non-moving [`visit_children`].
45pub fn visit_children_non_moving<VM>(
46    tls: VMWorkerThread,
47    object: ObjectReference,
48    object_tracer: &mut impl ObjectTracer,
49) where
50    VM: VMBinding,
51{
52    visit_children::<VM, false>(tls, object, object_tracer)
53}
54
55/// Convenient wrapper of moving [`visit_children`].
56pub fn visit_children_moving<VM>(
57    tls: VMWorkerThread,
58    object: ObjectReference,
59    object_tracer: &mut impl ObjectTracer,
60) where
61    VM: VMBinding,
62{
63    visit_children::<VM, true>(tls, object, object_tracer)
64}