From 1b0959f16286c73536f19c8becb1a2ab21c40cbc Mon Sep 17 00:00:00 2001 From: Kunshan Wang Date: Sat, 27 Apr 2024 22:46:42 +0800 Subject: [PATCH] Remove NULL ObjectReference (#169) Upstream PR: https://github.com/mmtk/mmtk-core/pull/1064 --------- Co-authored-by: mmtkgc-bot --- mmtk/Cargo.lock | 21 +++++++-------- mmtk/Cargo.toml | 2 +- mmtk/src/api.rs | 15 ++++------- mmtk/src/object_model.rs | 52 +++++++++++++++++++++++--------------- mmtk/src/reference_glue.rs | 23 ++++++++++++----- 5 files changed, 65 insertions(+), 48 deletions(-) diff --git a/mmtk/Cargo.lock b/mmtk/Cargo.lock index c7a4a2c0..dc5b4c76 100644 --- a/mmtk/Cargo.lock +++ b/mmtk/Cargo.lock @@ -127,12 +127,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -347,9 +348,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -392,9 +393,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -424,7 +425,7 @@ dependencies = [ [[package]] name = "mmtk" version = "0.24.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=e79e94e744660c486d5471f252ff05c4248bcea9#e79e94e744660c486d5471f252ff05c4248bcea9" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=a02803b4104519ff2289234101a2dd8ceedd1bc7#a02803b4104519ff2289234101a2dd8ceedd1bc7" dependencies = [ "atomic", "atomic-traits", @@ -459,7 +460,7 @@ dependencies = [ [[package]] name = "mmtk-macros" version = "0.24.0" -source = "git+https://github.com/mmtk/mmtk-core.git?rev=e79e94e744660c486d5471f252ff05c4248bcea9#e79e94e744660c486d5471f252ff05c4248bcea9" +source = "git+https://github.com/mmtk/mmtk-core.git?rev=a02803b4104519ff2289234101a2dd8ceedd1bc7#a02803b4104519ff2289234101a2dd8ceedd1bc7" dependencies = [ "proc-macro-error", "proc-macro2", @@ -710,9 +711,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.10" +version = "0.30.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d7c217777061d5a2d652aea771fb9ba98b6dade657204b08c4b9604d11555b" +checksum = "87341a165d73787554941cd5ef55ad728011566fe714e987d1b976c15dbc3a83" dependencies = [ "cfg-if", "core-foundation-sys", diff --git a/mmtk/Cargo.toml b/mmtk/Cargo.toml index 6b0c688e..f66765b0 100644 --- a/mmtk/Cargo.toml +++ b/mmtk/Cargo.toml @@ -28,7 +28,7 @@ log = {version = "0.4", features = ["max_level_trace", "release_max_level_off"] # - change branch/rev # - change repo name # But other changes including adding/removing whitespaces in commented lines may break the CI. -mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "e79e94e744660c486d5471f252ff05c4248bcea9" } +mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "a02803b4104519ff2289234101a2dd8ceedd1bc7" } # Uncomment the following to build locally - if you change the path locally, do not commit the change in a PR # mmtk = { path = "../repos/mmtk-core" } diff --git a/mmtk/src/api.rs b/mmtk/src/api.rs index a749941c..a9428952 100644 --- a/mmtk/src/api.rs +++ b/mmtk/src/api.rs @@ -5,6 +5,7 @@ use libc::c_char; use libc::c_void; use mmtk::memory_manager; use mmtk::scheduler::*; +use mmtk::util::api_util::NullableObjectReference; use mmtk::util::opaque_pointer::*; use mmtk::util::{Address, ObjectReference}; @@ -210,11 +211,8 @@ pub extern "C" fn add_phantom_candidate(reff: ObjectReference, referent: ObjectR } #[no_mangle] -pub extern "C" fn get_forwarded_object(object: ObjectReference) -> ObjectReference { - match object.get_forwarded_object::() { - Some(ref_obj) => ref_obj, - None => ObjectReference::NULL, - } +pub extern "C" fn get_forwarded_object(object: ObjectReference) -> NullableObjectReference { + object.get_forwarded_object::().into() } #[no_mangle] @@ -285,11 +283,8 @@ pub extern "C" fn add_finalizer(object: ObjectReference) { } #[no_mangle] -pub extern "C" fn get_finalized_object() -> ObjectReference { - match memory_manager::get_finalized_object(&SINGLETON) { - Some(obj) => obj, - None => ObjectReference::NULL, - } +pub extern "C" fn get_finalized_object() -> NullableObjectReference { + memory_manager::get_finalized_object(&SINGLETON).into() } // Allocation slow path diff --git a/mmtk/src/object_model.rs b/mmtk/src/object_model.rs index bd36eea8..e540ea3e 100644 --- a/mmtk/src/object_model.rs +++ b/mmtk/src/object_model.rs @@ -21,6 +21,15 @@ use memory_manager_constants::*; use tib_layout_constants::*; use JikesRVM; +/// Used as a parameter of `move_object` to specify where to move an object to. +enum MoveTarget { + /// Move an object to the address returned from `alloc_copy`. + ToAddress(Address), + /// Move an object to an `ObjectReference` pointing to an object previously computed from + /// `get_reference_when_copied_to`. + ToObject(ObjectReference), +} + /** Should we gather stats on hash code state transitions for address-based hashing? */ const HASH_STATS: bool = false; /** count number of Object.hashCode() operations */ @@ -131,7 +140,7 @@ impl ObjectModel for VMObjectModel { let bytes = if copy { let bytes = Self::bytes_required_when_copied(from, rvm_type); - Self::move_object(unsafe { Address::zero() }, from, to, bytes, rvm_type); + Self::move_object(from, MoveTarget::ToObject(to), bytes, rvm_type); bytes } else { Self::bytes_used(from, rvm_type) @@ -156,7 +165,8 @@ impl ObjectModel for VMObjectModel { } } - ObjectReference::from_raw_address(res + OBJECT_REF_OFFSET) + debug_assert!(!res.is_zero()); + unsafe { ObjectReference::from_raw_address_unchecked(res + OBJECT_REF_OFFSET) } } fn get_current_size(object: ObjectReference) -> usize { @@ -229,7 +239,8 @@ impl ObjectModel for VMObjectModel { #[inline(always)] fn address_to_ref(addr: Address) -> ObjectReference { - ObjectReference::from_raw_address(addr + (-TIB_OFFSET)) + debug_assert!(!addr.is_zero()); + unsafe { ObjectReference::from_raw_address_unchecked(addr + (-TIB_OFFSET)) } } fn dump_object(_object: ObjectReference) { @@ -256,7 +267,7 @@ impl VMObjectModel { let offset = Self::get_offset_for_alignment_class(from, rvm_type); let region = copy_context.alloc_copy(from, bytes, align, offset, copy); - let to_obj = Self::move_object(region, from, ObjectReference::NULL, bytes, rvm_type); + let to_obj = Self::move_object(from, MoveTarget::ToAddress(region), bytes, rvm_type); copy_context.post_copy(to_obj, bytes, copy); to_obj } @@ -275,7 +286,7 @@ impl VMObjectModel { let offset = Self::get_offset_for_alignment_array(from, rvm_type); let region = copy_context.alloc_copy(from, bytes, align, offset, copy); - let to_obj = Self::move_object(region, from, ObjectReference::NULL, bytes, rvm_type); + let to_obj = Self::move_object(from, MoveTarget::ToAddress(region), bytes, rvm_type); copy_context.post_copy(to_obj, bytes, copy); // XXX: Do not sync icache/dcache because we do not support PowerPC to_obj @@ -371,16 +382,12 @@ impl VMObjectModel { #[inline(always)] fn move_object( - immut_to_address: Address, from_obj: ObjectReference, - immut_to_obj: ObjectReference, + mut to: MoveTarget, num_bytes: usize, _rvm_type: Address, ) -> ObjectReference { trace!("VMObjectModel.move_object"); - let mut to_address = immut_to_address; - let mut to_obj = immut_to_obj; - debug_assert!(to_address.is_zero() || to_obj.to_raw_address().is_zero()); // Default values let mut copy_bytes = num_bytes; @@ -399,8 +406,8 @@ impl VMObjectModel { if !DYNAMIC_HASH_OFFSET { // The hashcode is the first word, so we copy to object one word higher - if to_obj.to_raw_address().is_zero() { - to_address += HASHCODE_BYTES; + if let MoveTarget::ToAddress(ref mut addr) = to { + *addr += HASHCODE_BYTES; } } } else if !DYNAMIC_HASH_OFFSET && hash_state == HASH_STATE_HASHED_AND_MOVED { @@ -410,9 +417,18 @@ impl VMObjectModel { } } - if !to_obj.to_raw_address().is_zero() { - to_address = to_obj.to_raw_address() + (-obj_ref_offset); - } + let (to_address, to_obj) = match to { + MoveTarget::ToAddress(addr) => { + let obj = + unsafe { ObjectReference::from_raw_address_unchecked(addr + obj_ref_offset) }; + (addr, obj) + } + MoveTarget::ToObject(obj) => { + let addr = obj.to_raw_address() + (-obj_ref_offset); + debug_assert!(obj.to_raw_address() == addr + obj_ref_offset); + (addr, obj) + } + }; // Low memory word of source object let from_address = from_obj.to_raw_address() + (-obj_ref_offset); @@ -422,12 +438,6 @@ impl VMObjectModel { Self::aligned_32_copy(to_address, from_address, copy_bytes); } - if to_obj.is_null() { - to_obj = ObjectReference::from_raw_address(to_address + obj_ref_offset); - } else { - debug_assert!(to_obj.to_raw_address() == to_address + obj_ref_offset); - } - // Do we need to copy the hash code? if hash_state == HASH_STATE_HASHED { unsafe { diff --git a/mmtk/src/reference_glue.rs b/mmtk/src/reference_glue.rs index 2f09dd00..dcbacba6 100644 --- a/mmtk/src/reference_glue.rs +++ b/mmtk/src/reference_glue.rs @@ -1,4 +1,5 @@ use mmtk::util::opaque_pointer::*; +use mmtk::util::Address; use mmtk::util::ObjectReference; use mmtk::vm::ReferenceGlue; @@ -25,15 +26,14 @@ impl ReferenceGlue for VMReferenceGlue { } } - fn get_referent(object: ObjectReference) -> ObjectReference { + fn get_referent(object: ObjectReference) -> Option { if cfg!(feature = "binding_side_ref_proc") { panic!(); } else { - debug_assert!(!object.is_null()); - unsafe { - (object.to_raw_address() + REFERENCE_REFERENT_FIELD_OFFSET) - .load::() - } + let addr = unsafe { + (object.to_raw_address() + REFERENCE_REFERENT_FIELD_OFFSET).load::
() + }; + ObjectReference::from_raw_address(addr) } } @@ -52,4 +52,15 @@ impl ReferenceGlue for VMReferenceGlue { } } } + + fn clear_referent(new_reference: ObjectReference) { + if cfg!(feature = "binding_side_ref_proc") { + panic!(); + } else { + unsafe { + (new_reference.to_raw_address() + REFERENCE_REFERENT_FIELD_OFFSET) + .store(Address::ZERO); + } + } + } }