mmtk/vm/
reference_glue.rs

1use crate::util::ObjectReference;
2use crate::util::VMWorkerThread;
3use crate::vm::ObjectTracer;
4use crate::vm::VMBinding;
5
6/// VM-specific methods for reference processing, including weak references, and finalizers.
7/// We handle weak references and finalizers differently:
8/// * for weak references, we assume they are implemented as normal reference objects (also known as weak objects)
9///   with a referent that is actually weakly reachable. This trait provides a few methods to access
10///   the referent of such an reference object.
11/// * for finalizers, we provide a `Finalizable` trait, and require bindings to specify a type
12///   that implements `Finalizable`. When the binding registers or pops a finalizable object
13///   from MMTk, the specified type is used for the finalizable objects. For most languages,
14///   they can just use `ObjectReference` for the finalizable type, meaning that they are registering
15///   and popping a normal object reference as finalizable objects.
16pub trait ReferenceGlue<VM: VMBinding> {
17    /// The type of finalizable objects. This type is used when the binding registers and pops finalizable objects.
18    type FinalizableType: Finalizable;
19
20    // TODO: Should we also move the following methods about weak references to a trait (similar to the `Finalizable` trait)?
21
22    /// Weak and soft references always clear the referent
23    /// before enqueueing.
24    ///
25    /// Arguments:
26    /// * `new_reference`: The reference whose referent is to be cleared.
27    fn clear_referent(new_reference: ObjectReference);
28
29    /// Get the referent from a weak reference object.
30    ///
31    /// Arguments:
32    /// * `object`: Reference to the referent.  `None` if the object currently does not point to a
33    ///   referent.  This may happen if the reference has been cleared.
34    fn get_referent(object: ObjectReference) -> Option<ObjectReference>;
35
36    /// Set the referent in a weak reference object.
37    ///
38    /// Arguments:
39    /// * `reff`: The object reference for the reference.
40    /// * `referent`: The referent object reference.
41    fn set_referent(reff: ObjectReference, referent: ObjectReference);
42
43    /// For weak reference types, if the referent is cleared during GC, the reference
44    /// will be added to a queue, and MMTk will call this method to inform
45    /// the VM about the changes for those references. This method is used
46    /// to implement Java's ReferenceQueue.
47    /// Note that this method is called for each type of weak references during GC, and
48    /// the references slice will be cleared after this call is returned. That means
49    /// MMTk will no longer keep these references alive once this method is returned.
50    fn enqueue_references(references: &[ObjectReference], tls: VMWorkerThread);
51}
52
53/// A finalizable object for MMTk. MMTk needs to know the actual object reference in the type,
54/// while a binding can use this type to store some runtime information about finalizable objects.
55/// For example, for bindings that allows multiple finalizer methods with one object, they can define
56/// the type as a tuple of `(object, finalize method)`, and register different finalizer methods to MMTk
57/// for the same object.
58/// The implementation should mark theird method implementations as inline for performance.
59pub trait Finalizable: std::fmt::Debug + Send {
60    /// Load the object reference.
61    fn get_reference(&self) -> ObjectReference;
62    /// Store the object reference.
63    fn set_reference(&mut self, object: ObjectReference);
64    /// Keep the heap references in the finalizable object alive. For example, the reference itself needs to be traced. However,
65    /// if the finalizable object includes other heap references, the implementation should trace them as well.
66    /// Note that trace_object() may move objects so we need to write the new reference in case that it is moved.
67    fn keep_alive<OT: ObjectTracer>(&mut self, trace: &mut OT);
68}
69
70/// This provides an implementation of `Finalizable` for `ObjectReference`. Most bindings
71/// should be able to use `ObjectReference` as `ReferenceGlue::FinalizableType`.
72impl Finalizable for ObjectReference {
73    fn get_reference(&self) -> ObjectReference {
74        *self
75    }
76    fn set_reference(&mut self, object: ObjectReference) {
77        *self = object;
78    }
79    fn keep_alive<OT: ObjectTracer>(&mut self, trace: &mut OT) {
80        *self = trace.trace_object(*self);
81    }
82}