Search in sources :

Example 1 with RuntimeTable

use of org.jikesrvm.objectmodel.RuntimeTable in project JikesRVM by JikesRVM.

the class BootImageWriter method copyToBootImage.

/**
 * Copy an object (and, recursively, any of its fields or elements that
 * are references) from host jdk address space into image.
 *
 * @param jdkObject object to be copied
 * @param allocOnly if allocOnly is true, the TIB and other reference fields are not recursively copied
 * @param overwriteAddress if !overwriteAddress.isMax(), then copy object to given address
 * @param parentObject
 * @param untraced Do not report any fields of this object as references
 * @param alignCode Alignment-encoded value (TIB allocation only)
 * @return offset of copied object within image, in bytes
 *         (OBJECT_NOT_PRESENT --> object not copied:
 *            it's not part of bootimage)
 */
private static Address copyToBootImage(Object jdkObject, boolean allocOnly, Address overwriteAddress, Object parentObject, boolean untraced, int alignCode) throws IllegalAccessException {
    try {
        // Return object if it is already copied and not being overwritten
        BootImageMap.Entry mapEntry = BootImageMap.findOrCreateEntry(jdkObject);
        if ((!mapEntry.imageAddress.EQ(OBJECT_NOT_ALLOCATED)) && overwriteAddress.isMax()) {
            return mapEntry.imageAddress;
        }
        if (verbosity.isAtLeast(DETAILED))
            depth++;
        // fetch object's type information
        Class<?> jdkType = jdkObject.getClass();
        RVMType rvmType = getRvmType(jdkType);
        if (rvmType == null) {
            if (verbosity.isAtLeast(DETAILED))
                traverseObject(jdkObject);
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            // object not part of bootimage
            return OBJECT_NOT_PRESENT;
        }
        // copy object to image
        if (jdkType.isArray()) {
            // allocate space in image prior to recursing
            int arrayCount = Array.getLength(jdkObject);
            RVMArray rvmArrayType = rvmType.asArray();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address arrayImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateArray(rvmArrayType, arrayCount, needsIdentityHash, identityHashValue, alignCode) : overwriteAddress;
            mapEntry.imageAddress = arrayImageAddress;
            mapEntry.imageAddress = copyArrayToBootImage(arrayCount, arrayImageAddress, jdkObject, jdkType, rvmArrayType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("", jdkObject.getClass().getName(), "tib");
                Address tibImageAddress = copyToBootImage(rvmType.getTypeInformationBlock(), allocOnly, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                if (tibImageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    fail("can't copy tib for " + jdkObject);
                }
                ObjectModel.setTIB(bootImage, mapEntry.imageAddress, tibImageAddress, rvmType);
            }
        } else if (jdkObject instanceof TIB) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            int alignCodeValue = ((TIB) jdkObject).getAlignData();
            if (verbosity.isAtLeast(DETAILED))
                say("Encoding value " + alignCodeValue + " into tib");
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), alignCodeValue);
            if (verbosity.isAtLeast(DETAILED))
                say(String.format("TIB address = %x, encoded value = %d, requested = %d%n", mapEntry.imageAddress.toInt(), AlignmentEncoding.extractTibCode(mapEntry.imageAddress), alignCodeValue));
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (rvmType == RVMType.ObjectReferenceArrayType || rvmType.getTypeRef().isRuntimeTable()) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), AlignmentEncoding.ALIGN_CODE_NONE);
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (jdkObject instanceof RuntimeTable) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            mapEntry.imageAddress = copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType == RVMType.CodeArrayType) {
            // Handle the code array that is represented as either byte or int arrays
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            Object backing = ((CodeArray) jdkObject).getBacking();
            return copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType.getTypeRef().isMagicType()) {
            say("Unhandled copying of magic type: " + rvmType.getDescriptor().toString() + " in object of type " + parentObject.getClass().toString());
            fail("incomplete boot image support");
        } else {
            // allocate space in image
            if (rvmType instanceof RVMArray)
                fail("This isn't a scalar " + rvmType);
            RVMClass rvmScalarType = rvmType.asClass();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address scalarImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateScalar(rvmScalarType, needsIdentityHash, identityHashValue) : overwriteAddress;
            mapEntry.imageAddress = scalarImageAddress;
            mapEntry.imageAddress = copyClassToBootImage(scalarImageAddress, jdkObject, jdkType, rvmScalarType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        }
        if (verbosity.isAtLeast(DETAILED))
            depth--;
        return mapEntry.imageAddress;
    } catch (Error e) {
        e = new Error(e.getMessage() + "\nwhile copying " + jdkObject + (jdkObject != null ? ":" + jdkObject.getClass() : "") + " from " + parentObject + (parentObject != null ? ":" + parentObject.getClass() : ""), e.getCause() != null ? e.getCause() : e);
        throw e;
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) RVMClass(org.jikesrvm.classloader.RVMClass) RuntimeTable(org.jikesrvm.objectmodel.RuntimeTable) CodeArray(org.jikesrvm.compilers.common.CodeArray) RVMArray(org.jikesrvm.classloader.RVMArray)

Aggregations

RVMArray (org.jikesrvm.classloader.RVMArray)1 RVMClass (org.jikesrvm.classloader.RVMClass)1 RVMType (org.jikesrvm.classloader.RVMType)1 CodeArray (org.jikesrvm.compilers.common.CodeArray)1 RuntimeTable (org.jikesrvm.objectmodel.RuntimeTable)1 TIB (org.jikesrvm.objectmodel.TIB)1 Address (org.vmmagic.unboxed.Address)1