Search in sources :

Example 1 with RVMType

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();
}
Also used : RVMType(org.jikesrvm.classloader.RVMType)

Example 2 with RVMType

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();
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) CodeArray(org.jikesrvm.compilers.common.CodeArray) TreeSet(java.util.TreeSet) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) BufferedOutputStream(java.io.BufferedOutputStream) PrintStream(java.io.PrintStream) TIB(org.jikesrvm.objectmodel.TIB) Offset(org.vmmagic.unboxed.Offset) RVMMethod(org.jikesrvm.classloader.RVMMethod) FileOutputStream(java.io.FileOutputStream) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 3 with RVMType

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();
        }
    }
}
Also used : RVMType(org.jikesrvm.classloader.RVMType)

Example 4 with RVMType

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");
}
Also used : Address(org.vmmagic.unboxed.Address) HashMap(java.util.HashMap) RVMType(org.jikesrvm.classloader.RVMType) CodeArray(org.jikesrvm.compilers.common.CodeArray) PrintStream(java.io.PrintStream) Hashtable(java.util.Hashtable) IOException(java.io.IOException) IOException(java.io.IOException) Offset(org.vmmagic.unboxed.Offset) BootRecord(org.jikesrvm.runtime.BootRecord) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 5 with RVMType

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!");
    }
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) HashSet(java.util.HashSet)

Aggregations

RVMType (org.jikesrvm.classloader.RVMType)77 RVMClass (org.jikesrvm.classloader.RVMClass)23 TypeReference (org.jikesrvm.classloader.TypeReference)18 Address (org.vmmagic.unboxed.Address)16 RVMMethod (org.jikesrvm.classloader.RVMMethod)15 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)15 TIB (org.jikesrvm.objectmodel.TIB)13 Entrypoint (org.vmmagic.pragma.Entrypoint)13 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)12 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)12 RVMArray (org.jikesrvm.classloader.RVMArray)11 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)10 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)10 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)10 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)9 Offset (org.vmmagic.unboxed.Offset)8