Trace

Trait Trace 

Source
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§

Source

type VM: VMBinding

The VM binding type this type serves.

Required Methods§

Source

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.

Source

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...
});
Source

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.

Source

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.

Implementors§

Source§

impl<P: Plan + PlanTraceObject<P::VM>, const KIND: u8> Trace for PlanTrace<P, KIND>

Source§

type VM = <P as HasSpaces>::VM

Source§

impl<VM: VMBinding> Trace for SFTTrace<VM>

Source§

type VM = VM

Source§

impl<VM: VMBinding> Trace for UnsupportedTrace<VM>

Source§

type VM = VM

Source§

impl<VM: VMBinding, P: GenerationalPlanExt<VM> + PlanTraceObject<VM>, const KIND: u8> Trace for GenNurseryTrace<VM, P, KIND>

Source§

type VM = VM