use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class ClassLoader method defineClass0.
/**
* Loads new type into the classloader name space.
* The class loader is marked as defining class loader.
*/
private Class<?> defineClass0(String name, byte[] data, int offset, int len) throws ClassFormatError {
RVMType vmType = RVMClassLoader.defineClassInternal(name, data, offset, len, this);
Class<?> ans = vmType.getClassForType();
loadedClasses.put(name, ans);
return ans;
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method copyMagicArrayToBootImage.
/**
* Copy a unboxed array type to the boot image
* @param jdkObject object representation
* @param rvmArrayType type of array
* @param allocOnly allocate object don't write to fields
* @param overwriteAddress addresss to write to if overwriting
* @param parentObject object containing array
* @return address of array
* @throws IllegalAccessException
*/
private static Address copyMagicArrayToBootImage(Object jdkObject, RVMArray rvmArrayType, boolean allocOnly, Address overwriteAddress, Object parentObject) throws IllegalAccessException {
// 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++;
RVMType rvmElementType = rvmArrayType.getElementType();
// allocate space in image
int arrayCount = Array.getLength(jdkObject);
Address arrayImageAddress;
if (overwriteAddress.isMax()) {
if (rvmElementType.equals(RVMType.CodeType)) {
arrayImageAddress = bootImage.allocateCode(rvmArrayType, arrayCount);
} else {
boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
int identityHashValue = mapEntry.getIdentityHashCode();
arrayImageAddress = bootImage.allocateArray(rvmArrayType, arrayCount, needsIdentityHash, identityHashValue, AlignmentEncoding.ALIGN_CODE_NONE);
}
} else {
arrayImageAddress = overwriteAddress;
}
mapEntry.imageAddress = arrayImageAddress;
if (verbosity.isAtLeast(DETAILED)) {
if (depth == DEPTH_CUTOFF)
say(SPACES.substring(0, depth + 1), "TOO DEEP: cutting off");
else if (depth < DEPTH_CUTOFF) {
String tab = SPACES.substring(0, depth + 1);
if (depth == 0 && jtocCount >= 0)
tab = tab + "jtoc #" + String.valueOf(jtocCount) + ": ";
int arraySize = rvmArrayType.getInstanceSize(arrayCount);
say(tab, "Copying array ", rvmArrayType.toString(), " length=", String.valueOf(arrayCount), (arraySize >= LARGE_ARRAY_SIZE) ? " large object!!!" : "");
}
}
// copy array elements from host jdk address space into image
if (rvmElementType.equals(RVMType.CodeType)) {
if (VM.BuildForIA32) {
byte[] values = (byte[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i]);
} else {
int[] values = (int[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setFullWord(arrayImageAddress.plus(i << LOG_BYTES_IN_INT), values[i]);
}
} else if (rvmElementType.equals(RVMType.AddressType)) {
Address[] values = (Address[]) jdkObject;
for (int i = 0; i < arrayCount; i++) {
Address addr = values[i];
String msg = "Address array element";
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, true), false, false);
}
} else if (rvmElementType.equals(RVMType.WordType)) {
Word[] values = (Word[]) jdkObject;
for (int i = 0; i < arrayCount; i++) {
String msg = "Word array element ";
Word addr = values[i];
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
}
} else if (rvmElementType.equals(RVMType.OffsetType)) {
Offset[] values = (Offset[]) jdkObject;
for (int i = 0; i < arrayCount; i++) {
String msg = "Offset array element " + i;
Offset addr = values[i];
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
}
} else if (rvmElementType.equals(RVMType.ExtentType)) {
Extent[] values = (Extent[]) jdkObject;
for (int i = 0; i < arrayCount; i++) {
String msg = "Extent array element ";
Extent addr = values[i];
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), getWordValue(addr, msg, false), false, false);
}
} else {
fail("unexpected magic array type: " + rvmArrayType);
}
// copy object's TIB into image, if it's not there already
if (!allocOnly) {
copyTIBToBootImage(rvmArrayType, jdkObject, mapEntry.imageAddress);
}
if (verbosity.isAtLeast(DETAILED))
depth--;
return mapEntry.imageAddress;
}
use of org.jikesrvm.classloader.RVMType 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;
}
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method copyKnownInstanceField.
/**
* If we can't find a field via reflection we may still determine
* and copy a value because we know the internals of Classpath.
* @param jdkObject the object containing the field
* @param rvmFieldName the name of the field
* @param rvmFieldType the type reference of the field
* @param rvmFieldAddress the address that the field is being written to
*/
private static boolean copyKnownInstanceField(Object jdkObject, String rvmFieldName, TypeReference rvmFieldType, Address rvmFieldAddress) throws IllegalAccessException {
// Class library independent objects
if (jdkObject instanceof java.lang.Class) {
Object value = null;
String fieldName = null;
boolean fieldIsFinal = false;
if (rvmFieldName.equals("type")) {
// lets go over the common ones
if (jdkObject == java.lang.Boolean.TYPE) {
value = RVMType.BooleanType;
} else if (jdkObject == java.lang.Byte.TYPE) {
value = RVMType.ByteType;
} else if (jdkObject == java.lang.Character.TYPE) {
value = RVMType.CharType;
} else if (jdkObject == java.lang.Double.TYPE) {
value = RVMType.DoubleType;
} else if (jdkObject == java.lang.Float.TYPE) {
value = RVMType.FloatType;
} else if (jdkObject == java.lang.Integer.TYPE) {
value = RVMType.IntType;
} else if (jdkObject == java.lang.Long.TYPE) {
value = RVMType.LongType;
} else if (jdkObject == java.lang.Short.TYPE) {
value = RVMType.ShortType;
} else if (jdkObject == java.lang.Void.TYPE) {
value = RVMType.VoidType;
} else {
value = TypeReference.findOrCreate((Class<?>) jdkObject).peekType();
if (value == null) {
fail("Failed to populate Class.type for " + jdkObject);
}
}
fieldName = "type";
fieldIsFinal = true;
}
if ((fieldName != null) && (value != null)) {
if (verbosity.isAtLeast(DETAILED))
traceContext.push(value.getClass().getName(), "java.lang.Class", fieldName);
Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
bootImage.setNullAddressWord(rvmFieldAddress, true, true, false);
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, !fieldIsFinal);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, !fieldIsFinal);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else {
// Unknown Class field or value for type
return false;
}
} else if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("count")) && (rvmFieldType.isIntType())) {
// The fields "count" and "offset" are not guaranteed to be present in
// the String implementation in the class library (case in point: IcedTea 7).
// We don't need to do anything for "offset" (the default value of 0 is correct)
// but we need to ensure that "count" has the correct value.
bootImage.setFullWord(rvmFieldAddress, ((java.lang.String) jdkObject).length());
return true;
}
// Class library dependent fields
if (classLibrary == "harmony") {
if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("hashCode")) && (rvmFieldType.isIntType())) {
// Populate String's hashCode value
bootImage.setFullWord(rvmFieldAddress, jdkObject.hashCode());
return true;
} else if (jdkObject instanceof java.util.Locale) {
String fieldName;
Object value;
if (rvmFieldName.equals("countryCode")) {
value = ((java.util.Locale) jdkObject).getCountry();
fieldName = "countryCode";
} else if (rvmFieldName.equals("languageCode")) {
value = ((java.util.Locale) jdkObject).getLanguage();
fieldName = "languageCode";
} else if (rvmFieldName.equals("variantCode")) {
value = ((java.util.Locale) jdkObject).getVariant();
fieldName = "languageCode";
} else {
return false;
}
if (verbosity.isAtLeast(DETAILED))
traceContext.push(value.getClass().getName(), "java.util.Locale", fieldName);
Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
throw new Error("Failed to populate " + fieldName + " in Locale");
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else if ((jdkObject instanceof java.util.WeakHashMap) && (rvmFieldName.equals("referenceQueue"))) {
Object value = new java.lang.ref.ReferenceQueue();
if (verbosity.isAtLeast(DETAILED))
traceContext.push(value.getClass().getName(), "java.util.WeakHashMap", "referenceQueue");
Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
throw new Error("Failed to populate referenceQueue in WeakHashMap");
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else if (jdkObject instanceof java.lang.ref.ReferenceQueue) {
if (rvmFieldName.equals("firstReference")) {
return false;
} else {
throw new Error("Unknown field " + rvmFieldName + " in java.lang.ref.ReferenceQueue");
}
} else if (jdkObject instanceof java.lang.reflect.Constructor) {
Constructor<?> cons = (Constructor<?>) jdkObject;
if (rvmFieldName.equals("vmConstructor")) {
// fill in this RVMMethod field
String typeName = "L" + cons.getDeclaringClass().getName().replace('.', '/') + ";";
RVMType type = TypeReference.findOrCreate(typeName).peekType();
if (type == null) {
throw new Error("Failed to find type for Constructor.constructor: " + cons + " " + typeName);
}
final RVMClass klass = type.asClass();
Class<?>[] consParams = cons.getParameterTypes();
RVMMethod constructor = null;
loop_over_all_constructors: for (RVMMethod vmCons : klass.getConstructorMethods()) {
TypeReference[] vmConsParams = vmCons.getParameterTypes();
if (vmConsParams.length == consParams.length) {
for (int j = 0; j < vmConsParams.length; j++) {
if (!consParams[j].equals(vmConsParams[j].resolve().getClassForType())) {
continue loop_over_all_constructors;
}
}
constructor = vmCons;
break;
}
}
if (constructor == null) {
throw new Error("Failed to populate Constructor.cons for " + cons);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.push("vmConstructor", "java.lang.Constructor", "cons");
Address imageAddress = BootImageMap.findOrCreateEntry(constructor).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(constructor, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else if (rvmFieldName.equals("isAccessible")) {
// This field is inherited accesible flag is actually part of
// AccessibleObject
bootImage.setByte(rvmFieldAddress, cons.isAccessible() ? 1 : 0);
return true;
} else if (rvmFieldName.equals("invoker")) {
// Bytecode reflection field, can only be installed in running VM
bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
return true;
} else {
// Unknown Constructor field
throw new Error("Unknown field " + rvmFieldName + " in java.lang.reflect.Constructor");
}
} else {
// unknown field
return false;
}
} else if (classLibrary == "classpath") {
if ((jdkObject instanceof java.lang.String) && (rvmFieldName.equals("cachedHashCode")) && (rvmFieldType.isIntType())) {
// Populate String's cachedHashCode value
bootImage.setFullWord(rvmFieldAddress, jdkObject.hashCode());
return true;
} else if (jdkObject instanceof java.lang.reflect.Constructor) {
Constructor<?> cons = (Constructor<?>) jdkObject;
if (rvmFieldName.equals("cons")) {
// fill in this RVMMethod field
String typeName = "L" + cons.getDeclaringClass().getName().replace('.', '/') + ";";
RVMType type = TypeReference.findOrCreate(typeName).peekType();
if (type == null) {
throw new Error("Failed to find type for Constructor.constructor: " + cons + " " + typeName);
}
final RVMClass klass = type.asClass();
Class<?>[] consParams = cons.getParameterTypes();
RVMMethod constructor = null;
loop_over_all_constructors: for (RVMMethod vmCons : klass.getConstructorMethods()) {
TypeReference[] vmConsParams = vmCons.getParameterTypes();
if (vmConsParams.length == consParams.length) {
for (int j = 0; j < vmConsParams.length; j++) {
if (!consParams[j].equals(vmConsParams[j].resolve().getClassForType())) {
continue loop_over_all_constructors;
}
}
constructor = vmCons;
break;
}
}
if (constructor == null) {
throw new Error("Failed to populate Constructor.cons for " + cons);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.push("VMConstructor", "java.lang.Constructor", "cons");
Object vmcons = java.lang.reflect.JikesRVMSupport.createVMConstructor(constructor);
Address imageAddress = BootImageMap.findOrCreateEntry(vmcons).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
bootImage.setNullAddressWord(rvmFieldAddress, true, false, false);
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(vmcons, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else if (rvmFieldName.equals("flag")) {
// This field is inherited accesible flag is actually part of
// AccessibleObject
bootImage.setByte(rvmFieldAddress, cons.isAccessible() ? 1 : 0);
return true;
} else {
// Unknown Constructor field
return false;
}
} else if (jdkObject instanceof java.lang.ref.ReferenceQueue) {
if (rvmFieldName.equals("lock")) {
VM.sysWriteln("writing the lock field.");
Object value = new org.jikesrvm.scheduler.LightMonitor();
if (verbosity.isAtLeast(DETAILED))
traceContext.push(value.getClass().getName(), "java.lang.ref.ReferenceQueue", "lock");
Address imageAddress = BootImageMap.findOrCreateEntry(value).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
throw new Error("Failed to populate lock in ReferenceQueue");
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(value, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), true, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else if (rvmFieldName.equals("first")) {
return false;
} else {
throw new Error("Unknown field " + rvmFieldName + " in java.lang.ref.ReferenceQueue");
}
} else if (jdkObject instanceof java.util.BitSet) {
BitSet bs = (BitSet) jdkObject;
if (rvmFieldName.equals("bits")) {
// highest bit set in set
int max = 0;
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
max = i;
}
long[] bits = new long[(max + 63) / 64];
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
bits[i / 64] |= 1L << (i & 63);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.push("[J", "java.util.BitSet", "bits");
Address imageAddress = BootImageMap.findOrCreateEntry(bits).imageAddress;
if (imageAddress.EQ(OBJECT_NOT_PRESENT)) {
// object not part of bootimage: install null reference
if (verbosity.isAtLeast(DETAILED))
traceContext.traceObjectNotInBootImage();
bootImage.setNullAddressWord(rvmFieldAddress, true, false);
} else if (imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
imageAddress = copyToBootImage(bits, false, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), false, false);
} else {
if (verbosity.isAtLeast(ADDRESSES))
traceContext.traceObjectFoundThroughKnown();
bootImage.setAddressWord(rvmFieldAddress, imageAddress.toWord(), false, false);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
return true;
} else {
// Unknown BitSet field
return false;
}
} else {
// Unknown field
return false;
}
} else {
throw new Error("Unknown class library: \"" + classLibrary + "\"");
}
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method copyArrayToBootImage.
/**
* Write array to boot image
* @param arrayCount
* @param arrayImageAddress
* @param jdkObject
* @param jdkType
* @param rvmArrayType
* @param allocOnly
* @param overwriteAddress
* @param parentObject
* @param untraced
* @return
* @throws IllegalAccessException
*/
private static Address copyArrayToBootImage(int arrayCount, Address arrayImageAddress, Object jdkObject, Class<?> jdkType, RVMArray rvmArrayType, boolean allocOnly, Address overwriteAddress, Object parentObject, boolean untraced) throws IllegalAccessException {
if (verbosity.isAtLeast(DETAILED)) {
if (depth == DEPTH_CUTOFF)
say(SPACES.substring(0, depth + 1), "TOO DEEP: cutting off");
else if (depth < DEPTH_CUTOFF) {
String tab = SPACES.substring(0, depth + 1);
if (depth == 0 && jtocCount >= 0)
tab = tab + "jtoc #" + String.valueOf(jtocCount) + ": ";
int arraySize = rvmArrayType.getInstanceSize(arrayCount);
say(tab, "Copying array ", jdkType.getName(), " length=", String.valueOf(arrayCount), (arraySize >= LARGE_ARRAY_SIZE) ? " large object!!!" : "");
}
}
RVMType rvmElementType = rvmArrayType.getElementType();
// recurse on values that are references
if (rvmElementType.isPrimitiveType()) {
// array element is logical or numeric type
if (rvmElementType.equals(RVMType.BooleanType)) {
boolean[] values = (boolean[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i] ? 1 : 0);
} else if (rvmElementType.equals(RVMType.ByteType)) {
byte[] values = (byte[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setByte(arrayImageAddress.plus(i), values[i]);
} else if (rvmElementType.equals(RVMType.CharType)) {
char[] values = (char[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setHalfWord(arrayImageAddress.plus(i << LOG_BYTES_IN_CHAR), values[i]);
} else if (rvmElementType.equals(RVMType.ShortType)) {
short[] values = (short[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setHalfWord(arrayImageAddress.plus(i << LOG_BYTES_IN_SHORT), values[i]);
} else if (rvmElementType.equals(RVMType.IntType)) {
int[] values = (int[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setFullWord(arrayImageAddress.plus(i << LOG_BYTES_IN_INT), values[i]);
} else if (rvmElementType.equals(RVMType.LongType)) {
long[] values = (long[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setDoubleWord(arrayImageAddress.plus(i << LOG_BYTES_IN_LONG), values[i]);
} else if (rvmElementType.equals(RVMType.FloatType)) {
float[] values = (float[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setFullWord(arrayImageAddress.plus(i << LOG_BYTES_IN_FLOAT), Float.floatToIntBits(values[i]));
} else if (rvmElementType.equals(RVMType.DoubleType)) {
double[] values = (double[]) jdkObject;
for (int i = 0; i < arrayCount; ++i) bootImage.setDoubleWord(arrayImageAddress.plus(i << LOG_BYTES_IN_DOUBLE), Double.doubleToLongBits(values[i]));
} else {
fail("unexpected primitive array type: " + rvmArrayType);
}
} else {
// array element is reference type
boolean isTIB = parentObject instanceof TIB;
Object[] values = (Object[]) jdkObject;
Class<?> jdkClass = jdkObject.getClass();
if (!allocOnly) {
for (int i = 0; i < arrayCount; ++i) {
if (values[i] != null) {
if (verbosity.isAtLeast(DETAILED))
traceContext.push(values[i].getClass().getName(), jdkClass.getName(), i);
if (isTIB && values[i] instanceof Word) {
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), (Word) values[i], false, false);
} else if (isTIB && values[i] == LazyCompilationTrampoline.getInstructions()) {
Address codeAddress = arrayImageAddress.plus(((TIB) parentObject).lazyMethodInvokerTrampolineIndex() << LOG_BYTES_IN_ADDRESS);
bootImage.setAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), codeAddress.toWord(), false, false);
} else {
copyReferenceFieldToBootImage(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), values[i], jdkObject, !untraced, !untraced, null, null);
}
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
} else {
bootImage.setNullAddressWord(arrayImageAddress.plus(i << LOG_BYTES_IN_ADDRESS), !untraced, !untraced, true);
}
}
}
}
return arrayImageAddress;
}
Aggregations