pub trait Trace:
'static
+ Send
+ Clone {
type VM: VMBinding;
// Required methods
fn from_mmtk(mmtk: &'static MMTK<Self::VM>) -> Self;
fn trace_object<Q: ObjectQueue>(
&self,
worker: &mut GCWorker<Self::VM>,
object: ObjectReference,
queue: &mut Q,
) -> ObjectReference;
fn post_scan_object(&self, object: ObjectReference);
fn may_move_objects() -> bool;
}Expand description
This trait provides methods used during a trace. The most important method is
Self::trace_object which provides the way to trace an object during the current trace. Many
work packets depend on this trait to trace objects.
We need different implementations of this trait for the different behaviors in
- different plans
- different traces of the same plan (e.g. marking trace and forwarding trace; nursery GC and mature GC; fast GC and defrag GC; etc.), and
- pinning (transitive or not) roots and regular edges.
Therefore, each GC selects one GCWorkContext, and each GCWorkContext selects two
Trace implementations for default edges and pinning edges, respectively.
A type of this trait shall be stateless and immutable. It shall be cheap to instantiate from an
MMTK instance.
This trait requires the Clone trait, and cloned instances behave exactly the same.
Required Associated Types§
Required Methods§
Sourcefn from_mmtk(mmtk: &'static MMTK<Self::VM>) -> Self
fn from_mmtk(mmtk: &'static MMTK<Self::VM>) -> Self
Instantiate from an MMTK instance.
Note that values of this trait are usually instantiated in work packets that use it. It
should be reasonably cheap to instantiate. Most types (such as PlanTrace and
GenNurseryTrace) only need a reference to the plan which can be downcasted from
MMTK::plan.
Sourcefn trace_object<Q: ObjectQueue>(
&self,
worker: &mut GCWorker<Self::VM>,
object: ObjectReference,
queue: &mut Q,
) -> ObjectReference
fn trace_object<Q: ObjectQueue>( &self, worker: &mut GCWorker<Self::VM>, object: ObjectReference, queue: &mut Q, ) -> ObjectReference
Trace the object. More precisely, it visits an object graph edge that points to
object.
It may add object (or the new ObjectReference for object in a moving GC) into the
queue, which means its children needs to be recursively traversed.
In non-moving GC, the return value is always object. In moving GC, the return value may
be object or the new ObjectReference for the object. If the return value is not
object, the slot that represents the object graph edge needs to be updated to hold the
return value instead.
Its implementation generally needs to figure out which space an object resides in, and invoke the right “trace object” method of the space for the current trace.
§Notes
§The enqueued value and the return value
The return value may be different from the enqueued value. For example, during the
forwarding stage of MarkCompact, it returns the new object reference, but enqueues the old
object because the object has not been moved, yet.
§The queue can be a callback instead of a collection
FnMut(ObjectReference) implements the ObjectQueue trait. This means you can use a
lambda expression at the place of the queue argument. For example, you can scan the
object immediately instead of adding the object reference into a container.
Example:
trace.trace_object(worker, object, &mut |enqueued_object| {
// Process the enqueued_object here...
});Sourcefn post_scan_object(&self, object: ObjectReference)
fn post_scan_object(&self, object: ObjectReference)
The post-scan hook to be call after scanning object.
Each object is scanned by Scanning::scan_object or
Scanning::scan_object_and_trace_edges, and this function will be called after scanning
an object as a hook to invoke possible policy-specific post-scan methods. If object is in
a space that needs such a hook, this method should call such hook of the space. Otherwise,
this method may do nothing.
Currently, only ImmixSpace needs this hook to mark the line.
Sourcefn may_move_objects() -> bool
fn may_move_objects() -> bool
Return true if Self::trace_object may move any object. If any space of the current
plan may move objects during this trace, this method should return true.
If it returns false, it means Self::trace_object is guaranteed not to move the
object, and it is safe to elide updating a slot after tracing the reference in the slot.
It is always correct to conservatively return true.
Note that this method is called very frequently, so it must be efficient.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.