WARNING: The use of the direct heap access operations is GC-unsafe. Therefore, these operations should be used with extreme care in a few select places, and only within GC-unsafe regions. VM code should use the indirect memory layer almost all the time when outside the interpreter.
Table of Contents
Note that the implementation of GC read and write barriers are hidden beneath the Ref typed accessors.
Weakly-typed 32-bit read and write:
macro void CVMD_fieldRead32( CVMObject* o, CVMUint32 off, CVMJavaVal32 res) macro void CVMD_fieldWrite32(CVMObject* o, CVMUint32 off, CVMJavaVal32 res)
Strongly-typed 32-bit read and write:
macro void CVMD_fieldReadRef( CVMObject* o, CVMUint32 off, CVMObject* item) macro void CVMD_fieldWriteRef( CVMObject* o, CVMUint32 off, CVMObject* item) macro void CVMD_fieldReadInt( CVMObject* o, CVMUint32 off, CVMJavaInt item) macro void CVMD_fieldWriteInt( CVMObject* o, CVMUint32 off, CVMJavaInt item) macro void CVMD_fieldReadFloat( CVMObject* o, CVMUint32 off, CVMJavaFloat item) macro void CVMD_fieldWriteFloat( CVMObject* o, CVMUint32 off, CVMJavaFloat item)
The weakly-typed versions read from and write into a word-aligned two-word area pointed to by location.
Weakly-typed 64-bit read and write:
macro void CVMD_fieldRead64( CVMObject* o, CVMUint32 off, CVMJavaVal32* location) macro void CVMD_fieldWrite64( CVMObject* o, CVMUint32 off, CVMJavaVal32* location)
Strongly-typed 64-bit read and write:
macro void CVMD_fieldReadLong( CVMObject* o, CVMUint32 off, CVMJavaVal64 val64) macro void CVMD_fieldWriteLong( CVMObject* o, CVMUint32 off, CVMJavaVal64 val64) macro void CVMD_fieldReadDouble( CVMObject* o, CVMUint32 off, CVMJavaVal64 val64) macro void CVMD_fieldWriteDouble(CVMObject* o, CVMUint32 off, CVMJavaVal64 val64)
In these macros, the first parameter is a direct array reference, the second is the array index where the first array element is at index 0, and the third is an l-value to read into, or a value to write.
These macros are all strongly typed. All the Java basic types are represented.
Note that the implementation of GC read and write barriers are hidden beneath the Ref typed accessors.
macro void CVMD_arrayReadRef( CVMArrayOfRef* arr, CVMUint32 index, CVMObject* item) macro void CVMD_arrayWriteRef( CVMArrayOfRef* arr, CVMUint32 index, CVMObject* item) macro void CVMD_arrayReadInt( CVMArrayOfInt* arr, CVMUint32 index, CVMJavaInt item) macro void CVMD_arrayWriteInt( CVMArrayOfInt* arr, CVMUint32 index, CVMJavaInt item) macro void CVMD_arrayReadByte( CVMArrayOfByte* arr, CVMUint32 index, CVMJavaByte item) macro void CVMD_arrayWriteByte( CVMArrayOfByte* arr, CVMUint32 index, CVMJavaByte item) macro void CVMD_arrayReadBool( CVMArrayOfBool* arr, CVMUint32 index, CVMJavaBool item) macro void CVMD_arrayWriteBool( CVMArrayOfBool* arr, CVMUint32 index, CVMJavaBool item) macro void CVMD_arrayReadShort( CVMArrayOfShort* arr, CVMUint32 index, CVMJavaShort item) macro void CVMD_arrayWriteShort( CVMArrayOfShort* arr, CVMUint32 index, CVMJavaShort item) macro void CVMD_arrayReadChar( CVMArrayOfChar* arr, CVMUint32 index, CVMJavaChar item) macro void CVMD_arrayWriteChar( CVMArrayOfChar* arr, CVMUint32 index, CVMJavaChar item) macro void CVMD_arrayReadFloat( CVMArrayOfFloat* arr, CVMUint32 index, CVMJavaFloat item) macro void CVMD_arrayWriteFloat( CVMArrayOfFloat* arr, CVMUint32 index, CVMJavaFloat item)
In these macros, the first parameter is a direct array reference, the second is the array index where the first array element is at index 0, and the third is an l-value of type CVMJavaVal64 to read into or a value to write.
The weakly-typed versions read from and write to a word-aligned two-word area pointed to by location:
macro void CVMD_arrayRead64( <CVMArrayOf64>* o, CVMUint32 off, CVMJavaVal32* location) macro void CVMD_arrayWrite64( <CVMArrayOf64>* o, CVMUint32 off, CVMJavaVal32* location)where <CVMArrayOf64> is either CVMArrayOfLong or CVMArrayOfDouble.
Strongly-typed versions:
macro void CVMD_arrayReadLong( <CVMArrayOf64>* o, CVMUint32 index, CVMJavaVal64 val64) macro void CVMD_arrayWriteLong( <CVMArrayOf64>* o, CVMUint32 index, CVMJavaVal64 val64) macro void CVMD_arrayReadDouble( <CVMArrayOf64>* o, CVMUint32 index, CVMJavaVal64 val64) macro void CVMD_arrayWriteDouble(<CVMArrayOf64>* o, CVMUint32 index, CVMJavaVal64 val64)where <CVMArrayOf64> is either CVMArrayOfLong or CVMArrayOfDouble.
All generic object operations apply to arrays as well. In particular, the header of an array object starts out with an object header, with an additional length entry, so any operation on the header of an object may be performed on an array header.
Below are array-specific operations.
Getting the length of an array:
macro CVMJavaInt32 CVMD_arrayGetLength(<CVMArrayOfAny>* o)where <CVMArrayOfAny> is any direct array reference.
Here are a couple of operations to create GC-unsafe windows of
operation, and to request GC-safe points.
The first macro is used for code that will not block. The
assumption here is that there is some cached state in the GC-unsafe
code which needs to be saved if GC is needed.
The second macro is used for code that may potentially block. In
this case, whatever cached state the GC-unsafe code has must be saved
before calling the macro.
GC-unsafe blocks
When a GC-safe thread wants to perform a GC-unsafe operation, it marks
itself as unable to tolerate GC, performs the GC-unsafe operation, and
then marks itself again as GC-safe.
CVMD_gcUnsafeExec() is
the way to create such a window of GC-unsafety. At the end of the
GC-unsafe window, the thread calling
CVMD_gcUnsafeExec()
polls for a GC request. If there is one, the thread suspends itself to
rendezvous with all the other threads rolling forward to their GC
points. Execution continues after GC.
macro void CVMD_gcUnsafeExec(CVMExecEnv* ee, code gcUnsafeAction)
where ee is a pointer to the current thread's execution
environment, and gcUnsafeAction is a segment of GC-unsafe code.
GC-safe blocks: Requesting a GC-safe point
GC-unsafe code must occasionally offer to become GC-safe to
bound the time from a GC request to the beginning of
GC. CVMD_gcSafeExec and
CVMD_gcSafeCheckPoint are
the two macros that allow that.
macro void CVMD_gcSafeCheckPoint(CVMExecEnv* ee, code saveAction, code restoreAction)
The thread calling CVMD_gcSafeCheckPoint()
checks whether there is a GC request. If there is, the thread executes
saveAction to save state necessary for GC, marks itself as
GC-safe, and suspends itself to rendezvous with all the other threads
rolling forward to their GC points. After GC completes, the thread is
resumed, marks itself as GC-unsafe again, and executes
restoreAction to do any caching operations necessary to
continue execution.
macro void CVMD_gcSafeExec(CVMExecEnv* ee,
The thread calling CVMD_gcSafeExec()
code saveAction,
code safeAction,
code restoreAction)
executes saveAction unconditionally,
marks itself GC-safe, and checks
to see if there is a GC-request. If there is one, the thread suspends
itself to rendezvous with all the other threads rolling forward to
their GC points. After GC is over, the thread is resumed, still in a
GC-safe state. It executes safeAction,
potentially blocking. After waking up from the blocking action, the thread marks
itself as GC-unsafe, and finally executes
restoreAction to cache state
and continues with GC-unsafe execution.