Trait jrsonnet_gcmodule::Trace
source · pub trait Trace: 'static {
fn trace(&self, tracer: &mut Tracer<'_>) { ... }
fn is_type_tracked() -> bool
where
Self: Sized,
{ ... }
}
Expand description
Defines how the cycle collector should collect a type.
Customized Drop
implementation
The Drop
implementation should avoid dereferencing other [Cc<T>
]
objects. Failing to do so might cause panic or undefined behavior. For
example, T1
has a field Cc<T2>
. The collector might have already
dropped T2
by the time T1::drop
runs.
The Drop
implementation should also be careful about cloning
(resurrecting) [Cc<T>
] objects. If it must do so, the trace
implementation should match by avoiding visiting those cloned objects.
The 'static
bound
Types tracked by the collector can potentially be kept alive forever. Therefore types with non-static references are not allowed.
Provided Methods§
sourcefn trace(&self, tracer: &mut Tracer<'_>)
fn trace(&self, tracer: &mut Tracer<'_>)
Define how to visit values referred by this value.
For example, if self.x
is a value referred by self
,
call self.x.trace(tracer)
to visit it.
The values that are visited must match the Drop::drop
implementation. Otherwise memory leak or panic might
happen. After the panic, dereferencing already collected
Cc<T>
can trigger:
- Undefined behavior on release build.
- Another panic on debug build.
Ideally this can be generated by the compiler, since the
compiler already knows how to generate Drop::drop
.
sourcefn is_type_tracked() -> boolwhere
Self: Sized,
fn is_type_tracked() -> boolwhere
Self: Sized,
Whether this type should be tracked by the collector.
Types that might include Cc<T>
where T
can form a cycle should
be tracked. This allows the collector to visit the Cc
values from
its parents and count references correctly.
If a type T
is tracked, Cc<T>
will be 3 usize
larger and the
collector will check them.
For example,
Vec<u8>
is not tracked. It does include any kind ofCc<T>
.Box<Cc<u8>>
is not tracked. It includesCc<u8>
butu8
cannot create cycles.Box<dyn Trace>
is tracked. The trait object can be anything, including any kinds of types that contains aCc<T>
.
Usually, concrete Rust types can opt-out the cycle collector. There are a few exceptions:
- Trait objects, and types containing trait objects. Trait objects can be anything so they should be tracked.
- Recursive types. Such as,
struct S(RefCell<Option<Rc<Box<S>>>>)
. Those types need an explicit name likeS
, and a manual implementation of theTrace
trait. That implementation should makeis_type_tracked
returntrue
directly.
This is an optimization for performance. When in-doubt, return true
for correctness.