@@ -212,6 +212,11 @@ impl Address {
212
212
Address ( self . 0 - size)
213
213
}
214
214
215
+ /// Apply an signed offset to the address.
216
+ pub const fn offset ( self , offset : isize ) -> Address {
217
+ Address ( self . 0 . wrapping_add_signed ( offset) )
218
+ }
219
+
215
220
/// Bitwise 'and' with a mask.
216
221
pub const fn and ( self , mask : usize ) -> usize {
217
222
self . 0 & mask
@@ -486,17 +491,23 @@ use crate::vm::VMBinding;
486
491
/// `usize`. For the convenience of passing `Option<ObjectReference>` to and from native (C/C++)
487
492
/// programs, mmtk-core provides [`crate::util::api_util::NullableObjectReference`].
488
493
///
494
+ /// Note that [`ObjectReference`] has to be word aligned.
495
+ ///
489
496
/// [NPO]: https://doc.rust-lang.org/std/option/index.html#representation
490
497
#[ repr( transparent) ]
491
498
#[ derive( Copy , Clone , Eq , Hash , PartialOrd , Ord , PartialEq , NoUninit ) ]
492
499
pub struct ObjectReference ( NonZeroUsize ) ;
493
500
494
501
impl ObjectReference {
502
+ /// The required minimal alignment for object reference. If the object reference's raw address is not aligned to this value,
503
+ /// you will see an assertion failure in the debug build when constructing an object reference instance.
504
+ pub const ALIGNMENT : usize = crate :: util:: constants:: BYTES_IN_ADDRESS ;
505
+
495
506
/// Cast the object reference to its raw address. This method is mostly for the convinience of a binding.
496
507
///
497
508
/// MMTk should not make any assumption on the actual location of the address with the object reference.
498
509
/// MMTk should not assume the address returned by this method is in our allocation. For the purposes of
499
- /// setting object metadata, MMTk should use [`crate::vm::ObjectModel::ref_to_address() `] or [`crate::vm::ObjectModel::ref_to_header() `].
510
+ /// setting object metadata, MMTk should use [`crate::util::ObjectReference::to_address `] or [`crate::util::ObjectReference::to_header `].
500
511
pub fn to_raw_address ( self ) -> Address {
501
512
Address ( self . 0 . get ( ) )
502
513
}
@@ -506,9 +517,13 @@ impl ObjectReference {
506
517
///
507
518
/// If `addr` is 0, the result is `None`.
508
519
///
509
- /// MMTk should not assume an arbitrary address can be turned into an object reference. MMTk can use [`crate::vm::ObjectModel::address_to_ref() `]
510
- /// to turn addresses that are from [`crate::vm::ObjectModel::ref_to_address() `] back to object.
520
+ /// MMTk should not assume an arbitrary address can be turned into an object reference. MMTk can use [`crate::util::ObjectReference::from_address `]
521
+ /// to turn addresses that are from [`crate::util::ObjectReference::to_address `] back to object.
511
522
pub fn from_raw_address ( addr : Address ) -> Option < ObjectReference > {
523
+ debug_assert ! (
524
+ addr. is_aligned_to( Self :: ALIGNMENT ) ,
525
+ "ObjectReference is required to be word aligned"
526
+ ) ;
512
527
NonZeroUsize :: new ( addr. 0 ) . map ( ObjectReference )
513
528
}
514
529
@@ -522,16 +537,19 @@ impl ObjectReference {
522
537
/// adding a positive offset to a non-zero address, we know the result must not be zero.
523
538
pub unsafe fn from_raw_address_unchecked ( addr : Address ) -> ObjectReference {
524
539
debug_assert ! ( !addr. is_zero( ) ) ;
540
+ debug_assert ! (
541
+ addr. is_aligned_to( Self :: ALIGNMENT ) ,
542
+ "ObjectReference is required to be word aligned"
543
+ ) ;
525
544
ObjectReference ( NonZeroUsize :: new_unchecked ( addr. 0 ) )
526
545
}
527
546
528
547
/// Get the in-heap address from an object reference. This method is used by MMTk to get an in-heap address
529
- /// for an object reference. This method is syntactic sugar for [`crate::vm::ObjectModel::ref_to_address`]. See the
530
- /// comments on [`crate::vm::ObjectModel::ref_to_address`].
548
+ /// for an object reference.
531
549
pub fn to_address < VM : VMBinding > ( self ) -> Address {
532
550
use crate :: vm:: ObjectModel ;
533
- let to_address = VM :: VMObjectModel :: ref_to_address ( self ) ;
534
- debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || to_address == self . to_raw_address( ) , "The binding claims unified object reference address, but for object reference {}, ref_to_address() returns {}" , self , to_address) ;
551
+ let to_address = Address ( self . 0 . get ( ) ) . offset ( VM :: VMObjectModel :: IN_OBJECT_ADDRESS_OFFSET ) ;
552
+ debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || to_address == self . to_raw_address( ) , "The binding claims unified object reference address, but for object reference {}, in-object addr is {}" , self , to_address) ;
535
553
to_address
536
554
}
537
555
@@ -549,17 +567,23 @@ impl ObjectReference {
549
567
pub fn to_object_start < VM : VMBinding > ( self ) -> Address {
550
568
use crate :: vm:: ObjectModel ;
551
569
let object_start = VM :: VMObjectModel :: ref_to_object_start ( self ) ;
552
- debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || object_start == self . to_raw_address( ) , "The binding claims unified object reference address, but for object reference {}, ref_to_address () returns {}" , self , object_start) ;
570
+ debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || object_start == self . to_raw_address( ) , "The binding claims unified object reference address, but for object reference {}, ref_to_object_start () returns {}" , self , object_start) ;
553
571
object_start
554
572
}
555
573
556
- /// Get the object reference from an address that is returned from [`crate::util::address::ObjectReference::to_address`]
557
- /// or [`crate::vm::ObjectModel::ref_to_address`]. This method is syntactic sugar for [`crate::vm::ObjectModel::address_to_ref`].
558
- /// See the comments on [`crate::vm::ObjectModel::address_to_ref`].
574
+ /// Get the object reference from an address that is returned from [`crate::util::address::ObjectReference::to_address`].
559
575
pub fn from_address < VM : VMBinding > ( addr : Address ) -> ObjectReference {
560
576
use crate :: vm:: ObjectModel ;
561
- let obj = VM :: VMObjectModel :: address_to_ref ( addr) ;
562
- debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || addr == obj. to_raw_address( ) , "The binding claims unified object reference address, but for address {}, address_to_ref() returns {}" , addr, obj) ;
577
+ let obj = unsafe {
578
+ ObjectReference :: from_raw_address_unchecked (
579
+ addr. offset ( -VM :: VMObjectModel :: IN_OBJECT_ADDRESS_OFFSET ) ,
580
+ )
581
+ } ;
582
+ debug_assert ! ( !VM :: VMObjectModel :: UNIFIED_OBJECT_REFERENCE_ADDRESS || addr == obj. to_raw_address( ) , "The binding claims unified object reference address, but for address {}, the object reference is {}" , addr, obj) ;
583
+ debug_assert ! (
584
+ obj. to_raw_address( ) . is_aligned_to( Self :: ALIGNMENT ) ,
585
+ "ObjectReference is required to be word aligned"
586
+ ) ;
563
587
obj
564
588
}
565
589
0 commit comments