From 2558b4fa16786dc779a0601e1792032b7c7a1ba3 Mon Sep 17 00:00:00 2001 From: Kunshan Wang Date: Wed, 17 Apr 2024 16:50:30 +0800 Subject: [PATCH 1/2] Add missing pinning metadata to mock_vm --- src/util/test_util/mock_vm.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/util/test_util/mock_vm.rs b/src/util/test_util/mock_vm.rs index 9f5d0c7122..842b37f8e6 100644 --- a/src/util/test_util/mock_vm.rs +++ b/src/util/test_util/mock_vm.rs @@ -478,6 +478,9 @@ impl crate::vm::ObjectModel for MockVM { const LOCAL_LOS_MARK_NURSERY_SPEC: VMLocalLOSMarkNurserySpec = VMLocalLOSMarkNurserySpec::in_header(0); + #[cfg(feature = "object_pinning")] + const LOCAL_PINNING_BIT_SPEC: VMLocalPinningBitSpec = VMLocalPinningBitSpec::in_header(0); + const OBJECT_REF_OFFSET_LOWER_BOUND: isize = DEFAULT_OBJECT_REF_OFFSET as isize; fn copy( From 954ad7df0301c07687048a23ebe455b13054ebcb Mon Sep 17 00:00:00 2001 From: Kunshan Wang Date: Wed, 17 Apr 2024 16:59:51 +0800 Subject: [PATCH 2/2] Use to_address for SFT access Changed convenient methods in `ObjectReference` so that if they use SFT, we use `self.to_address()` to get the address instead of `self.0` which returns the raw address. --- src/memory_manager.rs | 4 ++-- src/policy/immix/immixspace.rs | 2 +- src/util/address.rs | 29 ++++++++++++----------------- src/util/finalizable_processor.rs | 2 +- src/util/reference_processor.rs | 14 +++++++------- src/util/sanity/sanity_checker.rs | 2 +- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/memory_manager.rs b/src/memory_manager.rs index cabaa93ead..7cab5f932c 100644 --- a/src/memory_manager.rs +++ b/src/memory_manager.rs @@ -557,8 +557,8 @@ pub fn handle_user_collection_request(mmtk: &MMTK, tls: VMMut /// /// Arguments: /// * `object`: The object reference to query. -pub fn is_live_object(object: ObjectReference) -> bool { - object.is_live() +pub fn is_live_object(object: ObjectReference) -> bool { + object.is_live::() } /// Check if `addr` is the address of an object reference to an MMTk object. diff --git a/src/policy/immix/immixspace.rs b/src/policy/immix/immixspace.rs index bf72394c01..049e18f699 100644 --- a/src/policy/immix/immixspace.rs +++ b/src/policy/immix/immixspace.rs @@ -650,7 +650,7 @@ impl ImmixSpace { ); queue.enqueue(new_object); - debug_assert!(new_object.is_live()); + debug_assert!(new_object.is_live::()); self.unlog_object_if_needed(new_object); new_object } diff --git a/src/util/address.rs b/src/util/address.rs index 499d8c00fa..913c3ea198 100644 --- a/src/util/address.rs +++ b/src/util/address.rs @@ -546,49 +546,44 @@ impl ObjectReference { self.0 == 0 } - /// returns the ObjectReference - pub fn value(self) -> usize { - self.0 - } - /// Is the object reachable, determined by the policy? /// Note: Objects in ImmortalSpace may have `is_live = true` but are actually unreachable. - pub fn is_reachable(self) -> bool { + pub fn is_reachable(self) -> bool { if self.is_null() { false } else { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.is_reachable(self) + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.is_reachable(self) } } /// Is the object live, determined by the policy? - pub fn is_live(self) -> bool { + pub fn is_live(self) -> bool { if self.0 == 0 { false } else { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.is_live(self) + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.is_live(self) } } /// Can the object be moved? - pub fn is_movable(self) -> bool { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.is_movable() + pub fn is_movable(self) -> bool { + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.is_movable() } /// Get forwarding pointer if the object is forwarded. - pub fn get_forwarded_object(self) -> Option { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.get_forwarded_object(self) + pub fn get_forwarded_object(self) -> Option { + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.get_forwarded_object(self) } /// Is the object in any MMTk spaces? - pub fn is_in_any_space(self) -> bool { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.is_in_space(self) + pub fn is_in_any_space(self) -> bool { + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.is_in_space(self) } /// Is the object sane? #[cfg(feature = "sanity")] - pub fn is_sane(self) -> bool { - unsafe { SFT_MAP.get_unchecked(Address(self.0)) }.is_sane() + pub fn is_sane(self) -> bool { + unsafe { SFT_MAP.get_unchecked(self.to_address::()) }.is_sane() } } diff --git a/src/util/finalizable_processor.rs b/src/util/finalizable_processor.rs index d341a4694b..77ab7edbfc 100644 --- a/src/util/finalizable_processor.rs +++ b/src/util/finalizable_processor.rs @@ -53,7 +53,7 @@ impl FinalizableProcessor { for mut f in self.candidates.drain(start..).collect::>() { let reff = f.get_reference(); trace!("Pop {:?} for finalization", reff); - if reff.is_live() { + if reff.is_live::() { FinalizableProcessor::::forward_finalizable_reference(e, &mut f); trace!("{:?} is live, push {:?} back to candidates", reff, f); self.candidates.push(f); diff --git a/src/util/reference_processor.rs b/src/util/reference_processor.rs index 718235ff67..a0ce86cbd1 100644 --- a/src/util/reference_processor.rs +++ b/src/util/reference_processor.rs @@ -246,11 +246,11 @@ impl ReferenceProcessor { // For references in the table, the reference needs to be valid, and if the referent is not null, it should be valid as well sync.references.iter().for_each(|reff| { debug_assert!(!reff.is_null()); - debug_assert!(reff.is_in_any_space()); + debug_assert!(reff.is_in_any_space::()); let referent = VM::VMReferenceGlue::get_referent(*reff); if !VM::VMReferenceGlue::is_referent_cleared(referent) { debug_assert!( - referent.is_in_any_space(), + referent.is_in_any_space::(), "Referent {:?} (of reference {:?}) is not in any space", referent, reff @@ -260,7 +260,7 @@ impl ReferenceProcessor { // For references that will be enqueue'd, the referent needs to be valid, and the referent needs to be null. sync.enqueued_references.iter().for_each(|reff| { debug_assert!(!reff.is_null()); - debug_assert!(reff.is_in_any_space()); + debug_assert!(reff.is_in_any_space::()); let referent = VM::VMReferenceGlue::get_referent(*reff); debug_assert!(VM::VMReferenceGlue::is_referent_cleared(referent)); }); @@ -397,7 +397,7 @@ impl ReferenceProcessor { trace!("Processing reference: {:?}", reference); - if !reference.is_live() { + if !reference.is_live::() { // Reference is currently unreachable but may get reachable by the // following trace. We postpone the decision. continue; @@ -433,7 +433,7 @@ impl ReferenceProcessor { // If the reference is dead, we're done with it. Let it (and // possibly its referent) be garbage-collected. - if !reference.is_live() { + if !reference.is_live::() { ::VMReferenceGlue::clear_referent(reference); trace!(" UNREACHABLE reference: {}", reference); trace!(" (unreachable)"); @@ -456,11 +456,11 @@ impl ReferenceProcessor { trace!(" => {}", new_reference); - if old_referent.is_live() { + if old_referent.is_live::() { // Referent is still reachable in a way that is as strong as // or stronger than the current reference level. let new_referent = Self::get_forwarded_referent(trace, old_referent); - debug_assert!(new_referent.is_live()); + debug_assert!(new_referent.is_live::()); trace!(" ~> {}", new_referent); // The reference object stays on the waiting list, and the diff --git a/src/util/sanity/sanity_checker.rs b/src/util/sanity/sanity_checker.rs index 069dc93808..1fc7836613 100644 --- a/src/util/sanity/sanity_checker.rs +++ b/src/util/sanity/sanity_checker.rs @@ -195,7 +195,7 @@ impl ProcessEdgesWork for SanityGCProcessEdges { let mut sanity_checker = self.mmtk().sanity_checker.lock().unwrap(); if !sanity_checker.refs.contains(&object) { // FIXME steveb consider VM-specific integrity check on reference. - assert!(object.is_sane(), "Invalid reference {:?}", object); + assert!(object.is_sane::(), "Invalid reference {:?}", object); // Let plan check object assert!(