The indirect memory interface

The indirect memory interface reference

Introduction

This document is the reference manual for the indirect memory layer. These functions are used for accessing the garbage-collected heap indirectly using pointers to ICells. Please refer to How to be GC-safe in CVM for context and examples.

Note that the indirect memory interface is GC-safe, and is appropriate for use in VM code outside of the interpreter, like the class loader, or JNI implementation.

Table of Contents

ICell manipulations

Let's define the referent of an ICell as the direct object reference encapsulated by the ICell. The indirect memory interface allows GC-safe assignments and comparisons between referents of ICell's.

Assign referent of srcICellPtr to be the referent of dstICellPtr:

    macro void CVMID_icellAssign(CVMExecEnv* ee, CVMObjectICell* destICellPtr, CVMObjectICell* srcICellPtr)

Null out the referent of icellPtr:

    macro void CVMID_icellSetNull(CVMExecEnv* ee, CVMObjectICell* icellPtr)

Test whether the referent of icellPtr is null, The result is in res:

    macro void CVMID_icellIsNull(CVMExecEnv* ee, CVMObjectICell* icellPtr, CVMBool res)

Test whether the referent of icellPtr1 is the same object reference as icellPtr2. The result is in res:

    macro void CVMID_icellSameObject(CVMExecEnv* ee, CVMObjectICell* icellPtr1, CVMObjectICell* icellPtr2, CVMBool res)

Registered indirection cells

An indirection cell must be registered with GC to be scanned as a root. A registered indirection cell is either a local root or global root. In both cases, the client code is handed a pointer to an ICell that is part of the root set of GC.

Local roots

Local roots are allocated within local root blocks. At the end of a local root block, all allocated local roots within the block are destroyed. Note that local root blocks may be nested arbitrarily.

To begin a local root block, with respect to the current thread's execution environment, ee:

    macro CVMID_localrootBegin(CVMExecEnv* ee)
To allocate a local root and return a pointer to it:
    macro CVMID_localrootDeclare(<ICell>, var)
Here <ICell> may be any legal object or array ICell type. CVMID_localrootDeclare allocates a new local root, nulls out its referent, declares a <ICell>* var, and makes var point to the new local root. var is visible within the scope of the local root block.

To end the local root block, and to discard all local roots allocated within the block:

    macro CVMID_localrootEnd()

Global roots

Global roots are not bound to any one thread, but are shared between all threads. They are analogous to JNI global refs. Note that unlike local roots, global roots may be allocated out-of-order.

To allocate a new global root, null out its referent and return a pointer to it:

    CVMObjectICell* CVMID_getGlobalRoot()

To free the global root pointed to by globalRoot:

    void CVMID_freeGlobalRoot(CVMObjectICell* globalRoot)

Object field accesses

The following macros access object fields. The result-producing ones take an l-value as the last argument, and assign to it.

Accessing fields of 32-bit width

In these macros, the first parameter is a pointer to the execution environment (CVMExecEnv) of the current thread, the second parameter is a registered indirect object reference (CVMObjectICell*), the third is an offset in number of words from the beginning of the object, counting the first header word as 0, and the fourth is an l-value to read into or a value to write.

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 CVMID_fieldRead32( CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal32 res)
    macro void CVMID_fieldWrite32(CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal32 res)

Strongly-typed 32-bit read and write:

    macro void CVMID_fieldReadRef(    CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMObjectICell* item)
    macro void CVMID_fieldWriteRef(   CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMObjectICell* item)

    macro void CVMID_fieldReadInt(    CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaInt item)
    macro void CVMID_fieldWriteInt(   CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaInt item)

    macro void CVMID_fieldReadFloat(  CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaFloat item)
    macro void CVMID_fieldWriteFloat( CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaFloat item)

Accessing fields of 64-bit width

In these macros, the first parameter is a pointer to the execution environment (CVMExecEnv) of the current thread, the second parameter is a registered indirect object reference (CVMObjectICell*), the third is an offset in number of words from the beginning of the object, counting the first header word as 0, and the fourth is an l-value of type CVMJavaVal64 to read into or a value to write.

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 CVMID_fieldRead64(   CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal32* location)
    macro void CVMID_fieldWrite64(  CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal32* location)

Strongly-typed 64-bit read and write:

    macro void CVMID_fieldReadLong(   CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal64 val64)
    macro void CVMID_fieldWriteLong(  CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal64 val64)

    macro void CVMID_fieldReadDouble( CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal64 val64)
    macro void CVMID_fieldWriteDouble(CVMExecEnv* ee, CVMObjectICell* o, CVMUint32 off, CVMJavaVal64 val64)

Array accesses

The following macros access object fields. The result-producing ones take an l-value as the last argument, and assign to it.

Accessing elements of 32-bit width and below

In these macros, the first parameter is a pointer to the execution environment (CVMExecEnv) of the current thread, the second parameter is a registered indirect array reference (CVMArrayOf<T>ICell*), the third is the array index where the first array element is at index 0, and the fourth 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 CVMID_arrayReadRef(    CVMExecEnv* ee, CVMArrayOfRefICell* arr,   CVMUint32 index, CVMObjectICell* item)
    macro void CVMID_arrayWriteRef(   CVMExecEnv* ee, CVMArrayOfRefICell* arr,   CVMUint32 index, CVMObjectICell* item)

    macro void CVMID_arrayReadInt(    CVMExecEnv* ee, CVMArrayOfIntICell* arr,   CVMUint32 index, CVMJavaInt item)
    macro void CVMID_arrayWriteInt(   CVMExecEnv* ee, CVMArrayOfIntICell* arr,   CVMUint32 index, CVMJavaInt item)

    macro void CVMID_arrayReadByte(   CVMExecEnv* ee, CVMArrayOfByteICell* arr,  CVMUint32 index, CVMJavaByte item)
    macro void CVMID_arrayWriteByte(  CVMExecEnv* ee, CVMArrayOfByteICell* arr,  CVMUint32 index, CVMJavaByte item)

    macro void CVMID_arrayReadBool(   CVMExecEnv* ee, CVMArrayOfBoolICell* arr,  CVMUint32 index, CVMJavaBool item)
    macro void CVMID_arrayWriteBool(  CVMExecEnv* ee, CVMArrayOfBoolICell* arr,  CVMUint32 index, CVMJavaBool item)

    macro void CVMID_arrayReadShort(  CVMExecEnv* ee, CVMArrayOfShortICell* arr, CVMUint32 index, CVMJavaShort item)
    macro void CVMID_arrayWriteShort( CVMExecEnv* ee, CVMArrayOfShortICell* arr, CVMUint32 index, CVMJavaShort item)

    macro void CVMID_arrayReadChar(   CVMExecEnv* ee, CVMArrayOfCharICell*  arr, CVMUint32 index, CVMJavaChar item)
    macro void CVMID_arrayWriteChar(  CVMExecEnv* ee, CVMArrayOfCharICell*  arr, CVMUint32 index, CVMJavaChar item)

    macro void CVMID_arrayReadFloat(  CVMExecEnv* ee, CVMArrayOfFloatICell* arr, CVMUint32 index, CVMJavaFloat item)
    macro void CVMID_arrayWriteFloat( CVMExecEnv* ee, CVMArrayOfFloatICell* arr, CVMUint32 index, CVMJavaFloat item)

Accessing elements of 64-bit width

In these macros, the first parameter is a pointer to the execution environment (CVMExecEnv) of the current thread, the second parameter is a registered indirect array reference (CVMArrayOf<T>ICell*), the third is the array index where the first array element is at index 0, and the fourth 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 CVMID_arrayRead64(   CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 off, CVMJavaVal32* location)
    macro void CVMID_arrayWrite64(  CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 off, CVMJavaVal32* location)
where <CVMArrayOf64ICell> is either CVMArrayOfLongICell or CVMArrayOfDoubleICell.

Strongly-typed versions:

    macro void CVMID_arrayReadLong(   CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 index, CVMJavaVal64 val64)
    macro void CVMID_arrayWriteLong(  CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 index, CVMJavaVal64 val64)

    macro void CVMID_arrayReadDouble( CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 index, CVMJavaVal64 val64)
    macro void CVMID_arrayWriteDouble(CVMExecEnv* ee, <CVMArrayOf64ICell>* o, CVMUint32 index, CVMJavaVal64 val64)
where <CVMArrayOf64ICell> is either CVMArrayOfLongICell or CVMArrayOfDoubleICell.

Miscellaneous array operations

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 void CVMID_arrayGetLength(<CVMArrayOfAnyICell>* o, CVMJavaInt32 len)
where <CVMArrayOfAnyICell>* is a registered indirect array reference, and len is an l-value of type CVMJavaInt32 to store the length result in.

GC-unsafe operations

The remaining two operations allow setting and getting the referent of an ICell.

WARNING: The use of the ICell referent operations is GC-unsafe. Therefore, these operations should be used with extreme care in a few select places, and only within GC-unsafe regions.

Get the referent of icellPtr:

    macro CVMObject* CVMID_icellDirect(CVMObjectICell* icellPtr)

Set the referent of icellPtr to be the direct object reference directObj:

    macro void CVMID_icellSetDirect(CVMObjectICell* icellPtr, CVMObject* directObj)