Skip to content

Commit dd2c63b

Browse files
committed
Make ObjectReference non-nullable
1 parent e58470d commit dd2c63b

File tree

6 files changed

+52
-26
lines changed

6 files changed

+52
-26
lines changed

mmtk/Cargo.lock

Lines changed: 2 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mmtk/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ memoffset = "0.9.0"
3232
# - change branch
3333
# - change repo name
3434
# But other changes including adding/removing whitespaces in commented lines may break the CI.
35-
mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "a058b8c4f3dbfa625823847bb5df8e5c87f44e34" }
35+
#mmtk = { git = "https://github.com/mmtk/mmtk-core.git", rev = "a058b8c4f3dbfa625823847bb5df8e5c87f44e34" }
3636
# Uncomment the following to build locally
3737
# mmtk = { path = "../repos/mmtk-core" }
38+
mmtk = { path = "../../mmtk-core" }
3839

3940
[build-dependencies]
4041
built = { version = "0.7.1", features = ["git2"] }

mmtk/src/api.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -516,11 +516,11 @@ pub extern "C" fn add_finalizer(object: ObjectReference) {
516516
}
517517

518518
#[no_mangle]
519-
pub extern "C" fn get_finalized_object() -> ObjectReference {
519+
pub extern "C" fn get_finalized_object() -> Address {
520520
with_singleton!(|singleton| {
521521
match memory_manager::get_finalized_object(singleton) {
522-
Some(obj) => obj,
523-
None => ObjectReference::NULL,
522+
Some(obj) => obj.to_raw_address(),
523+
None => Address::ZERO,
524524
}
525525
})
526526
}

mmtk/src/edges.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,37 +127,57 @@ impl<const COMPRESSED: bool> OpenJDKEdge<COMPRESSED> {
127127

128128
/// encode an object pointer to its u32 compressed form
129129
fn compress(o: ObjectReference) -> u32 {
130-
if o.is_null() {
131-
0u32
132-
} else {
133-
((o.to_raw_address() - BASE.load(Ordering::Relaxed)) >> SHIFT.load(Ordering::Relaxed))
134-
as u32
135-
}
130+
((o.to_raw_address() - BASE.load(Ordering::Relaxed)) >> SHIFT.load(Ordering::Relaxed))
131+
as u32
136132
}
137133

138134
/// decode an object pointer from its u32 compressed form
139-
fn decompress(v: u32) -> ObjectReference {
135+
fn decompress(v: u32) -> Option<ObjectReference> {
140136
if v == 0 {
141-
ObjectReference::NULL
137+
None
138+
} else {
139+
// Note on `unsafe`: The result cannot be zero, so it is safe to use here.
140+
let objref = unsafe {
141+
ObjectReference::from_raw_address_unchecked(
142+
BASE.load(Ordering::Relaxed) + ((v as usize) << SHIFT.load(Ordering::Relaxed)),
143+
)
144+
};
145+
Some(objref)
146+
}
147+
}
148+
149+
/// Store a null reference in the slot.
150+
pub fn store_null(&self) {
151+
if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
152+
if COMPRESSED {
153+
if self.is_compressed() {
154+
self.x86_write_unaligned::<u32, true>(0)
155+
} else {
156+
self.x86_write_unaligned::<Address, true>(Address::ZERO)
157+
}
158+
} else {
159+
self.x86_write_unaligned::<Address, false>(Address::ZERO)
160+
}
142161
} else {
143-
ObjectReference::from_raw_address(
144-
BASE.load(Ordering::Relaxed) + ((v as usize) << SHIFT.load(Ordering::Relaxed)),
145-
)
162+
debug_assert!(!COMPRESSED);
163+
unsafe { self.addr.store(0) }
146164
}
147165
}
148166
}
149167

150168
impl<const COMPRESSED: bool> Edge for OpenJDKEdge<COMPRESSED> {
151-
fn load(&self) -> ObjectReference {
169+
fn load(&self) -> Option<ObjectReference> {
152170
if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
153171
if COMPRESSED {
154172
if self.is_compressed() {
155173
Self::decompress(self.x86_read_unaligned::<u32, true>())
156174
} else {
157-
self.x86_read_unaligned::<ObjectReference, true>()
175+
let addr = self.x86_read_unaligned::<Address, true>();
176+
ObjectReference::from_raw_address(addr)
158177
}
159178
} else {
160-
self.x86_read_unaligned::<ObjectReference, false>()
179+
let addr = self.x86_read_unaligned::<Address, false>();
180+
ObjectReference::from_raw_address(addr)
161181
}
162182
} else {
163183
debug_assert!(!COMPRESSED);

mmtk/src/object_model.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ impl<const COMPRESSED: bool> ObjectModel<OpenJDK<COMPRESSED>> for VMObjectModel<
3131
// Copy
3232
let src = from.to_raw_address();
3333
unsafe { std::ptr::copy_nonoverlapping::<u8>(src.to_ptr(), dst.to_mut_ptr(), bytes) }
34-
let to_obj = ObjectReference::from_raw_address(dst);
34+
// Note on onsafe: `alloc_copy` never returns 0.
35+
let to_obj = unsafe { ObjectReference::from_raw_address_unchecked(dst) };
3536
copy_context.post_copy(to_obj, bytes, copy);
3637
to_obj
3738
}
@@ -56,7 +57,8 @@ impl<const COMPRESSED: bool> ObjectModel<OpenJDK<COMPRESSED>> for VMObjectModel<
5657
}
5758

5859
fn get_reference_when_copied_to(_from: ObjectReference, to: Address) -> ObjectReference {
59-
ObjectReference::from_raw_address(to)
60+
debug_assert!(!to.is_zero());
61+
unsafe { ObjectReference::from_raw_address_unchecked(to) }
6062
}
6163

6264
fn get_current_size(object: ObjectReference) -> usize {
@@ -93,7 +95,8 @@ impl<const COMPRESSED: bool> ObjectModel<OpenJDK<COMPRESSED>> for VMObjectModel<
9395
}
9496

9597
fn address_to_ref(address: Address) -> ObjectReference {
96-
ObjectReference::from_raw_address(address)
98+
debug_assert!(!address.is_zero());
99+
unsafe { ObjectReference::from_raw_address_unchecked(address) }
97100
}
98101

99102
fn dump_object(object: ObjectReference) {

mmtk/src/reference_glue.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl<const COMPRESSED: bool> ReferenceGlue<OpenJDK<COMPRESSED>> for VMReferenceG
1515
let oop = Oop::from(reff);
1616
InstanceRefKlass::referent_address::<COMPRESSED>(oop).store(referent);
1717
}
18-
fn get_referent(object: ObjectReference) -> ObjectReference {
18+
fn get_referent(object: ObjectReference) -> Option<ObjectReference> {
1919
let oop = Oop::from(object);
2020
InstanceRefKlass::referent_address::<COMPRESSED>(oop).load()
2121
}
@@ -24,4 +24,8 @@ impl<const COMPRESSED: bool> ReferenceGlue<OpenJDK<COMPRESSED>> for VMReferenceG
2424
((*UPCALLS).enqueue_references)(references.as_ptr(), references.len());
2525
}
2626
}
27+
fn clear_referent(new_reference: ObjectReference) {
28+
let oop = Oop::from(new_reference);
29+
InstanceRefKlass::referent_address::<COMPRESSED>(oop).store_null();
30+
}
2731
}

0 commit comments

Comments
 (0)