Skip to content

Commit a02803b

Browse files
authored
Remove NULL ObjectReference (#1064)
We changed `ObjectReference` so that it is backed by `NonZeroUsize`, and can no longer represent a NULL reference. For cases where an `ObjectReferences` may or may not exist, `Option<ObjectReference>` should be used instead. This is an API-breaking change. - `ObjectReference::NULL` and `ObjectReference::is_null()` are removed. - `ObjectReference::from_raw_address()` now returns `Option<ObjectReference>`. The unsafe method `ObjectReference::from_raw_address_unchecked()` assumes the address is not zero, and returns `ObjectReference`. - API functions that may or may not return a valid `ObjectReference` now return `Option<ObjectReference>`. Examples include `Edge::load()` and `ReferenceGlue::get_referent()`. If a VM binding needs to expose `Option<ObjectReference>` to native (C/C++) programs, a convenient type `crate::util::api_util::NullableObjectReference` is provided. Fixes: #1043
1 parent 1b9cfe4 commit a02803b

31 files changed

+196
-187
lines changed

docs/userguide/src/tutorial/code/mygc_semispace/gc_work.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ impl<VM: VMBinding> ProcessEdgesWork for MyGCProcessEdges<VM> {
5656
}
5757

5858
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
59-
debug_assert!(!object.is_null());
6059
let worker = self.worker();
6160
let queue = &mut self.base.nodes;
6261
if self.plan.tospace().in_space(object) {

docs/userguide/src/tutorial/mygc/ss/exercise_solution.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ In `gc_work.rs`:
149149
the tospace and fromspace:
150150
```rust
151151
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
152-
debug_assert!(!object.is_null());
153-
154152
// Add this!
155153
else if self.plan().youngspace().in_space(object) {
156154
self.plan().youngspace.trace_object::<Self, TripleSpaceCopyContext<VM>>(

src/memory_manager.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,6 @@ pub fn is_mmtk_object(addr: Address) -> bool {
638638
/// * `object`: The object reference to query.
639639
pub fn is_in_mmtk_spaces<VM: VMBinding>(object: ObjectReference) -> bool {
640640
use crate::mmtk::SFT_MAP;
641-
if object.is_null() {
642-
return false;
643-
}
644641
SFT_MAP
645642
.get_checked(object.to_address::<VM>())
646643
.is_in_space(object)

src/plan/generational/gc_work.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ impl<VM: VMBinding, P: GenerationalPlanExt<VM> + PlanTraceObject<VM>, const KIND
4343
}
4444

4545
fn trace_object(&mut self, object: ObjectReference) -> ObjectReference {
46-
debug_assert!(!object.is_null());
47-
4846
// We cannot borrow `self` twice in a call, so we extract `worker` as a local variable.
4947
let worker = self.worker();
5048
self.plan.trace_object_nursery::<VectorObjectQueue, KIND>(
@@ -55,10 +53,10 @@ impl<VM: VMBinding, P: GenerationalPlanExt<VM> + PlanTraceObject<VM>, const KIND
5553
}
5654

5755
fn process_edge(&mut self, slot: EdgeOf<Self>) {
58-
let object = slot.load();
59-
if object.is_null() {
56+
let Some(object) = slot.load() else {
57+
// Skip slots that are not holding an object reference.
6058
return;
61-
}
59+
};
6260
let new_object = self.trace_object(object);
6361
debug_assert!(!self.plan.is_object_in_nursery(new_object));
6462
// Note: If `object` is a mature object, `trace_object` will not call `space.trace_object`,

src/plan/global.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ pub trait PlanTraceObject<VM: VMBinding> {
691691
///
692692
/// Arguments:
693693
/// * `trace`: the current transitive closure
694-
/// * `object`: the object to trace. This is a non-nullable object reference.
694+
/// * `object`: the object to trace.
695695
/// * `worker`: the GC worker that is tracing this object.
696696
fn trace_object<Q: ObjectQueue, const KIND: TraceKind>(
697697
&self,

src/plan/tracing.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl<'a, E: ProcessEdgesWork> EdgeVisitor<EdgeOf<E>> for ObjectsClosure<'a, E> {
117117
{
118118
use crate::vm::edge_shape::Edge;
119119
trace!(
120-
"(ObjectsClosure) Visit edge {:?} (pointing to {})",
120+
"(ObjectsClosure) Visit edge {:?} (pointing to {:?})",
121121
slot,
122122
slot.load()
123123
);

src/policy/copyspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ impl<VM: VMBinding> CopySpace<VM> {
204204
worker: &mut GCWorker<VM>,
205205
) -> ObjectReference {
206206
trace!("copyspace.trace_object(, {:?}, {:?})", object, semantics,);
207-
debug_assert!(!object.is_null());
208207

209208
// If this is not from space, we do not need to trace it (the object has been copied to the tosapce)
210209
if !self.is_from_space() {

src/policy/immix/immixspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ impl<VM: VMBinding> crate::policy::gc_work::PolicyTraceObject<VM> for ImmixSpace
184184
copy: Option<CopySemantics>,
185185
worker: &mut GCWorker<VM>,
186186
) -> ObjectReference {
187-
debug_assert!(!object.is_null());
188187
if KIND == TRACE_KIND_TRANSITIVE_PIN {
189188
self.trace_object_without_moving(queue, object)
190189
} else if KIND == TRACE_KIND_DEFRAG {

src/policy/immortalspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ impl<VM: VMBinding> ImmortalSpace<VM> {
187187
queue: &mut Q,
188188
object: ObjectReference,
189189
) -> ObjectReference {
190-
debug_assert!(!object.is_null());
191190
#[cfg(feature = "vo_bit")]
192191
debug_assert!(
193192
crate::util::metadata::vo_bit::is_vo_bit_set::<VM>(object),

src/policy/largeobjectspace.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ impl<VM: VMBinding> LargeObjectSpace<VM> {
189189
queue: &mut Q,
190190
object: ObjectReference,
191191
) -> ObjectReference {
192-
debug_assert!(!object.is_null());
193192
#[cfg(feature = "vo_bit")]
194193
debug_assert!(
195194
crate::util::metadata::vo_bit::is_vo_bit_set::<VM>(object),

0 commit comments

Comments
 (0)