mmtk/vm/
active_plan.rs

1use crate::plan::Mutator;
2use crate::scheduler::GCWorker;
3use crate::util::opaque_pointer::*;
4use crate::util::ObjectReference;
5use crate::vm::VMBinding;
6use crate::ObjectQueue;
7
8/// VM-specific methods for the current plan.
9pub trait ActivePlan<VM: VMBinding> {
10    /// Return whether there is a mutator created and associated with the thread.
11    ///
12    /// Arguments:
13    /// * `tls`: The thread to query.
14    ///
15    /// # Safety
16    /// The caller needs to make sure that the thread is valid (a value passed in by the VM binding through API).
17    fn is_mutator(tls: VMThread) -> bool;
18
19    /// Return a `Mutator` reference for the thread.
20    ///
21    /// Arguments:
22    /// * `tls`: The thread to query.
23    ///
24    /// # Safety
25    /// The caller needs to make sure that the thread is a mutator thread.
26    fn mutator(tls: VMMutatorThread) -> &'static mut Mutator<VM>;
27
28    /// Return an iterator that includes all the mutators at the point of invocation.
29    /// MMTk may call this method multiple times during a pause, and expect the set of mutators to be the same across all calls in a pause.
30    /// It is an undefined behavior if the set of mutators returned by this method changes during a pause.
31    fn mutators<'a>() -> Box<dyn Iterator<Item = &'a mut Mutator<VM>> + 'a>;
32
33    /// Return the total count of mutators.
34    /// MMTk may call this method multiple times during a pause, and expect the count to be the same across all calls in a pause. See also [`ActivePlan::mutators`].
35    fn number_of_mutators() -> usize;
36
37    /// The fallback for object tracing. MMTk generally expects to find an object in one of MMTk's spaces (if it is allocated by MMTK),
38    /// and apply the corresponding policy to trace the object. Tracing in MMTk means identifying whether we have encountered this object in the
39    /// current GC. For example, for mark sweep, we will check if an object is marked, and if it is not yet marked, mark and enqueue the object
40    /// for later scanning. For copying policies, copying also happens in this step. For example for MMTk's copying space, we will
41    /// copy an object if it is in 'from space', and enqueue the copied object for later scanning.
42    ///
43    /// If a binding would like to trace objects that are not allocated by MMTk and are not in any MMTk space, they can override this method.
44    /// They should check whether the object is encountered before in this current GC. If not, they should record the object as encountered themselves,
45    /// and enqueue the object reference to the object queue provided by the argument. If a binding moves objects, they should do the copying in the method,
46    /// and enqueue the new object reference instead.
47    ///
48    /// The method should return the new object reference if the method moves the object, otherwise return the original object reference.
49    ///
50    /// Note: **This is an experimental feature**, and may not interact well with other parts of MMTk.  Use with caution.
51    ///
52    /// Arguments:
53    /// * `queue`: The object queue. If an object is encountered for the first time in this GC, we expect the implementation to call `queue.enqueue()`
54    ///   for the object. If the object is moved during the tracing, the new object reference (after copying) should be enqueued instead.
55    /// * `object`: The object to trace.
56    /// * `worker`: The GC worker that is doing this tracing. This is used to copy object (see [`crate::vm::ObjectModel::copy`])
57    fn vm_trace_object<Q: ObjectQueue>(
58        _queue: &mut Q,
59        object: ObjectReference,
60        _worker: &mut GCWorker<VM>,
61    ) -> ObjectReference {
62        panic!("MMTk cannot trace object {:?} as it does not belong to any MMTk space. If the object is known to the VM, the binding can override this method and handle its tracing.", object)
63    }
64}