Struct mmtk::util::address::ObjectReference
source · #[repr(transparent)]pub struct ObjectReference(NonZeroUsize);
Expand description
ObjectReference
represents address for an object. Compared with Address
, operations allowed
on ObjectReference
are very limited. No address arithmetics are allowed for ObjectReference
.
The idea is from the paper Demystifying Magic: High-level Low-level Programming (VEE09)
and JikesRVM.
In MMTk, ObjectReference
holds a non-zero address, i.e. its raw address. It must satisfy
the following requirements.
- It uniquely references an MMTk object.
- The address must be within the address range of the object it refers to.
- The address must be word-aligned.
- It must be efficient to access object metadata from an
ObjectReference
.
Each ObjectReference
uniquely identifies exactly one MMTk object. There is no “null
reference” (see below for details).
Conversely, each object has a unique (raw) address used for ObjectReference
. That address is
nominated by the VM binding right after an object is allocated in the MMTk heap (i.e. the
argument of crate::memory_manager::post_alloc
). The same address is used by all
ObjectReference
instances that refer to that object until the object is moved, at which time
the VM binding shall choose another address to use as the ObjectReference
of the new copy (in
crate::vm::ObjectModel::copy
or crate::vm::ObjectModel::get_reference_when_copied_to
)
until the object is moved again.
In addition to the raw address, there are also two addresses related to each object allocated in
MMTk heap, namely starting address and header address. See the
crate::vm::ObjectModel
trait for their precise definition.
The VM binding may, in theory, pick any aligned address within the object, and it doesn’t have
to be the starting address. However, during tracing, MMTk will need to access object metadata
from a ObjectReference
. Particularly, it needs to identify reference fields, and query
information about the object, such as object size. Such information is usually accessed from
object headers. The choice of ObjectReference
must make such accesses efficient.
Because the raw address is within the object, MMTk will also use the raw address to identify the space or region (chunk, block, line, etc.) that contains the object, and to access side metadata and the SFTMap. If a VM binding needs to access side metadata directly (particularly, setting the “valid-object (VO) bit” in allocation fast paths), it shall use the raw address to compute the byte and bit address of the metadata bits.
§Notes
§About VMs own concepts of “object references”
A runtime may define its own concept of “object references” differently from MMTk’s
ObjectReference
type. It may define its object reference as
- the starting address of an object,
- an address inside an object,
- an address at a certain offset outside an object,
- a handle that points to an indirection table entry where a pointer to the object is held, or
- anything else that refers to an object.
Regardless, when passing an ObjectReference
value to MMTk through the API, MMTk expectes its
value to satisfy MMTk’s definition. This means MMTk’s ObjectReference
may not be the value
held in an object field. Some VM bindings may need to do conversions when passing object
references to MMTk. For example, adding an offset to the VM-level object reference so that the
resulting address is within the object. When using handles, the VM binding may use the pointer
stored in the entry of the indirection table instead of the pointer to the entry itself as
MMTk-level ObjectReference
.
§About null references
An ObjectReference
always refers to an object. Some VMs have special values (such as null
in Java) that do not refer to any object. Those values cannot be represented by
ObjectReference
. When scanning roots and object fields, the VM binding should ignore slots
that do not hold a reference to an object. Specifically, crate::vm::slot::Slot::load
returns Option<ObjectReference>
. It can return None
so that MMTk skips that slot.
Option<ObjectReference>
should be used for the cases where a non-null object reference may or
may not exist, That includes several API functions, including crate::vm::slot::Slot::load
.
ObjectReference
is backed by NonZeroUsize
which cannot be zero, and it has the
#[repr(transparent)]
attribute. Thanks to null pointer optimization (NPO),
Option<ObjectReference>
has the same size as NonZeroUsize
and usize
.
For the convenience of passing Option<ObjectReference>
to and from native (C/C++) programs,
mmtk-core provides crate::util::api_util::NullableObjectReference
.
§About the VMSpace
The VMSpace
is managed by the VM binding. The VM binding declare ranges of memory as part of
the VMSpace
, but MMTk never allocates into it. The VM binding allocates objects into the
VMSpace
(usually by mapping boot-images), and refers to objects in the VMSpace
using
ObjectReference
s whose raw addresses point inside those objects (and must be word-aligned,
too). MMTk will access metadata using methods of ObjectModel
like other objects. MMTk also
has side metadata available for objects in the VMSpace
.
§About ObjectReference
pointing outside MMTk spaces
If a VM binding implements crate::vm::ActivePlan::vm_trace_object
, ObjectReference
is
allowed to point to locations outside any MMTk spaces. When tracing objects, such
ObjectReference
values will be processed by ActivePlan::vm_trace_object
so that the VM
binding can trace its own allocated objects during GC. However, this is an experimental
feature, and may not interact well with other parts of MMTk. Notably, MMTk will not allocate
side metadata for such ObjectReference
, and attempts to access side metadata with a non-MMTk
ObjectReference
will result in crash. Use with caution.
Tuple Fields§
§0: NonZeroUsize
Implementations§
source§impl ObjectReference
impl ObjectReference
sourcepub const ALIGNMENT: usize = 8usize
pub const ALIGNMENT: usize = 8usize
The required minimal alignment for object reference. If the object reference’s raw address is not aligned to this value, you will see an assertion failure in the debug build when constructing an object reference instance.
sourcepub fn to_raw_address(self) -> Address
pub fn to_raw_address(self) -> Address
Cast the object reference to its raw address.
sourcepub fn from_raw_address(addr: Address) -> Option<ObjectReference>
pub fn from_raw_address(addr: Address) -> Option<ObjectReference>
Cast a raw address to an object reference.
If addr
is 0, the result is None
.
sourcepub unsafe fn from_raw_address_unchecked(addr: Address) -> ObjectReference
pub unsafe fn from_raw_address_unchecked(addr: Address) -> ObjectReference
Like from_raw_address
, but assume addr
is not zero. This can be used to elide a check
against zero for performance-critical code.
§Safety
This method assumes addr
is not zero. It should only be used in cases where we know at
compile time that the input cannot be zero. For example, if we compute the address by
adding a positive offset to a non-zero address, we know the result must not be zero.
sourcepub fn to_header<VM: VMBinding>(self) -> Address
pub fn to_header<VM: VMBinding>(self) -> Address
Get the header base address from an object reference. This method is used by MMTk to get a base address for the
object header, and access the object header. This method is syntactic sugar for crate::vm::ObjectModel::ref_to_header
.
See the comments on crate::vm::ObjectModel::ref_to_header
.
sourcepub fn to_object_start<VM: VMBinding>(self) -> Address
pub fn to_object_start<VM: VMBinding>(self) -> Address
Get the start of the allocation address for the object. This method is used by MMTk to get the start of the allocation
address originally returned from crate::memory_manager::alloc
for the object.
This method is syntactic sugar for crate::vm::ObjectModel::ref_to_object_start
. See comments on crate::vm::ObjectModel::ref_to_object_start
.
sourcepub fn is_reachable(self) -> bool
pub fn is_reachable(self) -> bool
Is the object reachable, determined by the policy?
Note: Objects in ImmortalSpace may have is_live = true
but are actually unreachable.
sourcepub fn is_movable(self) -> bool
pub fn is_movable(self) -> bool
Can the object be moved?
sourcepub fn get_forwarded_object(self) -> Option<Self>
pub fn get_forwarded_object(self) -> Option<Self>
Get forwarding pointer if the object is forwarded.
sourcepub fn is_in_any_space(self) -> bool
pub fn is_in_any_space(self) -> bool
Is the object in any MMTk spaces?
Trait Implementations§
source§impl Clone for ObjectReference
impl Clone for ObjectReference
source§fn clone(&self) -> ObjectReference
fn clone(&self) -> ObjectReference
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for ObjectReference
impl Debug for ObjectReference
allows Debug format the Address (as upper-case hex value with 0x prefix)
source§impl Display for ObjectReference
impl Display for ObjectReference
allows Display format the Address (as upper-case hex value with 0x prefix)
source§impl Finalizable for ObjectReference
impl Finalizable for ObjectReference
This provides an implementation of Finalizable
for ObjectReference
. Most bindings
should be able to use ObjectReference
as ReferenceGlue::FinalizableType
.
source§fn get_reference(&self) -> ObjectReference
fn get_reference(&self) -> ObjectReference
source§fn set_reference(&mut self, object: ObjectReference)
fn set_reference(&mut self, object: ObjectReference)
source§fn keep_alive<E: ProcessEdgesWork>(&mut self, trace: &mut E)
fn keep_alive<E: ProcessEdgesWork>(&mut self, trace: &mut E)
source§impl Hash for ObjectReference
impl Hash for ObjectReference
source§impl LowerHex for ObjectReference
impl LowerHex for ObjectReference
allows print Address as lower-case hex value
source§impl Ord for ObjectReference
impl Ord for ObjectReference
source§fn cmp(&self, other: &ObjectReference) -> Ordering
fn cmp(&self, other: &ObjectReference) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
source§impl PartialEq for ObjectReference
impl PartialEq for ObjectReference
source§fn eq(&self, other: &ObjectReference) -> bool
fn eq(&self, other: &ObjectReference) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl PartialOrd for ObjectReference
impl PartialOrd for ObjectReference
source§fn partial_cmp(&self, other: &ObjectReference) -> Option<Ordering>
fn partial_cmp(&self, other: &ObjectReference) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl UpperHex for ObjectReference
impl UpperHex for ObjectReference
allows print Address as upper-case hex value
impl Copy for ObjectReference
impl Eq for ObjectReference
impl NoUninit for ObjectReference
impl StructuralPartialEq for ObjectReference
Auto Trait Implementations§
impl RefUnwindSafe for ObjectReference
impl Send for ObjectReference
impl Sync for ObjectReference
impl Unpin for ObjectReference
impl UnwindSafe for ObjectReference
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
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>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
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)
fn as_any(&self) -> &(dyn Any + 'static)
&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)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&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
impl<T> DowncastSync for T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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