public class ObjectModel extends Object
Conceptually each Java object is composed of the following pieces:
JavaHeader
. This portion of the
object supports language-level functions such as locking, hashcodes,
dynamic type checking, virtual function invocation, and array length.
MemoryManager
. This portion
of the object supports allocator-specific requirements such as
mark/barrier bits, reference counts, etc.
MiscHeader
. This portion supports
various other clients that want to add bits/words to all objects.
Typical uses are profiling and instrumentation (basically this is a
way to add an instance field to java.lang.Object).
|<- lo memory hi memory ->| SCALAR LAYOUT: |<---------- scalar header --------->| +----------+------------+------------+------+------+------+--------+ | GCHeader | MiscHeader | JavaHeader | fldO | fld1 | fldx | fldN-1 | +----------+------------+------------+------+------+------+--------+ ^ JHOFF ^objref . ARRAY LAYOUT: . |<---------- array header ----------------->| +----------+------------+------------+------+------+------+------+------+ | GCHeader | MiscHeader | JavaHeader | len | elt0 | elt1 | ... |eltN-1| +----------+------------+------------+------+------+------+------+------+ ^ JHOFF ^objref
Assumptions:
This model allows free null pointer checking for most reads: a small offset from that reference will wrap around to either very high or very low unmapped memory in the case of a null pointer. As long as these segments of memory are not mapped to the current process, loads/stores through such a pointer will cause a trap that we can catch with a unix signal handler.
Note the key invariant that all elements of the header are available at the same offset from an objref for both arrays and scalar objects.
Note that this model allows for arbitrary growth of the GC header to the left of the object. A possible TODO item is to modify the necessary interfaces within this class and JavaHeader to allow moveObject, bytesUsed, bytesRequiredWhenCopied, etc. to tell this class how many GC header bytes have been allocated. As these calls would be constant within the constant of the call the optimising compiler should be able to allow this at minimal cost.
Another possible TODO item is to include support for linear scanning, where it is possible to move from one object to the next under contiguous allocation. At the moment this is in conflict with object alignment code for objects with long/double fields. We could possibly include the code anyway but require that the alignment code is switched off, or that all objects are aligned. Linear scanning is used in several GC algorithms including card-marking and compaction.
JavaHeader
,
MiscHeader
,
MemoryManager
Modifier and Type | Field and Description |
---|---|
static boolean |
HASH_STATS
Should we gather stats on hash code state transitions for address-based hashing?
|
static int |
hashRequests
count number of Object.hashCode() operations
|
static int |
hashTransition1
count transitions from UNHASHED to HASHED
|
static int |
hashTransition2
count transitions from HASHED to HASHED_AND_MOVED
|
private static FieldLayout |
layout
Layout widget
|
private static boolean |
PACKED
Whether to pack bytes and shorts into 32bit fields
|
Constructor and Description |
---|
ObjectModel() |
Modifier and Type | Method and Description |
---|---|
static Address |
allocateArray(BootImageInterface bootImage,
RVMArray array,
int numElements,
boolean needsIdentityHash,
int identityHashValue,
int alignCode)
Allocate and initialize space in the bootimage (at bootimage writing time)
to be an uninitialized instance of the (array) type specified by array.
|
static Address |
allocateArray(BootImageInterface bootImage,
RVMArray array,
int numElements,
boolean needsIdentityHash,
int identityHashValue,
int align,
int alignCode)
Allocate and initialize space in the bootimage (at bootimage writing time)
to be an uninitialized instance of the (array) type specified by array.
|
static Address |
allocateCode(BootImageInterface bootImage,
RVMArray array,
int numElements)
Allocate and initialize space in the bootimage (at bootimage writing time)
to be an uninitialized instance of the (array) type specified by array.
|
static Address |
allocateScalar(BootImageInterface bootImage,
RVMClass klass,
boolean needsIdentityHash,
int identityHashValue)
Allocate and initialize space in the bootimage (at bootimage writing time)
to be an uninitialized instance of the (scalar) type specified by klass.
|
static void |
allocateThinLock(RVMType t)
Allocates a thin lock word for instances of the type
(if they already have one, then has no effect).
|
static boolean |
attemptAvailableBits(Object o,
Word oldVal,
Word newVal)
An attempt on the word containing the available bits.
|
static int |
bytesRequiredWhenCopied(Object obj) |
static int |
bytesRequiredWhenCopied(Object fromObj,
RVMArray type,
int numElements)
how many bytes are needed when the array object is copied by GC?
|
static int |
bytesRequiredWhenCopied(Object fromObj,
RVMClass type)
how many bytes are needed when the scalar object is copied by GC?
|
static int |
bytesUsed(Object obj) |
static int |
bytesUsed(Object obj,
RVMArray type,
int numElements)
how many bytes are used by the array?
|
static int |
bytesUsed(Object obj,
RVMClass type)
how many bytes are used by the scalar?
|
static int |
computeArrayHeaderSize(RVMArray type)
Computes the header size of an instance of the given type.
|
static int |
computeHeaderSize(Object ref)
Computes the header size of an object.
|
static int |
computeHeaderSize(Object[] tib)
Given a TIB, compute the header size of an instance of the TIB's class.
|
static int |
computeHeaderSize(RVMType type)
Computes the header size of an instance of the given type.
|
static int |
computeScalarHeaderSize(RVMClass type)
Computes the header size of an instance of the given type.
|
static Offset |
defaultThinLockOffset() |
static void |
describeObject(ObjectReference addr)
For debugging: dumps descriptor of an object.
|
static void |
dumpHeader(Object ref)
For low level debugging of GC subsystem.
|
static void |
dumpHeader(ObjectReference ptr)
For low level debugging of GC subsystem.
|
static void |
fillAlignmentGap(BootImageInterface bootImage,
Address address,
Extent size)
Fills an alignment gap with the alignment value
|
static void |
genericLock(Object o) |
static void |
genericUnlock(Object o) |
static int |
getAlignment(RVMArray t) |
static int |
getAlignment(RVMArray t,
Object obj) |
static int |
getAlignment(RVMClass t) |
static int |
getAlignment(RVMClass t,
Object obj) |
static ObjectReference |
getArrayFromStartAddress(Address start)
Gets an object reference from the address the lowest word of the object was allocated.
|
static int |
getArrayLength(Object o) |
static Offset |
getArrayLengthOffset() |
static int |
getHeaderEndOffset()
For a reference to an object, what is the offset in bytes to the
last word of the header from an out-to-in perspective for the object?
|
static Lock |
getHeavyLock(Object o,
boolean create)
Obtains the heavy-weight lock, if there is one, associated with the
indicated object.
|
static ObjectReference |
getNextObject(ObjectReference obj) |
static ObjectReference |
getNextObject(ObjectReference obj,
RVMArray type,
int numElements)
Get the next object after this array under contiguous allocation.
|
static ObjectReference |
getNextObject(ObjectReference obj,
RVMClass type)
Gets the next object after this scalar under contiguous allocation.
|
static Address |
getObjectEndAddress(Object obj)
Get the pointer just past an object.
|
static Address |
getObjectEndAddress(Object object,
RVMArray type,
int elements)
Gets the pointer just past an object.
|
static Address |
getObjectEndAddress(Object object,
RVMClass type)
Gets the pointer just past an object.
|
static ObjectReference |
getObjectFromStartAddress(Address start)
Get an object reference from the address the lowest word of the object was allocated.
|
static int |
getObjectHashCode(Object o) |
static RVMType |
getObjectType(Object o) |
static int |
getOffsetForAlignment(RVMArray t,
boolean needsIdentityHash) |
static int |
getOffsetForAlignment(RVMArray t,
ObjectReference obj) |
static int |
getOffsetForAlignment(RVMClass t,
boolean needsIdentityHash) |
static int |
getOffsetForAlignment(RVMClass t,
ObjectReference obj) |
static Address |
getPointerInMemoryRegion(ObjectReference ref)
Given a reference, return an address which is guaranteed to be inside
the memory region allocated to the object.
|
static Object |
getReferenceWhenCopiedTo(Object obj,
Address to)
Gets the reference of an object after copying to a specified region.
|
static Object |
getReferenceWhenCopiedTo(Object obj,
Address region,
RVMArray type)
Get the reference of an object after copying to a specified region.
|
static Object |
getReferenceWhenCopiedTo(Object obj,
Address region,
RVMClass type)
Get the reference of an object after copying to a specified region.
|
static ObjectReference |
getScalarFromStartAddress(Address start)
Gets an object reference from the address the lowest word of the object was allocated.
|
static Offset |
getThinLockOffset(Object o) |
static TIB |
getTIB(Object o) |
static TIB |
getTIB(ObjectReference ptr) |
static boolean |
holdsLock(Object obj,
RVMThread thread) |
static Object |
initializeArray(Address ptr,
TIB tib,
int numElems,
int size)
Initialize raw storage with low memory word ptr of size bytes
to be an uninitialized instance of the array type specific by tib
with numElems elements.
|
static void |
initializeAvailableByte(Object o)
Freezes the other bits in the byte containing the available bits
so that it is safe to update them using setAvailableBits.
|
static Object |
initializeScalar(Address ptr,
TIB tib,
int size)
Initialize raw storage with low memory word ptr of size bytes
to be an uninitialized instance of the (scalar) type specified by tib.
|
static void |
layoutInstanceFields(RVMClass klass)
Layout the instance fields declared in this class.
|
static Address |
maximumObjectRef(Address regionHighAddr)
Given the largest base address in a region, return the largest
object reference that could refer to an object in the region.
|
static Address |
minimumObjectRef(Address regionBaseAddr)
Given the smallest base address in a region, return the smallest
object reference that could refer to an object in the region.
|
static Object |
moveObject(Address toAddress,
Object fromObj,
int numBytes,
RVMArray type)
Copy an array object to the given raw storage address
|
static Object |
moveObject(Address toAddress,
Object fromObj,
int numBytes,
RVMClass type)
Copy a scalar object to the given raw storage address.
|
static Object |
moveObject(Object fromObj,
Object toObj,
int numBytes,
RVMArray type)
Copy an array object to the given raw storage address.
|
static Object |
moveObject(Object fromObj,
Object toObj,
int numBytes,
RVMClass type)
Copies a scalar object to the given raw storage address.
|
static int |
objectStartOffset(RVMClass t)
For a reference to an object, what is the offset in bytes to the bottom
word of the object?
|
static Address |
objectStartRef(ObjectReference obj)
Maps from the object ref to the lowest address of the storage
associated with the object.
|
static Word |
prepareAvailableBits(Object o)
A prepare on the word containing the available bits.
|
static Word |
readAvailableBitsWord(Object o)
Non-atomic read of word containing available bits
|
static byte |
readAvailableByte(Object o)
Non-atomic read of byte containing available bits
|
static void |
setArrayLength(Object o,
int len)
Sets the length of an array.
|
static void |
setAvailableBit(Object o,
int idx,
boolean flag)
Sets argument bit to 1 if value is true, 0 if value is false
|
static void |
setTIB(BootImageInterface bootImage,
Address refAddress,
Address tibAddr,
RVMType type)
Sets the TIB for an object during bootimage writing.
|
static void |
setTIB(ObjectReference ptr,
TIB tib) |
static void |
setTIB(Object ref,
TIB tib) |
static boolean |
testAvailableBit(Object o,
int idx) |
static void |
writeAvailableBitsWord(Object o,
Word val)
Non-atomic write of word containing available bits.
|
static void |
writeAvailableByte(Object o,
byte val)
Non-atomic write of byte containing available bits
|
public static final boolean HASH_STATS
public static int hashRequests
public static int hashTransition1
public static int hashTransition2
private static final boolean PACKED
private static final FieldLayout layout
public ObjectModel()
public static void layoutInstanceFields(RVMClass klass)
klass
- the class to layoutpublic static Address getPointerInMemoryRegion(ObjectReference ref)
ref
- an objectpublic static Offset getArrayLengthOffset()
public static TIB getTIB(ObjectReference ptr)
public static void setTIB(ObjectReference ptr, TIB tib)
public static void setTIB(BootImageInterface bootImage, Address refAddress, Address tibAddr, RVMType type)
bootImage
- the bootimagerefAddress
- the object's addresstibAddr
- the TIB's addresstype
- the object's typepublic static Address getObjectEndAddress(Object obj)
obj
- the object in questionpublic static Address getObjectEndAddress(Object object, RVMClass type)
object
- the object in questiontype
- the object's classpublic static Address getObjectEndAddress(Object object, RVMArray type, int elements)
object
- the object in questiontype
- the object's classelements
- the array's lengthpublic static ObjectReference getObjectFromStartAddress(Address start)
start
- the lowest word in the storage of an allocated objectpublic static ObjectReference getScalarFromStartAddress(Address start)
start
- the lowest word in the storage of an allocated objectpublic static ObjectReference getArrayFromStartAddress(Address start)
start
- the lowest word in the storage of an allocated objectpublic static ObjectReference getNextObject(ObjectReference obj)
obj
- an objectpublic static ObjectReference getNextObject(ObjectReference obj, RVMClass type)
obj
- the current object, which must be a scalartype
- the object's typepublic static ObjectReference getNextObject(ObjectReference obj, RVMArray type, int numElements)
obj
- the current object, which must be an arraytype
- the object's typenumElements
- the length of the arraypublic static Object getReferenceWhenCopiedTo(Object obj, Address to)
obj
- the object to copyto
- the target address for the copypublic static int bytesUsed(Object obj)
obj
- an objectpublic static int bytesUsed(Object obj, RVMClass type)
obj
- an objecttype
- the object's typepublic static int bytesUsed(Object obj, RVMArray type, int numElements)
obj
- an objecttype
- the object's typenumElements
- the array's lengthpublic static int bytesRequiredWhenCopied(Object obj)
obj
- the objectpublic static int bytesRequiredWhenCopied(Object fromObj, RVMClass type)
fromObj
- the object to copytype
- the object's typepublic static int bytesRequiredWhenCopied(Object fromObj, RVMArray type, int numElements)
fromObj
- the object to copytype
- the object's typenumElements
- the number of elements in the arraypublic static Address objectStartRef(ObjectReference obj)
obj
- the object referencepublic static Object getReferenceWhenCopiedTo(Object obj, Address region, RVMClass type)
obj
- the object to copyregion
- the target address for the copytype
- the scalar's typepublic static Object getReferenceWhenCopiedTo(Object obj, Address region, RVMArray type)
obj
- the object to copyregion
- the target address for the copytype
- the array's typepublic static Object moveObject(Object fromObj, Object toObj, int numBytes, RVMClass type)
fromObj
- the scalar to copytoObj
- target address for copynumBytes
- how many bytes to copytype
- the scalar's typepublic static Object moveObject(Object fromObj, Object toObj, int numBytes, RVMArray type)
fromObj
- the object to copytoObj
- the target objectnumBytes
- the number of bytes to copytype
- the array's typepublic static Object moveObject(Address toAddress, Object fromObj, int numBytes, RVMClass type)
toAddress
- the target addressfromObj
- the object to copynumBytes
- how many bytes to copytype
- the scalar's typepublic static Object moveObject(Address toAddress, Object fromObj, int numBytes, RVMArray type)
toAddress
- the target addressfromObj
- the object to copynumBytes
- how many bytes to copytype
- the array's typepublic static RVMType getObjectType(Object o)
o
- an objectpublic static int getArrayLength(Object o)
o
- an arraypublic static void setArrayLength(Object o, int len)
o
- an arraylen
- the length of the arraypublic static int getObjectHashCode(Object o)
public static Offset getThinLockOffset(Object o)
public static Offset defaultThinLockOffset()
public static void allocateThinLock(RVMType t)
t
- the type that is supposed to receive a thin
lock wordpublic static void genericLock(Object o)
public static void genericUnlock(Object o)
public static boolean holdsLock(Object obj, RVMThread thread)
obj
- an objectthread
- a threadtrue
if the lock on obj is currently owned
by thread false
if it is not.public static Lock getHeavyLock(Object o, boolean create)
null
, if there is no
heavy-weight lock associated with the object.o
- the object from which a lock is desiredcreate
- if true, create heavy lock if none foundpublic static Word readAvailableBitsWord(Object o)
o
- the object to readpublic static byte readAvailableByte(Object o)
o
- the object to readpublic static void writeAvailableBitsWord(Object o, Word val)
o
- the object whose word will be writtenval
- the available bits wordpublic static void writeAvailableByte(Object o, byte val)
o
- the object whose available byte will be writtenval
- the value to write to the available bytepublic static boolean testAvailableBit(Object o, int idx)
o
- the object whose bit will be testedidx
- the index in the bitstrue
if argument bit is 1, false
if it is 0public static void setAvailableBit(Object o, int idx, boolean flag)
o
- the object whose bit will be setidx
- the index in the bitsflag
- true
for 1, false
for 0public static void initializeAvailableByte(Object o)
o
- the object whose available bytes will be initializedpublic static Word prepareAvailableBits(Object o)
Note: this method is intended to be used in conjunction with the attempt method.
o
- the object which has the available bitsattemptAvailableBits(Object, Word, Word)
public static boolean attemptAvailableBits(Object o, Word oldVal, Word newVal)
Note: this method is intended to be used in conjunction
with the prepare method. If the method returns false
,
callers must update their information about the old value of
the available bits word before retrying again.
o
- the object which has the available bitsoldVal
- the old value that the word is expected to havenewVal
- the new value that will be written, if possiblepublic static Address minimumObjectRef(Address regionBaseAddr)
regionBaseAddr
- the smallest base address in the regionpublic static Address maximumObjectRef(Address regionHighAddr)
regionHighAddr
- the highest base address in the regionpublic static int computeHeaderSize(RVMType type)
type
- the instance's typepublic static int computeHeaderSize(Object ref)
ref
- the object whose header size is of interestpublic static int computeScalarHeaderSize(RVMClass type)
type
- the instance's typepublic static int computeArrayHeaderSize(RVMArray type)
type
- the instance's typepublic static int computeHeaderSize(Object[] tib)
tib
- a TIBpublic static int getHeaderEndOffset()
public static int objectStartOffset(RVMClass t)
t
- the class of the objectpublic static int getAlignment(RVMClass t)
t
- RVMClass instance being createdpublic static int getAlignment(RVMClass t, Object obj)
t
- RVMClass instance being copiedobj
- the object being copiedpublic static int getAlignment(RVMArray t)
t
- RVMArray instance being createdpublic static int getAlignment(RVMArray t, Object obj)
t
- RVMArray instance being copiedobj
- the object being copiedpublic static int getOffsetForAlignment(RVMClass t, boolean needsIdentityHash)
t
- RVMClass instance being createdneedsIdentityHash
- TODO document this parameter. IIs it still needed?
It's never set to true.public static int getOffsetForAlignment(RVMClass t, ObjectReference obj)
t
- RVMClass instance being copiedobj
- the object being copiedpublic static int getOffsetForAlignment(RVMArray t, boolean needsIdentityHash)
t
- RVMArray instance being createdneedsIdentityHash
- TODO document this parameter. Is it still needed?
It's never set to true.public static int getOffsetForAlignment(RVMArray t, ObjectReference obj)
t
- RVMArray instance being copiedobj
- the object being copiedpublic static Object initializeScalar(Address ptr, TIB tib, int size)
ptr
- address of raw storagetib
- the type information blocksize
- number of bytes of raw storage allocated.public static Address allocateScalar(BootImageInterface bootImage, RVMClass klass, boolean needsIdentityHash, int identityHashValue)
bootImage
- the bootimage to put the object inklass
- the RVMClass object of the instance to create.needsIdentityHash
- needs an identity hash valueidentityHashValue
- the value for the identity hashpublic static void fillAlignmentGap(BootImageInterface bootImage, Address address, Extent size)
bootImage
- the bootimage being compiledaddress
- the start address for the gap that needs to be filledsize
- the size of the gap to be filledpublic static Object initializeArray(Address ptr, TIB tib, int numElems, int size)
ptr
- address of raw storagetib
- the type information blocknumElems
- number of elements in the arraysize
- number of bytes of raw storage allocated.public static Address allocateArray(BootImageInterface bootImage, RVMArray array, int numElements, boolean needsIdentityHash, int identityHashValue, int alignCode)
bootImage
- the bootimage to put the object inarray
- RVMArray object of array being allocated.numElements
- number of elementsneedsIdentityHash
- needs an identity hash valueidentityHashValue
- the value for the identity hashalignCode
- TODOpublic static Address allocateArray(BootImageInterface bootImage, RVMArray array, int numElements, boolean needsIdentityHash, int identityHashValue, int align, int alignCode)
bootImage
- the bootimage to put the object inarray
- RVMArray object of array being allocated.numElements
- number of elementsneedsIdentityHash
- needs an identity hash valueidentityHashValue
- the value for the identity hashalign
- special alignment valuealignCode
- the alignment-encoded valuepublic static Address allocateCode(BootImageInterface bootImage, RVMArray array, int numElements)
bootImage
- the bootimage to put the object inarray
- RVMArray object of array being allocated.numElements
- number of elementspublic static void dumpHeader(ObjectReference ptr)
ptr
- the object reference whose header should be dumpedpublic static void dumpHeader(Object ref)
ref
- the object reference whose header should be dumpedpublic static void describeObject(ObjectReference addr)
addr
- the object to dump