Skip to content

Commit 5ecfd57

Browse files
authored
Use JavaHeader address as ObjectReference (#179)
This PR changes the definition of MMTk-level `ObjectReference` for the JikesRVM binding so that it now points to the JavaHeader, and is different from the JikesRVM-level `ObjectReference` (a.k.a. `JikesObj`). This will guarantee that the MMTk-level ObjectReference is always inside an object. Note that this PR does not involve a change in mmtk-core. It changes `ObjectModel::IN_OBJECT_ADDRESS_OFFSET` to 0 so that the "in-object address" is identical to the raw address of `ObjectReference`. It demonstrates the JikesRVM binding can work well with MMTk-level `ObjectReference` being different from JikesRVM-level `ObjectReference`. Related issues and PRs. - This PR is based on #177 - This PR is the 2nd step of #178 - It will ultimately allow mmtk/mmtk-core#1170 to be implemented.
1 parent 7efbc5c commit 5ecfd57

File tree

2 files changed

+24
-12
lines changed

2 files changed

+24
-12
lines changed

mmtk/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ pub struct JikesRVM;
4646

4747
/// The type of slots in JikesRVM.
4848
///
49-
/// Each slot holds a `JikesObj` value, which is equal to the JikesRVM-level `ObjectReference`. The
50-
/// Java parts of the binding may insert `Address` values into native arrays of `JikesRVMSlot`
51-
/// passed from Rust code, so this type has `repr(transparent)` to make sure it has the same layout
52-
/// as `Address`
49+
/// Each slot holds a `JikesObj` value. Conversion between `JikesObj` and the MMTk-level
50+
/// `ObjectReference` happens when loading from or storing to a slot. The Java parts of the binding
51+
/// may use raw memory access to insert `Address` into Rust arrays of `JikesRVMSlot`, so this type
52+
/// has `repr(transparent)` to make sure it has the same layout as `Address`
5353
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5454
#[repr(transparent)]
5555
pub struct JikesRVMSlot(Address);

mmtk/src/object_model.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use libc::*;
22
use std::convert::{TryFrom, TryInto};
33
use std::sync::atomic::{AtomicUsize, Ordering};
44

5+
use crate::java_header_constants::JAVA_HEADER_OFFSET;
56
use crate::unboxed_size_constants::*;
67
use crate::vm_metadata;
78
use mmtk::util::alloc::fill_alignment_gap;
@@ -24,25 +25,33 @@ use JikesRVM;
2425

2526
/// This type represents a JikesRVM-level `ObjectReference`.
2627
///
27-
/// Currently, it has the same value as the MMTk-level `mmtk::util::address::ObjectReference`, but
28-
/// can be null (has the value of 0). Therefore, an MMTk-level `ObjectReference` can always safely
29-
/// converted to a `JikesObj`, but safely converting a `JikesObj` to an MMTk-level `ObjectReference`
30-
/// will involve a null check.
28+
/// A `JikesObj` has the same value as the JikesRVM-level `ObjectReference`, while an MMTk-level
29+
/// `ObjectReference` points at the JavaHeader of an object. Converting between the two types
30+
/// involves adding/subtracting an offset. Because JikesRVM-level `ObjectReference` (and therefore
31+
/// `JikesObj`) can be null, safely converting a `JikesObj` to an MMTk-level `ObjectReference` will
32+
/// involve a null check.
3133
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3234
#[repr(transparent)]
3335
pub struct JikesObj(Address);
3436

3537
impl From<ObjectReference> for JikesObj {
3638
fn from(value: ObjectReference) -> Self {
37-
Self(value.to_raw_address())
39+
Self(value.to_raw_address().offset(-JAVA_HEADER_OFFSET))
3840
}
3941
}
4042

4143
impl TryFrom<JikesObj> for ObjectReference {
4244
type Error = NullRefError;
4345

4446
fn try_from(value: JikesObj) -> Result<Self, Self::Error> {
45-
ObjectReference::from_raw_address(value.0).ok_or(NullRefError)
47+
if value.is_null() {
48+
Err(NullRefError)
49+
} else {
50+
let objref_addr = value.0.offset(JAVA_HEADER_OFFSET);
51+
debug_assert!(!objref_addr.is_zero());
52+
let result = unsafe { ObjectReference::from_raw_address_unchecked(objref_addr) };
53+
Ok(result)
54+
}
4655
}
4756
}
4857

@@ -449,9 +458,12 @@ impl ObjectModel<JikesRVM> for VMObjectModel {
449458
JikesObj::from(object).to_address()
450459
}
451460

452-
const OBJECT_REF_OFFSET_LOWER_BOUND: isize = OBJECT_REF_OFFSET;
461+
/// This is the offset from the start to the JavaHeader when the object does not have the hash
462+
/// code in the front. Its value is zero for now.
463+
const OBJECT_REF_OFFSET_LOWER_BOUND: isize = OBJECT_REF_OFFSET + JAVA_HEADER_OFFSET;
453464

454-
const IN_OBJECT_ADDRESS_OFFSET: isize = TIB_OFFSET;
465+
/// MMTk-level `ObjectReference` points at the JavaHeader which is always inside the object.
466+
const IN_OBJECT_ADDRESS_OFFSET: isize = 0;
455467

456468
fn dump_object(_object: ObjectReference) {
457469
unimplemented!()

0 commit comments

Comments
 (0)