pub struct ReferenceProcessor {
    sync: Mutex<ReferenceProcessorSync>,
    semantics: Semantics,
    allow_new_candidate: AtomicBool,
}
Expand description

We create a reference processor for each semantics. Generally we expect these to happen for each processor:

  1. The VM adds reference candidates. They could either do it when a weak reference is created, or when a weak reference is traced during GC.
  2. We scan references after the GC determins liveness.
  3. We forward references if the GC needs forwarding after liveness.
  4. We inform the binding of references whose referents are cleared during this GC by enqueue’ing.

Fields§

§sync: Mutex<ReferenceProcessorSync>

Most of the reference processor is protected by a mutex.

§semantics: Semantics

The semantics for the reference processor

§allow_new_candidate: AtomicBool

Is it allowed to add candidate to this reference processor? The value is true for most of the time, but it is set to false once we finish forwarding references, at which point we do not expect to encounter any ‘new’ reference in the same GC. This makes sure that no new entry will be added to our reference table once we finish forwarding, as we will not be able to process the entry in that GC.

Implementations§

source§

impl ReferenceProcessor

source

pub fn new(semantics: Semantics) -> Self

source

pub fn add_candidate(&self, reff: ObjectReference)

Add a candidate.

source

fn disallow_new_candidate(&self)

source

fn allow_new_candidate(&self)

source

fn get_forwarded_referent(referent: ObjectReference) -> ObjectReference

Return the new ObjectReference of a referent if it is already moved, or its current ObjectReference otherwise. The referent must be live when calling this function.

source

fn get_forwarded_reference(object: ObjectReference) -> ObjectReference

Return the new ObjectReference of a reference object if it is already moved, or its current ObjectReference otherwise. The reference object must be live when calling this function.

source

fn keep_referent_alive<E: ProcessEdgesWork>( e: &mut E, referent: ObjectReference ) -> ObjectReference

This function is called when retaining soft reference. It

  • keeps the referent alive, and
  • adds the referent to the tracing queue if not yet reached, so that its children will be kept alive, too, and
  • gets the new object reference of the referent if it is moved.
source

fn trace_forward_object<E: ProcessEdgesWork>( e: &mut E, referent: ObjectReference ) -> ObjectReference

This function is called when forwarding the references and referents (for MarkCompact). It

  • adds the reference or the referent to the tracing queue if not yet reached, so that the children of the reference or referent will be visited and forwarded, too, and
  • gets the forwarded object reference of the object.
source

pub fn enqueue<VM: VMBinding>(&self, tls: VMWorkerThread)

Inform the binding to enqueue the weak references whose referents were cleared in this GC.

source

pub fn forward<E: ProcessEdgesWork>(&self, trace: &mut E, _nursery: bool)

Forward the reference tables in the reference processor. This is only needed if a plan does not forward objects in their first transitive closure. nursery is not used for this.

source

fn scan<VM: VMBinding>(&self, _nursery: bool)

Scan the reference table, and update each reference/referent. It doesn’t keep the reference or the referent alive.

source

fn retain<E: ProcessEdgesWork>(&self, trace: &mut E, _nursery: bool)

Retain referent in the reference table. This method deals only with soft references. It retains the referent if the reference is definitely reachable. This method does not update reference or referent. So after this method, scan() should be used to update the references/referents.

source

fn process_reference<VM: VMBinding>( &self, reference: ObjectReference, enqueued_references: &mut Vec<ObjectReference> ) -> Option<ObjectReference>

Process a reference.

  • If both the reference and the referent is alive, return the updated reference and update its referent properly.
  • If the reference is alive, and the referent is not cleared but not alive, return None and the reference (with cleared referent) is enqueued.
  • For other cases, return None.

If a None value is returned, the reference can be removed from the reference table. Otherwise, the updated reference should be kept in the reference table.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.