Issue mmtk/mmtk-core#1170 proposed requiring the ObjectReference type in mmtk-core to always point into a byte inside an object (in addition to the already-added requirement that ObjectReference must be word-aligned). That will make side metadata handling much easier, and eliminate the need to distinguish between ObjectReference.to_address::<VM>() and ObjectReference.to_raw_address() which is confusing.
JikesRVM is the only officially supported VM where object.to_address::<JikesRVM>() is different from object.to_raw_address(). In JikesRVM, ObjectReference is defined as the address of the array payload. The entire JikesRVM is built around this definition. Constants (such as TIB_OFFSET, STATUS_OFFSET and ARRAY_LENGTH_OFFSET) are all relative to the JikesRVM-level ObjectReference.
However, to implement mmtk/mmtk-core#1170, we must redefine the MMTk-level ObjectReference which the JikesRVM binding gives to mmtk-core. The address of the JavaHeader of each object is a good candidate for the new definition because it is guaranteed to be inside an object. But from the software engineering's point of view,
- we can't change the JikesRVM-level
ObjectReference because it is used throughout the VM, and
- we don't want to change the constants in
mmtk-jikesrvm/mmtk/src/java_header_constants.rs to be relative to JavaHeader because it makes the code inconsistent and error-prone.
To solve this problem, we need to make a clear distinction between the MMTk-level ObjectReference and the JikesRVM-level ObjectReference. We'll create a new Rust type struct JikesObj(Address) which is equal to the JikesRVM-level ObjectReference. We can convert between JikesObj and (the MMTk-level) ObjectReference by adding/subtracting JAVA_HEADER_BYTES. All the header / status / length fields are accessed using JikesObj using existing constants which are relative to JikesObj.
The refactoring will take three steps. The first two steps are local to mmtk-jikesrvm. Only the last step involves changes to mmtk-core.
- Step 1: Introducing the JikesRVM-specific
JikesObj type. All methods that access object metadata and type info are off-loaded to the JikesObj type and other wrapper types such as TIB and RVMType. That leaves the implementation of the ObjectModel trait as simple as converting the MMTk-level ObjectReference parameter to JikesObj, and calling its methods. In this step, JikeObj and ObjectReference still have the same underlying usize value. This step only makes sure the new abstraction works.
- Step 2: Redefining the MMTk-level
ObjectReference to point to JavaHeader. If the abstraction from Step 1 is correct, we only need to rewrite the conversion function between ObjectReference and JikesObj, and change some constants (most importantly IN_OBJECT_ADDRESS_OFFSET) in VMObjectModel. This step makes sure the JikesRVM binding can work with a changed definition of MMTk-level ObjectReference.
- Step 3: Modifying mmtk-core to require
ObjectReference to point into an object. This will formally introduce the requirement into mmtk-core, and refactor functions (such as the algorithm that searches for the last VO bits) to take advantage of the new requirement. Since the JikesRVM binding already works with ObjectReference pointing into object bodies in Step 2, Step 3 should be as simple as removing redundant methods and constants in the ObjectModel trait.
Issue mmtk/mmtk-core#1170 proposed requiring the
ObjectReferencetype in mmtk-core to always point into a byte inside an object (in addition to the already-added requirement thatObjectReferencemust be word-aligned). That will make side metadata handling much easier, and eliminate the need to distinguish betweenObjectReference.to_address::<VM>()andObjectReference.to_raw_address()which is confusing.JikesRVM is the only officially supported VM where
object.to_address::<JikesRVM>()is different fromobject.to_raw_address(). In JikesRVM,ObjectReferenceis defined as the address of the array payload. The entire JikesRVM is built around this definition. Constants (such asTIB_OFFSET,STATUS_OFFSETandARRAY_LENGTH_OFFSET) are all relative to the JikesRVM-levelObjectReference.However, to implement mmtk/mmtk-core#1170, we must redefine the MMTk-level
ObjectReferencewhich the JikesRVM binding gives to mmtk-core. The address of theJavaHeaderof each object is a good candidate for the new definition because it is guaranteed to be inside an object. But from the software engineering's point of view,ObjectReferencebecause it is used throughout the VM, andmmtk-jikesrvm/mmtk/src/java_header_constants.rsto be relative toJavaHeaderbecause it makes the code inconsistent and error-prone.To solve this problem, we need to make a clear distinction between the MMTk-level
ObjectReferenceand the JikesRVM-levelObjectReference. We'll create a new Rust typestruct JikesObj(Address)which is equal to the JikesRVM-levelObjectReference. We can convert betweenJikesObjand (the MMTk-level)ObjectReferenceby adding/subtractingJAVA_HEADER_BYTES. All the header / status / length fields are accessed usingJikesObjusing existing constants which are relative toJikesObj.The refactoring will take three steps. The first two steps are local to mmtk-jikesrvm. Only the last step involves changes to mmtk-core.
JikesObjtype. All methods that access object metadata and type info are off-loaded to theJikesObjtype and other wrapper types such asTIBandRVMType. That leaves the implementation of theObjectModeltrait as simple as converting the MMTk-levelObjectReferenceparameter toJikesObj, and calling its methods. In this step,JikeObjandObjectReferencestill have the same underlyingusizevalue. This step only makes sure the new abstraction works.ObjectReferenceto point toJavaHeader. If the abstraction from Step 1 is correct, we only need to rewrite the conversion function betweenObjectReferenceandJikesObj, and change some constants (most importantlyIN_OBJECT_ADDRESS_OFFSET) inVMObjectModel. This step makes sure the JikesRVM binding can work with a changed definition of MMTk-levelObjectReference.ObjectReferenceto point into an object. This will formally introduce the requirement into mmtk-core, and refactor functions (such as the algorithm that searches for the last VO bits) to take advantage of the new requirement. Since the JikesRVM binding already works withObjectReferencepointing into object bodies in Step 2, Step 3 should be as simple as removing redundant methods and constants in theObjectModeltrait.