Search in sources :

Example 6 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class DynamicCallGraphOrganizer method thresholdReached.

/**
 * Process contents of buffer:
 *    add call graph edges and increment their weights.
 */
@Override
void thresholdReached() {
    if (DEBUG)
        VM.sysWriteln("DCG_Organizer.thresholdReached()");
    for (int i = 0; i < bufferSize; i = i + 3) {
        int calleeCMID = 0;
        // FIXME: This is necessary but hacky and may not even be correct.
        while (calleeCMID == 0) {
            calleeCMID = buffer[i + 0];
        }
        CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(calleeCMID);
        if (compiledMethod == null)
            continue;
        RVMMethod callee = compiledMethod.getMethod();
        if (callee.isRuntimeServiceMethod()) {
            if (DEBUG)
                VM.sysWrite("Skipping sample with runtime service callee");
            continue;
        }
        int callerCMID = buffer[i + 1];
        compiledMethod = CompiledMethods.getCompiledMethod(callerCMID);
        if (compiledMethod == null)
            continue;
        RVMMethod stackFrameCaller = compiledMethod.getMethod();
        int MCOff = buffer[i + 2];
        Offset MCOffset = Offset.fromIntSignExtend(buffer[i + 2]);
        int bytecodeIndex = -1;
        RVMMethod caller = null;
        switch(compiledMethod.getCompilerType()) {
            case CompiledMethod.TRAP:
            case CompiledMethod.JNI:
                if (DEBUG)
                    VM.sysWrite("Skipping sample with TRAP/JNI caller");
                continue;
            case CompiledMethod.BASELINE:
                {
                    BaselineCompiledMethod baseCompiledMethod = (BaselineCompiledMethod) compiledMethod;
                    // note: the following call expects the offset in INSTRUCTIONS!
                    bytecodeIndex = baseCompiledMethod.findBytecodeIndexForInstruction(MCOffset);
                    caller = stackFrameCaller;
                }
                break;
            case CompiledMethod.OPT:
                {
                    OptCompiledMethod optCompiledMethod = (OptCompiledMethod) compiledMethod;
                    OptMachineCodeMap mc_map = optCompiledMethod.getMCMap();
                    try {
                        bytecodeIndex = mc_map.getBytecodeIndexForMCOffset(MCOffset);
                        if (bytecodeIndex == -1) {
                            // so skip the sample.
                            if (DEBUG) {
                                VM.sysWrite("  *** SKIP SAMPLE ", stackFrameCaller.toString());
                                VM.sysWrite("@", compiledMethod.toString());
                                VM.sysWrite(" at MC offset ", MCOff);
                                VM.sysWrite(" calling ", callee.toString());
                                VM.sysWriteln(" due to invalid bytecodeIndex");
                            }
                            // skip sample.
                            continue;
                        }
                    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
                        VM.sysWrite("  ***ERROR: getBytecodeIndexForMCOffset(", MCOffset);
                        VM.sysWriteln(") ArrayIndexOutOfBounds!");
                        e.printStackTrace();
                        if (VM.ErrorsFatal)
                            VM.sysFail("Exception in AI organizer.");
                        caller = stackFrameCaller;
                        // skip sample
                        continue;
                    } catch (OptimizingCompilerException e) {
                        VM.sysWrite("***Error: SKIP SAMPLE: can't find bytecode index in OPT compiled " + stackFrameCaller + "@" + compiledMethod + " at MC offset ", MCOff);
                        VM.sysWriteln("!");
                        if (VM.ErrorsFatal)
                            VM.sysFail("Exception in AI organizer.");
                        // skip sample
                        continue;
                    }
                    try {
                        caller = mc_map.getMethodForMCOffset(MCOffset);
                    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
                        VM.sysWrite("  ***ERROR: getMethodForMCOffset(", MCOffset);
                        VM.sysWriteln(") ArrayIndexOutOfBounds!");
                        e.printStackTrace();
                        if (VM.ErrorsFatal)
                            VM.sysFail("Exception in AI organizer.");
                        caller = stackFrameCaller;
                        continue;
                    } catch (OptimizingCompilerException e) {
                        VM.sysWrite("***Error: SKIP SAMPLE: can't find caller in OPT compiled " + stackFrameCaller + "@" + compiledMethod + " at MC offset ", MCOff);
                        VM.sysWriteln("!");
                        if (VM.ErrorsFatal)
                            VM.sysFail("Exception in AI organizer.");
                        // skip sample
                        continue;
                    }
                    if (caller == null) {
                        VM.sysWrite("  ***ERROR: getMethodForMCOffset(", MCOffset);
                        VM.sysWriteln(") returned null!");
                        caller = stackFrameCaller;
                        // skip sample
                        continue;
                    }
                }
                break;
        }
        // increment the call graph edge, adding it if needed
        Controller.dcg.incrementEdge(caller, bytecodeIndex, callee);
    }
    if (thresholdReachedCount > 0) {
        thresholdReachedCount--;
    }
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) OptMachineCodeMap(org.jikesrvm.compilers.opt.runtimesupport.OptMachineCodeMap) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 7 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class BulkCompile method compileAllMethods.

/**
 * Compile all methods nominated in the compiler advice,
 * which should have been provided in a .ca advice file.<p>
 *
 * This method will be called at boot time (via notifyStartup())
 * if ENABLE_PRECOMPILE is true.  For replay compilation, this
 * method needs to be called explicitly from within the application
 * or benchmark harness. Typical usage in a benchmarking context
 * would be to call this method at the end of the first iteration
 * of the benchmark so that all/most classes were loaded, and
 * compilation could occur prior to the second iteration.
 */
public static void compileAllMethods() {
    if (!(Controller.options.ENABLE_BULK_COMPILE || Controller.options.ENABLE_PRECOMPILE)) {
        /* should not be here */
        VM.sysFail("Attempt to perform bulk compilation without setting either -X:aos:enable_bulk_compile=true or -X:aos:enable_precompile=true");
    }
    EdgeCounts.loadCountsFromFileIfAvailable(VM.EdgeCounterFile);
    CompilerAdvice.readCompilerAdvice();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln(Controller.options.ENABLE_PRECOMPILE ? "Start precompile" : "Start bulk compile");
    for (CompilerAdviceAttribute value : CompilerAdviceAttribute.values()) {
        if (value.getOptLevel() == -1) {
            if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                VM.sysWriteln("Skipping base method: ", value.toString());
            } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                VM.sysWrite(".");
            }
            continue;
        }
        ClassLoader cl = RVMClassLoader.findWorkableClassloader(value.getClassName());
        if (cl == null)
            continue;
        TypeReference tRef = TypeReference.findOrCreate(cl, value.getClassName());
        RVMClass cls = (RVMClass) tRef.peekType();
        if (cls != null) {
            // Ensure the class is properly loaded
            if (!cls.isInstantiated()) {
                if (!cls.isResolved()) {
                    if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                        VM.sysWriteln("Resolving class: ", cls.toString());
                    } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                        VM.sysWrite("R");
                    }
                    cls.resolve();
                }
                if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                    VM.sysWriteln("Instantiating class: ", cls.toString());
                } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                    VM.sysWrite("I");
                }
                cls.instantiate();
            }
            // Find the method
            RVMMethod method = cls.findDeclaredMethod(value.getMethodName(), value.getMethodSig());
            // If found, compile it
            if ((method != null) && !method.hasNoOptCompileAnnotation() && (method instanceof org.jikesrvm.classloader.NormalMethod)) {
                // if user's requirement is higher than advice
                if (value.getOptLevel() > Controller.options.DERIVED_MAX_OPT_LEVEL) {
                    if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                        VM.sysWrite("Replay advice overriden by default opt levels.  Wanted ");
                        VM.sysWrite(value.getOptLevel());
                        VM.sysWrite(", but Controller.options.DERIVED_MAX_OPT_LEVEL: ");
                        VM.sysWrite(Controller.options.DERIVED_MAX_OPT_LEVEL);
                        VM.sysWrite(" ");
                        VM.sysWriteln(value.toString());
                    } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                        VM.sysWrite(value.getOptLevel(), "!");
                    }
                    method.compile();
                } else {
                    CompilationPlan compPlan;
                    if (Controller.options.counters()) {
                        // for invocation counter, we only use one optimization level
                        compPlan = InvocationCounts.createCompilationPlan((NormalMethod) method);
                        AOSLogging.logger.recompilationStarted(compPlan);
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Bulk compiling for counters ");
                            VM.sysWriteln(value.toString());
                        }
                        RuntimeCompiler.recompileWithOpt(compPlan);
                        AOSLogging.logger.recompilationCompleted(compPlan);
                    } else if (Controller.options.sampling()) {
                        // Create our set of standard optimization plans.
                        compPlan = Controller.recompilationStrategy.createCompilationPlan((NormalMethod) method, value.getOptLevel(), null);
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Bulk compiling for sampling ");
                            VM.sysWriteln(value.toString());
                        }
                        if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                            VM.sysWrite(value.getOptLevel());
                        }
                        AOSLogging.logger.recompilationStarted(compPlan);
                        RuntimeCompiler.recompileWithOpt(compPlan);
                        AOSLogging.logger.recompilationCompleted(compPlan);
                    } else {
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Compiler advice file overridden ");
                            VM.sysWriteln(value.toString());
                        }
                        method.compile();
                    }
                }
            } else {
                if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                    VM.sysWrite("Replay failed for ");
                    VM.sysWrite(value.toString());
                    VM.sysWrite(" ");
                    VM.sysWriteln(cl.toString());
                } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                    VM.sysWrite("*");
                }
            }
        }
    }
    AOSLogging.logger.compileAllMethodsCompleted();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln("Recompilation complete");
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) NormalMethod(org.jikesrvm.classloader.NormalMethod) RVMClassLoader(org.jikesrvm.classloader.RVMClassLoader) CompilationPlan(org.jikesrvm.compilers.opt.driver.CompilationPlan) TypeReference(org.jikesrvm.classloader.TypeReference) CompilerAdviceAttribute(org.jikesrvm.adaptive.util.CompilerAdviceAttribute) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 8 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod 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 9 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class BuildJNIFunctionTable method buildTable.

/**
 * Construct the JNIFuntionTable.
 * This is not very efficient, but is done at bootImageWriting time,
 * so we just don't worry about it.
 */
public static FunctionTable buildTable() {
    String[] names = initNames();
    FunctionTable functions = FunctionTable.allocate(JNIFunctions.FUNCTIONCOUNT);
    RVMClass cls = TypeReference.JNIFunctions.peekType().asClass();
    if (VM.VerifyAssertions)
        VM._assert(cls.isInstantiated());
    for (RVMMethod mth : cls.getDeclaredMethods()) {
        String methodName = mth.getName().toString();
        int jniIndex = indexOf(names, methodName);
        if (jniIndex != -1) {
            functions.set(jniIndex, mth.getCurrentEntryCodeArray());
        }
    }
    return functions;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) FunctionTable(org.jikesrvm.jni.FunctionTable) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 10 with RVMMethod

use of org.jikesrvm.classloader.RVMMethod in project JikesRVM by JikesRVM.

the class FinalMIRExpansion method findOrCreateYieldpointBlock.

/**
 * Return a basic block holding the call to a runtime yield service.
 * Create a new basic block at the end of the code order if necessary.
 *
 * @param ir the governing IR
 * @param whereFrom is this yieldpoint from the PROLOGUE, EPILOGUE, or a
 * BACKEDGE?
 */
static BasicBlock findOrCreateYieldpointBlock(IR ir, int whereFrom) {
    RVMMethod meth = null;
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    Register zero = phys.getGPR(0);
    // state for creating the block
    if (whereFrom == RVMThread.PROLOGUE) {
        if (ir.MIRInfo.prologueYieldpointBlock != null) {
            return ir.MIRInfo.prologueYieldpointBlock;
        } else {
            meth = Entrypoints.optThreadSwitchFromPrologueMethod;
        }
    } else if (whereFrom == RVMThread.BACKEDGE) {
        if (ir.MIRInfo.backedgeYieldpointBlock != null) {
            return ir.MIRInfo.backedgeYieldpointBlock;
        } else {
            meth = Entrypoints.optThreadSwitchFromBackedgeMethod;
        }
    } else if (whereFrom == RVMThread.EPILOGUE) {
        if (ir.MIRInfo.epilogueYieldpointBlock != null) {
            return ir.MIRInfo.epilogueYieldpointBlock;
        } else {
            meth = Entrypoints.optThreadSwitchFromEpilogueMethod;
        }
    } else if (whereFrom == RVMThread.OSROPT) {
        if (ir.MIRInfo.osrYieldpointBlock != null) {
            return ir.MIRInfo.osrYieldpointBlock;
        } else {
            meth = Entrypoints.optThreadSwitchFromOsrOptMethod;
        }
    }
    // Not found.  create new basic block holding the requested yieldpoint
    // method
    BasicBlock result = new BasicBlock(-1, null, ir.cfg);
    ir.cfg.addLastInCodeOrder(result);
    Register JTOC = phys.getJTOC();
    Register CTR = phys.getCTR();
    Offset offset = meth.getOffset();
    if (fits(offset, 16)) {
        result.appendInstruction(MIR_Load.create(PPC_LAddr, A(zero), A(JTOC), IC(PPCMaskLower16(offset))));
    } else {
        // not implemented
        if (VM.VerifyAssertions)
            VM._assert(fits(offset, 32));
        result.appendInstruction(MIR_Binary.create(PPC_ADDIS, A(zero), A(JTOC), IC(PPCMaskUpper16(offset))));
        result.appendInstruction(MIR_Load.create(PPC_LAddr, A(zero), A(zero), IC(PPCMaskLower16(offset))));
    }
    result.appendInstruction(MIR_Move.create(PPC_MTSPR, A(CTR), A(zero)));
    result.appendInstruction(MIR_Branch.create(PPC_BCTR));
    // cache the create block and then return it
    if (whereFrom == RVMThread.PROLOGUE) {
        ir.MIRInfo.prologueYieldpointBlock = result;
    } else if (whereFrom == RVMThread.BACKEDGE) {
        ir.MIRInfo.backedgeYieldpointBlock = result;
    } else if (whereFrom == RVMThread.EPILOGUE) {
        ir.MIRInfo.epilogueYieldpointBlock = result;
    } else if (whereFrom == RVMThread.OSROPT) {
        ir.MIRInfo.osrYieldpointBlock = result;
    }
    return result;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Offset(org.vmmagic.unboxed.Offset)

Aggregations

RVMMethod (org.jikesrvm.classloader.RVMMethod)86 RVMClass (org.jikesrvm.classloader.RVMClass)29 TypeReference (org.jikesrvm.classloader.TypeReference)17 RVMType (org.jikesrvm.classloader.RVMType)15 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)14 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)13 Atom (org.jikesrvm.classloader.Atom)11 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)11 Offset (org.vmmagic.unboxed.Offset)11 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)10 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)10 Address (org.vmmagic.unboxed.Address)9 MethodReference (org.jikesrvm.classloader.MethodReference)8 NormalMethod (org.jikesrvm.classloader.NormalMethod)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 Method (java.lang.reflect.Method)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)7 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)7