Search in sources :

Example 1 with NormalMethod

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

the class OnStackReplacementEvent method process.

/**
 * This function will generate a controller plan and
 * inserted in the recompilation queue.
 */
@Override
public void process() {
    CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(CMID);
    NormalMethod todoMethod = (NormalMethod) compiledMethod.getMethod();
    double priority;
    OptOptions options;
    OptimizationPlanElement[] optimizationPlan;
    ControllerPlan oldPlan = ControllerMemory.findLatestPlan(todoMethod);
    if (oldPlan != null) {
        CompilationPlan oldCompPlan = oldPlan.getCompPlan();
        priority = oldPlan.getPriority();
        options = oldCompPlan.options;
        optimizationPlan = oldCompPlan.optimizationPlan;
    } else {
        priority = 5.0;
        options = (OptOptions) RuntimeCompiler.options;
        optimizationPlan = (OptimizationPlanElement[]) RuntimeCompiler.optimizationPlan;
    }
    CompilationPlan compPlan = new CompilationPlan(todoMethod, optimizationPlan, null, options);
    OnStackReplacementPlan plan = new OnStackReplacementPlan(this.suspendedThread, compPlan, this.CMID, this.whereFrom, this.tsFromFPoff, this.ypTakenFPoff, priority);
    Controller.compilationQueue.insert(priority, plan);
    AOSLogging.logger.logOsrEvent("OSR inserts compilation plan successfully!");
    // do not hold the reference anymore.
    suspendedThread = null;
    CMID = 0;
}
Also used : NormalMethod(org.jikesrvm.classloader.NormalMethod) OptimizationPlanElement(org.jikesrvm.compilers.opt.driver.OptimizationPlanElement) CompilationPlan(org.jikesrvm.compilers.opt.driver.CompilationPlan) OptOptions(org.jikesrvm.compilers.opt.OptOptions) ControllerPlan(org.jikesrvm.adaptive.controller.ControllerPlan) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod)

Example 2 with NormalMethod

use of org.jikesrvm.classloader.NormalMethod 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 3 with NormalMethod

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

the class BaselineExceptionDeliverer method unwindStackFrame.

/**
 * Unwind a stackframe.
 */
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
    NormalMethod method = (NormalMethod) compiledMethod.getMethod();
    ArchBaselineCompiledMethod bcm = (ArchBaselineCompiledMethod) compiledMethod;
    if (method.isSynchronized()) {
        Address ip = registers.getInnermostInstructionAddress();
        Offset instr = compiledMethod.getInstructionOffset(ip);
        Offset lockOffset = bcm.getLockAcquisitionOffset();
        if (instr.sGT(lockOffset)) {
            // we actually have the lock, so must unlock it.
            Object lock;
            if (method.isStatic()) {
                lock = method.getDeclaringClass().getResolvedClassForType();
            } else {
                Address fp = registers.getInnermostFramePointer();
                short location = bcm.getGeneralLocalLocation(0);
                Address addr;
                if (BaselineCompilerImpl.isRegister(location)) {
                    lock = Magic.addressAsObject(registers.getGPRs().get(location).toAddress());
                } else {
                    addr = fp.plus(BaselineCompilerImpl.locationToOffset(location) - // location offsets are positioned on top of their stackslot
                    BYTES_IN_ADDRESS);
                    lock = Magic.addressAsObject(addr.loadAddress());
                }
            }
            if (ObjectModel.holdsLock(lock, RVMThread.getCurrentThread())) {
                ObjectModel.genericUnlock(lock);
            }
        }
    }
    // restore non-volatile registers
    Address fp = registers.getInnermostFramePointer();
    Offset frameOffset = Offset.fromIntSignExtend(bcm.getFrameSize());
    for (int i = bcm.getLastFloatStackRegister(); i >= FIRST_FLOAT_LOCAL_REGISTER.value(); --i) {
        frameOffset = frameOffset.minus(BYTES_IN_DOUBLE);
        long temp = Magic.getLongAtOffset(Magic.addressAsObject(fp), frameOffset);
        registers.getFPRs()[i] = Magic.longBitsAsDouble(temp);
    }
    for (int i = bcm.getLastFixedStackRegister(); i >= FIRST_FIXED_LOCAL_REGISTER.value(); --i) {
        frameOffset = frameOffset.minus(BYTES_IN_ADDRESS);
        registers.getGPRs().set(i, fp.loadWord(frameOffset));
    }
    registers.unwindStackFrame();
}
Also used : Address(org.vmmagic.unboxed.Address) NormalMethod(org.jikesrvm.classloader.NormalMethod) Offset(org.vmmagic.unboxed.Offset) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 4 with NormalMethod

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

the class BaselineExceptionDeliverer method unwindStackFrame.

/**
 * Unwind a stackframe.
 */
@Override
@Unpreemptible("Unwind stack possibly from unpreemptible code")
public void unwindStackFrame(CompiledMethod compiledMethod, AbstractRegisters registers) {
    NormalMethod method = (NormalMethod) compiledMethod.getMethod();
    Address fp = registers.getInnermostFramePointer();
    if (method.isSynchronized()) {
        // release the lock, if it is being held
        Address ip = registers.getInnermostInstructionAddress();
        Offset instr = compiledMethod.getInstructionOffset(ip);
        Offset lockOffset = ((ArchBaselineCompiledMethod) compiledMethod).getLockAcquisitionOffset();
        if (instr.sGT(lockOffset)) {
            // we actually have the lock, so must unlock it.
            Object lock;
            if (method.isStatic()) {
                lock = method.getDeclaringClass().getResolvedClassForType();
            } else {
                lock = Magic.addressAsObject(fp.plus(BaselineCompilerImpl.locationToOffset(((ArchBaselineCompiledMethod) compiledMethod).getGeneralLocalLocation(0)) - BYTES_IN_ADDRESS).loadAddress());
            }
            if (ObjectModel.holdsLock(lock, RVMThread.getCurrentThread())) {
                ObjectModel.genericUnlock(lock);
            }
        }
    }
    // Restore nonvolatile registers used by the baseline compiler.
    if (VM.VerifyAssertions)
        VM._assert(SAVED_GPRS == 2);
    registers.getGPRs().set(EDI.value(), fp.plus(EDI_SAVE_OFFSET).loadWord());
    registers.getGPRs().set(EBX.value(), fp.plus(EBX_SAVE_OFFSET).loadWord());
    if (method.hasBaselineSaveLSRegistersAnnotation()) {
        registers.getGPRs().set(EBP.value(), fp.plus(EBP_SAVE_OFFSET).toWord());
    }
    registers.unwindStackFrame();
}
Also used : Address(org.vmmagic.unboxed.Address) NormalMethod(org.jikesrvm.classloader.NormalMethod) Offset(org.vmmagic.unboxed.Offset) Unpreemptible(org.vmmagic.pragma.Unpreemptible)

Example 5 with NormalMethod

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

the class Inliner method execute.

/**
 * Return a generation context that represents the
 * execution of inlDec in the context <code>&lt;parent,ebag&gt;</code> for
 * the call instruction callSite.
 * <p> PRECONDITION: inlDec.isYes()
 * <p> POSTCONDITIONS:
 * Let gc be the returned generation context.
 * <ul>
 *  <li> gc.cfg.firstInCodeOrder is the entry to the inlined context
 *  <li>gc.cfg.lastInCodeOrder is the exit from the inlined context
 *  <li> GenerationContext.transferState(parent, child) has been called.
 * </ul>
 *
 * @param inlDec the inlining decision to execute
 * @param parent the caller generation context
 * @param ebag exception handler scope for the caller
 * @param callSite the callsite to execute
 * @return a generation context that represents the execution of the
 *         inline decision in the given context
 */
public static GenerationContext execute(InlineDecision inlDec, GenerationContext parent, ExceptionHandlerBasicBlockBag ebag, Instruction callSite) {
    if (inlDec.needsGuard()) {
        // Step 1: create the synthetic generation context we'll
        // return to our caller.
        GenerationContext container = GenerationContext.createSynthetic(parent, ebag);
        container.getCfg().breakCodeOrder(container.getPrologue(), container.getEpilogue());
        // Step 2: (a) Print a message (optional)
        // (b) Generate the child GC for each target
        RVMMethod[] targets = inlDec.getTargets();
        byte[] guards = inlDec.getGuards();
        GenerationContext[] children = new GenerationContext[targets.length];
        for (int i = 0; i < targets.length; i++) {
            NormalMethod callee = (NormalMethod) targets[i];
            // (a)
            if (parent.getOptions().PRINT_INLINE_REPORT) {
                String guard = guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST ? " (class test) " : " (method test) ";
                VM.sysWriteln("\tGuarded inline" + guard + " " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
            }
            // (b)
            children[i] = parent.createChildContext(ebag, callee, callSite);
            BC2IR.generateHIR(children[i]);
            children[i].transferStateToParent();
        }
        // special purpose coding wrapping the calls to Operand.meet.
        if (Call.hasResult(callSite)) {
            Register reg = Call.getResult(callSite).getRegister();
            container.setResult(children[0].getResult());
            for (int i = 1; i < targets.length; i++) {
                if (children[i].getResult() != null) {
                    container.setResult((container.getResult() == null) ? children[i].getResult() : Operand.meet(container.getResult(), children[i].getResult(), reg));
                }
            }
            if (!inlDec.OSRTestFailed()) {
                // Account for the non-predicted case as well...
                RegisterOperand failureCaseResult = Call.getResult(callSite).copyRO();
                container.setResult((container.getResult() == null) ? failureCaseResult : Operand.meet(container.getResult(), failureCaseResult, reg));
            }
        }
        // Step 4: Create a block to contain a copy of the original call or an OSR_Yieldpoint
        // to cover the case that all predictions fail.
        BasicBlock testFailed = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
        testFailed.setExceptionHandlers(ebag);
        if (COUNT_FAILED_GUARDS && Controller.options.INSERT_DEBUGGING_COUNTERS) {
            // Get a dynamic count of how many times guards fail at runtime.
            // Need a name for the event to count.  In this example, a
            // separate counter for each method by using the method name
            // as the event name.  You could also have used just the string
            // "Guarded inline failed" to keep only one counter.
            String eventName = "Guarded inline failed: " + callSite.position().getMethod().toString();
            // Create instruction that will increment the counter
            // corresponding to the named event.
            Instruction counterInst = AOSDatabase.debuggingCounterData.getCounterInstructionForEvent(eventName);
            testFailed.appendInstruction(counterInst);
        }
        if (inlDec.OSRTestFailed()) {
            // note where we're storing the osr barrier instruction
            Instruction lastOsrBarrier = parent.getOSRBarrierFromInst(callSite);
            Instruction s = BC2IR._osrHelper(lastOsrBarrier, parent);
            s.copyPosition(callSite);
            testFailed.appendInstruction(s);
            testFailed.insertOut(parent.getExit());
        } else {
            Instruction call = callSite.copyWithoutLinks();
            Call.getMethod(call).setIsGuardedInlineOffBranch(true);
            call.copyPosition(callSite);
            testFailed.appendInstruction(call);
            testFailed.insertOut(container.getEpilogue());
            // BC2IR.maybeInlineMethod).
            if (ebag != null) {
                for (Enumeration<BasicBlock> e = ebag.enumerator(); e.hasMoreElements(); ) {
                    BasicBlock handler = e.nextElement();
                    testFailed.insertOut(handler);
                }
            }
            testFailed.setCanThrowExceptions();
            testFailed.setMayThrowUncaughtException();
        }
        container.getCfg().linkInCodeOrder(testFailed, container.getEpilogue());
        testFailed.setInfrequent();
        // Step 5: Patch together all the callees by generating guard blocks
        BasicBlock firstIfBlock = testFailed;
        // Note: We know that receiver must be a register
        // operand (and not a string constant) because we are doing a
        // guarded inlining....if it was a string constant we'd have
        // been able to inline without a guard.
        Operand receiver = Call.getParam(callSite, 0);
        MethodOperand mo = Call.getMethod(callSite);
        boolean isInterface = mo.isInterface();
        if (isInterface) {
            if (VM.BuildForIMTInterfaceInvocation) {
                RVMType interfaceType = mo.getTarget().getDeclaringClass();
                TypeReference recTypeRef = receiver.getType();
                RVMClass recType = (RVMClass) recTypeRef.peekType();
                // Attempt to avoid inserting the check by seeing if the
                // known static type of the receiver implements the interface.
                boolean requiresImplementsTest = true;
                if (recType != null && recType.isResolved() && !recType.isInterface()) {
                    byte doesImplement = ClassLoaderProxy.includesType(interfaceType.getTypeRef(), recTypeRef);
                    requiresImplementsTest = doesImplement != YES;
                }
                if (requiresImplementsTest) {
                    RegisterOperand checkedReceiver = parent.getTemps().makeTemp(receiver);
                    Instruction dtc = TypeCheck.create(MUST_IMPLEMENT_INTERFACE, checkedReceiver, receiver.copy(), new TypeOperand(interfaceType), Call.getGuard(callSite).copy());
                    dtc.copyPosition(callSite);
                    checkedReceiver.refine(interfaceType.getTypeRef());
                    Call.setParam(callSite, 0, checkedReceiver.copyRO());
                    testFailed.prependInstruction(dtc);
                }
            }
        }
        // "logical" test and to share test insertion for interfaces/virtuals.
        for (int i = children.length - 1; i >= 0; i--, testFailed = firstIfBlock) {
            firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
            firstIfBlock.setExceptionHandlers(ebag);
            BasicBlock lastIfBlock = firstIfBlock;
            RVMMethod target = children[i].getMethod();
            Instruction tmp;
            if (isInterface) {
                RVMClass callDeclClass = mo.getTarget().getDeclaringClass();
                if (!callDeclClass.isInterface()) {
                    // the entire compilation.
                    throw new OptimizingCompilerException("Attempted guarded inline of invoke interface when decl class of target method may not be an interface");
                }
                // We potentially have to generate IR to perform two tests here:
                // (1) Does the receiver object implement callDeclClass?
                // (2) Given that it does, is target the method that would
                // be invoked for this receiver?
                // It is quite common to be able to answer (1) "YES" at compile
                // time, in which case we only have to generate IR to establish
                // (2) at runtime.
                byte doesImplement = ClassLoaderProxy.includesType(callDeclClass.getTypeRef(), target.getDeclaringClass().getTypeRef());
                if (doesImplement != YES) {
                    // implements the interface).
                    if (parent.getOptions().PRINT_INLINE_REPORT) {
                        VM.sysWriteln("\t\tRequired additional instanceof " + callDeclClass + " test");
                    }
                    firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    firstIfBlock.setExceptionHandlers(ebag);
                    RegisterOperand instanceOfResult = parent.getTemps().makeTempInt();
                    tmp = InstanceOf.create(INSTANCEOF_NOTNULL, instanceOfResult, new TypeOperand(callDeclClass), receiver.copy(), Call.getGuard(callSite));
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    tmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), instanceOfResult.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    firstIfBlock.insertOut(testFailed);
                    firstIfBlock.insertOut(lastIfBlock);
                    container.getCfg().linkInCodeOrder(firstIfBlock, lastIfBlock);
                }
            }
            if (guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST) {
                tmp = InlineGuard.create(IG_CLASS_TEST, receiver.copy(), Call.getGuard(callSite).copy(), new TypeOperand(target.getDeclaringClass()), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else if (guards[i] == OptOptions.INLINE_GUARD_METHOD_TEST) {
                // declaring class.
                if (isInterface) {
                    RegisterOperand t = parent.getTemps().makeTempInt();
                    Instruction test = InstanceOf.create(INSTANCEOF_NOTNULL, t, new TypeOperand(target.getDeclaringClass().getTypeRef()), receiver.copy());
                    test.copyPosition(callSite);
                    lastIfBlock.appendInstruction(test);
                    Instruction cmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), t.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    cmp.copyPosition(callSite);
                    lastIfBlock.appendInstruction(cmp);
                    BasicBlock subclassTest = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    lastIfBlock.insertOut(testFailed);
                    lastIfBlock.insertOut(subclassTest);
                    container.getCfg().linkInCodeOrder(lastIfBlock, subclassTest);
                    lastIfBlock = subclassTest;
                }
                tmp = InlineGuard.create(IG_METHOD_TEST, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else {
                tmp = InlineGuard.create(IG_PATCH_POINT, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), inlDec.OSRTestFailed() ? BranchProfileOperand.never() : BranchProfileOperand.unlikely());
            }
            tmp.copyPosition(callSite);
            lastIfBlock.appendInstruction(tmp);
            lastIfBlock.insertOut(testFailed);
            lastIfBlock.insertOut(children[i].getPrologue());
            container.getCfg().linkInCodeOrder(lastIfBlock, children[i].getCfg().firstInCodeOrder());
            if (children[i].getEpilogue() != null) {
                children[i].getEpilogue().appendInstruction(container.getEpilogue().makeGOTO());
                children[i].getEpilogue().insertOut(container.getEpilogue());
            }
            container.getCfg().linkInCodeOrder(children[i].getCfg().lastInCodeOrder(), testFailed);
        }
        // Step 6: finish by linking container.prologue & testFailed
        container.getPrologue().insertOut(testFailed);
        container.getCfg().linkInCodeOrder(container.getPrologue(), testFailed);
        return container;
    } else {
        if (VM.VerifyAssertions)
            VM._assert(inlDec.getNumberOfTargets() == 1);
        NormalMethod callee = (NormalMethod) inlDec.getTargets()[0];
        if (parent.getOptions().PRINT_INLINE_REPORT) {
            VM.sysWriteln("\tInline " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
        }
        GenerationContext child = parent.createChildContext(ebag, callee, callSite);
        BC2IR.generateHIR(child);
        child.transferStateToParent();
        return child;
    }
}
Also used : GenerationContext(org.jikesrvm.compilers.opt.bc2ir.GenerationContext) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RVMClass(org.jikesrvm.classloader.RVMClass) RVMMethod(org.jikesrvm.classloader.RVMMethod) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) NormalMethod(org.jikesrvm.classloader.NormalMethod) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Aggregations

NormalMethod (org.jikesrvm.classloader.NormalMethod)95 Test (org.junit.Test)66 OptOptions (org.jikesrvm.compilers.opt.OptOptions)45 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)41 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)31 DefaultInlineOracle (org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle)28 InlineOracle (org.jikesrvm.compilers.opt.inlining.InlineOracle)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)28 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)21 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)17 TypeReference (org.jikesrvm.classloader.TypeReference)15 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)15 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)15 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)13 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)13 Register (org.jikesrvm.compilers.opt.ir.Register)13 RVMMethod (org.jikesrvm.classloader.RVMMethod)8 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)8 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)8 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)8