use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class ClassLoader method resolveClass.
/**
* Forces a class to be linked (initialized). If the class has already been
* linked this operation has no effect.
*
* @param clazz
* The Class to link.
* @throws NullPointerException
* if clazz is null.
*/
protected final void resolveClass(Class<?> clazz) {
RVMType cls = JikesRVMSupport.getTypeForClass(clazz);
cls.resolve();
cls.instantiate();
cls.initialize();
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method writeAddressMap.
/**
* Write method address map for use with dbx debugger.
*
* @param fileName name of file to write the map to
*/
private static void writeAddressMap(String mapFileName) throws IOException {
if (verbosity.isAtLeast(SUMMARY))
say("writing ", mapFileName);
// Restore previously unnecessary Statics data structures
Statics.bootImageReportGeneration(staticsJunk);
FileOutputStream fos = new FileOutputStream(mapFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos, 128);
PrintStream out = new PrintStream(bos, false);
out.println("#! /bin/bash");
out.println("# This is a method address map, for use with the ``dbx'' debugger.");
out.println("# To sort by \"code\" address, type \"bash <name-of-this-file>\".");
out.println("# Bootimage data: " + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt() + bootImage.getDataSize()));
out.println("# Bootimage code: " + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt() + bootImage.getCodeSize()));
out.println("# Bootimage refs: " + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt() + bootImage.getRMapSize()));
out.println();
out.println("(/bin/grep 'code 0x' | /bin/sort -k 4.3,4) << EOF-EOF-EOF");
out.println();
out.println("JTOC Map");
out.println("--------");
out.println("slot offset category contents details");
out.println("---- ------ -------- -------- -------");
String pad = " ";
// Numeric JTOC fields
for (int jtocSlot = Statics.getLowestInUseSlot(); jtocSlot < Statics.middleOfTable; jtocSlot++) {
Offset jtocOff = Statics.slotAsOffset(jtocSlot);
String category;
String contents;
String details;
RVMField field = getRvmStaticField(jtocOff);
RVMField field2 = getRvmStaticField(jtocOff.plus(4));
boolean couldBeLongLiteral = Statics.isLongSizeLiteral(jtocSlot);
boolean couldBeIntLiteral = Statics.isIntSizeLiteral(jtocSlot);
if (couldBeLongLiteral && ((field == null) || (field2 == null))) {
if ((field == null) && (field2 == null)) {
category = "literal ";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L";
} else if ((field == null) && (field2 != null)) {
category = "literal/field";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L / " + field2.toString();
} else if ((field != null) && (field2 == null)) {
category = "literal/field";
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
details = lval + "L / " + field.toString();
} else {
throw new Error("Unreachable");
}
jtocSlot++;
} else if (couldBeIntLiteral) {
if (field != null) {
category = "literal/field";
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
details = Integer.toString(ival) + " / " + field.toString();
} else {
category = "literal ";
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
details = Integer.toString(ival);
}
} else {
if (field != null) {
category = "field ";
details = field.toString();
TypeReference type = field.getType();
if (type.isIntLikeType()) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
} else if (type.isLongType()) {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
jtocSlot++;
} else if (type.isFloatType()) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Float.toString(Float.intBitsToFloat(ival)) + pad;
} else if (type.isDoubleType()) {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Double.toString(Double.longBitsToDouble(lval)) + pad;
jtocSlot++;
} else if (type.isWordLikeType()) {
if (VM.BuildFor32Addr) {
int ival = Statics.getSlotContentsAsInt(jtocOff);
contents = Services.intAsHexString(ival) + pad;
} else {
long lval = Statics.getSlotContentsAsLong(jtocOff);
contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
jtocSlot++;
}
} else {
// Unknown?
int ival = Statics.getSlotContentsAsInt(jtocOff);
category = "<? - field> ";
details = "<? - " + field.toString() + ">";
contents = Services.intAsHexString(ival) + pad;
}
} else {
// Unknown?
int ival = Statics.getSlotContentsAsInt(jtocOff);
category = "<?> ";
details = "<?>";
contents = Services.intAsHexString(ival) + pad;
}
}
out.println((jtocSlot + " ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + " " + contents + " " + details);
}
// Reference JTOC fields
for (int jtocSlot = Statics.middleOfTable, n = Statics.getHighestInUseSlot(); jtocSlot <= n; jtocSlot += Statics.getReferenceSlotSize()) {
Offset jtocOff = Statics.slotAsOffset(jtocSlot);
Object obj = BootImageMap.getObject(getIVal(jtocOff));
String category;
String details;
String contents = Services.addressAsHexString(getReferenceAddr(jtocOff, false)) + pad;
RVMField field = getRvmStaticField(jtocOff);
if (Statics.isReferenceLiteral(jtocSlot)) {
if (field != null) {
category = "literal/field";
} else {
category = "literal ";
}
if (obj == null) {
details = "(null)";
} else if (obj instanceof String) {
details = "\"" + obj + "\"";
} else if (obj instanceof Class) {
details = obj.toString();
;
} else if (obj instanceof TIB) {
category = "literal tib ";
RVMType type = ((TIB) obj).getType();
details = (type == null) ? "?" : type.toString();
} else {
details = "object " + obj.getClass();
}
if (field != null) {
details += " / " + field.toString();
}
} else if (field != null) {
category = "field ";
details = field.toString();
} else if (obj instanceof TIB) {
// TIBs confuse the statics as their backing is written into the boot image
category = "tib ";
RVMType type = ((TIB) obj).getType();
details = (type == null) ? "?" : type.toString();
} else {
category = "unknown ";
if (obj instanceof String) {
details = "\"" + obj + "\"";
} else if (obj instanceof Class) {
details = obj.toString();
} else {
CompiledMethod m = findMethodOfCode(obj);
if (m != null) {
category = "code ";
details = m.getMethod().toString();
} else if (obj != null) {
details = "<?> - unrecognized field or literal of type " + obj.getClass();
} else {
details = "<?>";
}
}
}
out.println((jtocSlot + " ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + " " + contents + " " + details);
}
out.println();
out.println("Method Map");
out.println("----------");
out.println(" address method");
out.println(" ------- ------");
out.println();
for (int i = 0; i < CompiledMethods.numCompiledMethods(); ++i) {
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethodUnchecked(i);
if (compiledMethod != null) {
RVMMethod m = compiledMethod.getMethod();
if (m != null && compiledMethod.isCompiled()) {
CodeArray instructions = compiledMethod.getEntryCodeArray();
Address code = BootImageMap.getImageAddress(instructions.getBacking(), true);
out.println(". . code " + Services.addressAsHexString(code) + " " + compiledMethod.getMethod());
}
}
}
// Extra information on the layout of objects in the boot image
if (false) {
out.println();
out.println("Object Map");
out.println("----------");
out.println(" address type");
out.println(" ------- ------");
out.println();
SortedSet<BootImageMap.Entry> set = new TreeSet<BootImageMap.Entry>(new Comparator<BootImageMap.Entry>() {
@Override
public int compare(BootImageMap.Entry a, BootImageMap.Entry b) {
return Integer.valueOf(a.imageAddress.toInt()).compareTo(b.imageAddress.toInt());
}
});
for (Enumeration<BootImageMap.Entry> e = BootImageMap.elements(); e.hasMoreElements(); ) {
BootImageMap.Entry entry = e.nextElement();
set.add(entry);
}
for (Iterator<BootImageMap.Entry> i = set.iterator(); i.hasNext(); ) {
BootImageMap.Entry entry = i.next();
Address data = entry.imageAddress;
out.println(". . data " + Services.addressAsHexString(data) + " " + entry.jdkObject.getClass());
}
}
out.println();
out.println("EOF-EOF-EOF");
out.flush();
out.close();
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method spaceReport.
/**
* Print a report of space usage in the boot image.
*/
public static void spaceReport() {
RVMType[] tempTypes = new RVMType[RVMType.numTypes() - FIRST_TYPE_DICTIONARY_INDEX];
for (int i = FIRST_TYPE_DICTIONARY_INDEX; i < RVMType.numTypes(); ++i) tempTypes[i - FIRST_TYPE_DICTIONARY_INDEX] = RVMType.getType(i);
Arrays.sort(tempTypes, new TypeComparator<RVMType>());
int totalCount = 0, totalBytes = 0;
for (RVMType type : tempTypes) {
if (type == null)
continue;
DemographicInformation info = demographicData.get(type);
if (info == null)
continue;
totalCount += info.count;
totalBytes += info.size;
}
VM.sysWriteln();
VM.sysWriteln("Boot image space report:");
VM.sysWriteln("------------------------------------------------------------------------------------------");
VM.sysWriteField(60, "TOTAL");
VM.sysWriteField(15, totalCount);
VM.sysWriteField(15, totalBytes);
VM.sysWriteln();
VM.sysWriteln();
VM.sysWriteln("Compiled methods space report:");
VM.sysWriteln("------------------------------------------------------------------------------------------");
CompiledMethods.spaceReport();
VM.sysWriteln("------------------------------------------------------------------------------------------");
VM.sysWriteln();
VM.sysWriteln("Boot image space usage by types:");
VM.sysWriteln("Type Count Bytes");
VM.sysWriteln("------------------------------------------------------------------------------------------");
VM.sysWriteField(60, "TOTAL");
VM.sysWriteField(15, totalCount);
VM.sysWriteField(15, totalBytes);
VM.sysWriteln();
for (RVMType type : tempTypes) {
if (type == null)
continue;
DemographicInformation info = demographicData.get(type);
if (info == null)
continue;
if (info.count > 0) {
VM.sysWriteField(60, type.toString());
VM.sysWriteField(15, info.count);
VM.sysWriteField(15, info.size);
VM.sysWriteln();
}
}
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class BootImageWriter method main.
/**
* Main.
* @param args command line arguments
*/
public static void main(String[] args) {
String logFile = null;
String bootImageCodeName = null;
String bootImageDataName = null;
String bootImageRMapName = null;
String bootImageMapName = null;
Vector<String> bootImageTypeNames = null;
String bootImageTypeNamesFile = null;
String[] bootImageCompilerArgs = {};
//
// This may look useless, but it is not: it is a kludge to prevent
// forName blowing up. By forcing the system to load some classes
// now, we ensure that forName does not cause security violations by
// trying to load into java.util later.
//
java.util.HashMap<Object, Class<?>> x = new java.util.HashMap<Object, Class<?>>();
x.put(x, x.getClass());
sillyhack = x;
//
for (int i = 0; i < args.length; ++i) {
// name of class library
if (args[i].equals("-classlib")) {
if (++i >= args.length)
fail("argument syntax error: Got a -classlib flag without a following class library name");
classLibrary = args[i].toLowerCase().intern();
continue;
}
// name of code image file
if (args[i].equals("-oc")) {
if (++i >= args.length)
fail("argument syntax error: Got a -oc flag without a following code image file name");
bootImageCodeName = args[i];
continue;
}
// name of data image file
if (args[i].equals("-od")) {
if (++i >= args.length)
fail("argument syntax error: Got a -od flag without a following data image file name");
bootImageDataName = args[i];
continue;
}
// name of ref map image file
if (args[i].equals("-or")) {
if (++i >= args.length)
fail("argument syntax error: Got a -or flag without a following ref map file name");
bootImageRMapName = args[i];
continue;
}
// name of map file
if (args[i].equals("-m")) {
if (++i >= args.length)
fail("argument syntax error: Got a -m flag without a following bootImageMap file name");
bootImageMapName = args[i];
continue;
}
// image code start address
if (args[i].equals("-ca")) {
if (++i >= args.length)
fail("argument syntax error: Got a -ca flag without a following image address");
bootImageCodeAddress = decodeAddress(args[i]);
continue;
}
// image data start address
if (args[i].equals("-da")) {
if (++i >= args.length)
fail("argument syntax error: Got a -da flag without a following image address");
bootImageDataAddress = decodeAddress(args[i]);
continue;
}
// image ref map start address
if (args[i].equals("-ra")) {
if (++i >= args.length)
fail("argument syntax error: Got a -ra flag without a following image address");
bootImageRMapAddress = decodeAddress(args[i]);
continue;
}
// file containing names of types to be placed into bootimage
if (args[i].equals("-n")) {
if (++i >= args.length)
fail("argument syntax error: Got a -n flag without a following file name");
if (bootImageTypeNamesFile != null)
fail("argument syntax error: We've already read in the bootImageTypeNames from" + bootImageTypeNamesFile + "; just got another -n argument" + " telling us to read them from " + args[i]);
bootImageTypeNamesFile = args[i];
continue;
}
// bootimage compiler argument
if (args[i].startsWith("-X:bc:")) {
String[] nbca = new String[bootImageCompilerArgs.length + 1];
for (int j = 0; j < bootImageCompilerArgs.length; j++) {
nbca[j] = bootImageCompilerArgs[j];
}
nbca[nbca.length - 1] = args[i].substring(6);
bootImageCompilerArgs = nbca;
say("compiler arg: ", bootImageCompilerArgs[nbca.length - 1]);
continue;
}
// places where rvm components live, at build time
if (args[i].equals("-classpath")) {
if (++i >= args.length)
fail("argument syntax error: Got a -classpath flag without a following classpath for build-time RVM components");
bootImageRepositoriesAtBuildTime = args[i];
continue;
}
// places where rvm components live, at execution time
if (args[i].equals("-xclasspath")) {
if (++i >= args.length)
fail("argument syntax error: Got an -xclasspath flag without a following execution-time classpath for RVM components");
bootImageRepositoriesAtExecutionTime = args[i];
continue;
}
// generate trace messages while writing bootimage (for debugging)
if (args[i].equals("-trace")) {
verbosity = verbosity.increaseBy(1);
continue;
}
// generate info by type
if (args[i].equals("-demographics")) {
demographics = true;
continue;
}
// numThreads
if (args[i].startsWith("-numThreads=")) {
int desiredThreadCount = Integer.parseInt(args[i].substring(12));
if (desiredThreadCount < 0) {
fail("numThreads must be a non-negative number, value supplied: " + desiredThreadCount);
}
// already does this so there's nothing to do here.
if (desiredThreadCount == 0)
continue;
// use the explicit value provided by the user
numThreads = desiredThreadCount;
continue;
}
// profile
if (args[i].equals("-profile")) {
profile = true;
continue;
}
// log
if (args[i].equals("-log")) {
if (++i >= args.length)
fail("argument syntax error: Got a -log flag without a following argument for the log file");
logFile = args[i];
continue;
}
// generate detailed information about traversed objects (for debugging)
if (args[i].equals("-detailed")) {
verbosity = verbosity.increaseBy(2);
continue;
}
// write words to bootimage in little endian format
if (args[i].equals("-littleEndian")) {
littleEndian = true;
continue;
}
fail("unrecognized command line argument: " + args[i]);
}
if (verbosity.isAtLeast(Verbosity.DETAILED))
traversed = new Hashtable<Object, Integer>(500);
//
if (bootImageCodeName == null)
fail("please specify \"-oc <boot-image-code-filename>\"");
if (bootImageDataName == null)
fail("please specify \"-od <boot-image-data-filename>\"");
if (bootImageRMapName == null)
fail("please specify \"-or <boot-image-rmap-filename>\"");
if (bootImageTypeNamesFile == null)
fail("please specify \"-n <boot-image-type-names-filename>\"");
if (bootImageRepositoriesAtBuildTime == null)
fail("please specify \"-classpath <path>\"");
if (bootImageRepositoriesAtExecutionTime == null)
bootImageRepositoriesAtExecutionTime = bootImageRepositoriesAtBuildTime;
if (bootImageDataAddress.isZero())
fail("please specify boot-image address with \"-da <addr>\"");
if (!(bootImageDataAddress.toWord().and(Word.fromIntZeroExtend(0x00FFFFFF)).isZero()))
fail("please specify a boot-image address that is a multiple of 0x01000000");
if (bootImageCodeAddress.isZero())
fail("please specify boot-image address with \"-ca <addr>\"");
if (!(bootImageCodeAddress.toWord().and(Word.fromIntZeroExtend(0x00FFFFFF)).isZero()))
fail("please specify a boot-image address that is a multiple of 0x01000000");
if (bootImageRMapAddress.isZero())
fail("please specify boot-image address with \"-ra <addr>\"");
if (!(bootImageRMapAddress.toWord().and(Word.fromIntZeroExtend(0x00FFFFFF)).isZero()))
fail("please specify a boot-image address that is a multiple of 0x01000000");
// Redirect the log file
if (logFile != null) {
try {
PrintStream logFileStream = new PrintStream(logFile);
System.setOut(logFileStream);
System.setErr(logFileStream);
} catch (IOException ex) {
fail("Failed to open log file for redirecting: " + ex.getMessage());
}
}
//
try {
bootImage = new BootImage(littleEndian, verbosity.isAtLeast(Verbosity.SUMMARY), bootImageCodeName, bootImageDataName, bootImageRMapName);
} catch (IOException e) {
fail("unable to write bootImage: " + e);
}
//
// Install handler that intercepts all object address references made by
// xxx classes executed on host jdk and substitutes a value that can be
// fixed up later when those objects are copied from host jdk to bootimage.
//
enableObjectAddressRemapper();
//
if (verbosity.isAtLeast(SUMMARY))
say("starting up");
// try {
VM.initForBootImageWriter(bootImageRepositoriesAtBuildTime, bootImageCompilerArgs);
// } catch (Exception e) {
// fail("unable to initialize VM: "+e);
// }
//
// Create (in host jdk address space) the rvm objects that will be
// needed at run time to execute enough of the virtual machine
// to dynamically load and compile the remainder of itself.
//
long startTime = 0;
long stopTime = 0;
if (profile)
startTime = System.currentTimeMillis();
try {
bootImageTypeNames = readTypeNames(bootImageTypeNamesFile);
} catch (IOException e) {
fail("unable to read the type names from " + bootImageTypeNamesFile + ": " + e);
}
if (profile) {
stopTime = System.currentTimeMillis();
System.out.println("PROF: readingTypeNames " + (stopTime - startTime) + " ms");
}
if (profile)
startTime = System.currentTimeMillis();
try {
createBootImageObjects(bootImageTypeNames, bootImageTypeNamesFile);
} catch (Exception e) {
e.printStackTrace(System.out);
fail("unable to create objects: " + e);
}
if (profile) {
stopTime = System.currentTimeMillis();
System.out.println("PROF: createBootImageObjects " + (stopTime - startTime) + " ms");
}
//
// No further bootimage object references should get generated.
// If they are, they'll be assigned an objectId of "-1" (see Magic)
// and will manifest themselves as an array subscript out of bounds
// error when BootImageMap attempts to look up the object references.
//
disableObjectAddressRemapper();
// //////////////////////////////////////////////////
// Copy rvm objects from host jdk into bootimage.
// //////////////////////////////////////////////////
VM.writingImage = true;
if (verbosity.isAtLeast(SUMMARY))
say("Memory available: ", String.valueOf(Runtime.getRuntime().freeMemory()), " bytes out of ", String.valueOf(Runtime.getRuntime().totalMemory()), " bytes");
if (profile)
startTime = System.currentTimeMillis();
//
if (verbosity.isAtLeast(SUMMARY))
say("copying boot record");
BootRecord bootRecord = BootRecord.the_boot_record;
Address bootRecordImageAddress = Address.zero();
try {
// copy just the boot record
bootRecordImageAddress = copyToBootImage(bootRecord, true, Address.max(), null, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (bootRecordImageAddress.EQ(OBJECT_NOT_PRESENT)) {
fail("can't copy boot record");
}
} catch (IllegalAccessException e) {
fail("can't copy boot record: " + e);
}
//
if (verbosity.isAtLeast(SUMMARY))
say("copying jtoc");
// Pointer to middle of JTOC
Address jtocImageAddress = Address.max();
try {
if (VM.BuildForIA32) {
// Force 16byte alignment of the JTOC on Intel
int[] slots = Statics.getSlotsAsIntArray();
jtocImageAddress = bootImage.allocateArray(RVMArray.IntArray, slots.length, false, 0, 16, AlignmentEncoding.ALIGN_CODE_NONE);
BootImageMap.Entry jtocEntry = BootImageMap.findOrCreateEntry(slots);
jtocEntry.imageAddress = jtocImageAddress;
}
jtocImageAddress = copyToBootImage(Statics.getSlotsAsIntArray(), false, jtocImageAddress, null, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (jtocImageAddress.EQ(OBJECT_NOT_PRESENT)) {
fail("can't copy jtoc");
}
} catch (IllegalAccessException e) {
fail("can't copy jtoc: " + e);
}
Address jtocPtr = jtocImageAddress.plus(Statics.middleOfTable << LOG_BYTES_IN_INT);
if (jtocPtr.NE(bootRecord.tocRegister))
fail("mismatch in JTOC placement " + Services.addressAsHexString(jtocPtr) + " != " + Services.addressAsHexString(bootRecord.tocRegister));
//
if (verbosity.isAtLeast(SUMMARY))
say("copying statics");
try {
int refSlotSize = Statics.getReferenceSlotSize();
for (int i = Statics.middleOfTable + refSlotSize, n = Statics.getHighestInUseSlot(); i <= n; i += refSlotSize) {
if (!Statics.isReference(i)) {
throw new Error("Static " + i + " of " + n + " isn't reference");
}
// for diagnostic
jtocCount = i;
Offset jtocOff = Statics.slotAsOffset(i);
int objCookie;
if (VM.BuildFor32Addr)
objCookie = Statics.getSlotContentsAsInt(jtocOff);
else
objCookie = (int) Statics.getSlotContentsAsLong(jtocOff);
// if (verbose.isAtLeast(ADDRESSES))
// say(" jtoc[", String.valueOf(i), "] = ", String.valueOf(objCookie));
Object jdkObject = BootImageMap.getObject(objCookie);
if (jdkObject == null)
continue;
if (verbosity.isAtLeast(DETAILED))
traceContext.push(jdkObject.getClass().getName(), getRvmStaticField(jtocOff) + "");
copyReferenceFieldToBootImage(jtocPtr.plus(jtocOff), jdkObject, Statics.getSlotsAsIntArray(), false, false, null, null);
if (verbosity.isAtLeast(DETAILED))
traceContext.pop();
}
// Copy entries that are in the pending queue
processPendingEntries();
// Find and copy unallocated entries
for (int i = 0; i < BootImageMap.objectIdToEntry.size(); i++) {
BootImageMap.Entry mapEntry = BootImageMap.objectIdToEntry.get(i);
if (mapEntry.imageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
mapEntry.imageAddress = copyToBootImage(mapEntry.jdkObject, false, Address.max(), null, false, AlignmentEncoding.ALIGN_CODE_NONE);
fixupLinkAddresses(mapEntry);
}
}
} catch (IllegalAccessException e) {
fail("unable to copy statics: " + e);
}
jtocCount = -1;
if (profile) {
stopTime = System.currentTimeMillis();
System.out.println("PROF: filling bootimage byte[] " + (stopTime - startTime) + " ms");
}
//
if (verbosity.isAtLeast(SUMMARY))
say("updating boot record");
byte[] startupStack = startupThread.getStack();
CodeArray startupCode = Entrypoints.bootMethod.getCurrentEntryCodeArray();
bootRecord.spRegister = BootImageMap.getImageAddress(startupStack, true).plus(startupStack.length);
bootRecord.ipRegister = BootImageMap.getImageAddress(startupCode.getBacking(), true);
bootRecord.bootThreadOffset = Entrypoints.bootThreadField.getOffset();
bootRecord.bootImageDataStart = bootImageDataAddress;
bootRecord.bootImageDataEnd = bootImageDataAddress.plus(bootImage.getDataSize());
bootRecord.bootImageCodeStart = bootImageCodeAddress;
bootRecord.bootImageCodeEnd = bootImageCodeAddress.plus(bootImage.getCodeSize());
bootRecord.bootImageRMapStart = bootImageRMapAddress;
bootRecord.bootImageRMapEnd = bootImageRMapAddress.plus(bootImage.getRMapSize());
//
if (verbosity.isAtLeast(SUMMARY))
say("re-copying boot record (and its TIB)");
try {
Address newBootRecordImageAddress = copyToBootImage(bootRecord, false, bootRecordImageAddress, null, false, AlignmentEncoding.ALIGN_CODE_NONE);
if (!newBootRecordImageAddress.EQ(bootRecordImageAddress)) {
VM.sysWriteln("bootRecordImageOffset = ", bootRecordImageAddress);
VM.sysWriteln("newBootRecordImageOffset = ", newBootRecordImageAddress);
if (VM.VerifyAssertions) {
VM._assert(newBootRecordImageAddress.EQ(bootRecordImageAddress));
}
}
// Make sure pending entries are fully written out
processPendingEntries();
} catch (IllegalAccessException e) {
fail("unable to update boot record: " + e);
}
if (VM.BuildWithGCTrace) {
/* Set the values in fields updated during the build process */
Offset prevAddrOffset = Entrypoints.tracePrevAddressField.getOffset();
bootImage.setAddressWord(jtocPtr.plus(prevAddrOffset), MiscHeader.getBootImageLink().toWord(), false, false);
Offset oIDOffset = Entrypoints.traceOIDField.getOffset();
bootImage.setAddressWord(jtocPtr.plus(oIDOffset), MiscHeader.getOID(), false, false);
}
//
if (profile)
startTime = System.currentTimeMillis();
try {
bootImage.write();
} catch (IOException e) {
fail("unable to write bootImage: " + e);
}
if (profile) {
stopTime = System.currentTimeMillis();
System.out.println("PROF: writing RVM.map " + (stopTime - startTime) + " ms");
}
//
if (demographics) {
spaceReport();
}
//
if (verbosity.isAtLeast(DETAILED)) {
for (int i = FIRST_TYPE_DICTIONARY_INDEX; i < RVMType.numTypes(); ++i) {
RVMType type = RVMType.getType(i);
if (type == null)
continue;
if (!type.isResolved()) {
say("type referenced but not resolved: ", type.toString());
} else if (!type.isInstantiated()) {
say("type referenced but not instantiated: ", type.toString());
} else if (!type.isInitialized()) {
say("type referenced but not initialized: ", type.toString());
}
}
}
//
try {
if (bootImageMapName != null)
writeAddressMap(bootImageMapName);
} catch (IOException e) {
fail("unable to write address map: " + e);
}
if (verbosity.isAtLeast(SUMMARY))
say("done");
}
use of org.jikesrvm.classloader.RVMType in project JikesRVM by JikesRVM.
the class CompilationOrder method fixUpMissingSuperClasses.
/**
* Makes sure that all superclasses are instantiated by detecting missed classes.
* <p>
* If the code just called {@code instantiate()} on every class, all superclasses would
* be compiled automatically. However, the code is explicitly managing superclasses and
* so must take care to enumerate all superclasses.
*/
public void fixUpMissingSuperClasses() {
int round = 1;
while (!missingSuperclasses.isEmpty()) {
if (DEBUG) {
say("[CompilationOrder] fixing up superclasses, round " + round);
say("[CompilationOrder] fixing up superclasses, remaining classes at start " + missingSuperclasses);
}
// Everything that's on the queue is not missing and won't need to be processed
HashSet<RVMType> dequeTypes = new HashSet<RVMType>(compilationDeque);
missingSuperclasses.removeAll(dequeTypes);
// Everything that will be initialized when its superclass is compiled won't be
// missing either
HashSet<RVMType> willBeAddedToDeque = new HashSet<RVMType>();
for (Collection<RVMType> c : waitingForSuperclassToInitialize.values()) {
willBeAddedToDeque.addAll(c);
}
missingSuperclasses.removeAll(willBeAddedToDeque);
// The rest will need to be processed in order to fix up missing superclasses
HashSet<RVMType> toAddAsTypes = new HashSet<RVMType>(missingSuperclasses);
for (RVMType type : toAddAsTypes) {
addType(type);
}
round++;
}
assertThatCountOfWorkersMatchesCountOfClasses();
if (DEBUG) {
say("[CompilationOrder] fixing up superclasses finished!");
}
}
Aggregations