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;
}
}
Aggregations