Search in sources :

Example 1 with ExceptionHandlerBasicBlockBag

use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag in project JikesRVM by JikesRVM.

the class Inliner method execute.

/**
 * Execute an inlining decision inlDec for the CALL instruction
 * callSite that is contained in ir.
 *
 * @param inlDec the inlining decision to execute
 * @param ir the governing IR
 * @param callSite the call site to inline
 */
public static void execute(InlineDecision inlDec, IR ir, Instruction callSite) {
    // Find out where the call site is and isolate it in its own basic block.
    BasicBlock bb = callSite.getBasicBlock().segregateInstruction(callSite, ir);
    BasicBlock in = bb.prevBasicBlockInCodeOrder();
    BasicBlock out = bb.nextBasicBlockInCodeOrder();
    // We need to ensure that inlining the CALL instruction does not
    // insert any new exceptional edges into the CFG that were not
    // present before the inlining.  Note that inlining the CALL may
    // introduce new CALLS, for which we don't know the exception
    // behavior.  However, we know that any new PEIs introduced in the
    // inlined code had better not add exceptional edges to the
    // original CFG.  So, create a new ExceptionHandlerBasicBlockBag
    // which will enforce this behavior.
    ExceptionHandlerBasicBlock[] catchBlocks = new ExceptionHandlerBasicBlock[bb.getNumberOfExceptionalOut()];
    Enumeration<BasicBlock> e = bb.getExceptionalOut();
    for (int i = 0; i < catchBlocks.length; i++) {
        catchBlocks[i] = (ExceptionHandlerBasicBlock) e.nextElement();
    }
    ExceptionHandlerBasicBlockBag bag = new ExceptionHandlerBasicBlockBag(catchBlocks, null);
    // Execute the inlining decision, updating ir.gc's state.
    GenerationContext childgc = execute(inlDec, ir.getGc(), bag, callSite);
    // Splice the callee into the caller's code order
    ir.cfg.removeFromCFGAndCodeOrder(bb);
    ir.cfg.breakCodeOrder(in, out);
    ir.cfg.linkInCodeOrder(in, childgc.getCfg().firstInCodeOrder());
    ir.cfg.linkInCodeOrder(childgc.getCfg().lastInCodeOrder(), out);
    // Splice the callee into the caller's CFG
    in.insertOut(childgc.getPrologue());
    if (childgc.getEpilogue() != null) {
        childgc.getEpilogue().insertOut(out);
    }
}
Also used : GenerationContext(org.jikesrvm.compilers.opt.bc2ir.GenerationContext) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)

Example 2 with ExceptionHandlerBasicBlockBag

use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag in project JikesRVM by JikesRVM.

the class GenerationContextTest method childContextsQueryOSRBarrierInformationViaOutermostParent.

@Test
public void childContextsQueryOSRBarrierInformationViaOutermostParent() throws Exception {
    NormalMethod nm = getNormalMethodForTest("methodForInliningTests");
    CompiledMethod cm = new OptCompiledMethod(-1, nm);
    OptOptions opts = new OptOptions();
    InlineOracle io = new DefaultInlineOracle();
    GenerationContext outermost = new GenerationContext(nm, null, cm, opts, io);
    Class<?>[] classArgs = { Object.class };
    NormalMethod callee = getNormalMethodForTest("emptyStaticMethodWithObjectParamAndReturnValue", classArgs);
    MethodOperand methOp = MethodOperand.STATIC(callee);
    RegisterOperand result = createMockRegisterOperand(TypeReference.JavaLangObject);
    Instruction callInstr = Call.create(CALL, result, null, methOp, 1);
    RegisterOperand objectParam = createMockRegisterOperand(TypeReference.JavaLangObject);
    Call.setParam(callInstr, 0, objectParam);
    callInstr.setPosition(new InlineSequence(nm));
    ExceptionHandlerBasicBlockBag ebag = getMockEbag();
    GenerationContext child = outermost.createChildContext(ebag, callee, callInstr);
    Instruction osrBarrier = createMockOSRBarrier();
    Instruction call = createMockCall();
    child.saveOSRBarrierForInst(osrBarrier, call);
    assertThat(outermost.getOSRBarrierFromInst(call), is(osrBarrier));
    assertThat(child.getOSRBarrierFromInst(call), is(osrBarrier));
    GenerationContext child2 = outermost.createChildContext(ebag, callee, callInstr);
    assertThat(child2.getOSRBarrierFromInst(call), is(osrBarrier));
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineOracle(org.jikesrvm.compilers.opt.inlining.InlineOracle) OptOptions(org.jikesrvm.compilers.opt.OptOptions) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) NormalMethod(org.jikesrvm.classloader.NormalMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineSequence(org.jikesrvm.compilers.opt.inlining.InlineSequence) Test(org.junit.Test)

Example 3 with ExceptionHandlerBasicBlockBag

use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag in project JikesRVM by JikesRVM.

the class GenerationContextTest method methodIsSelectedForDebuggingWithMethodToPrintReturnsTrueIfOutermostParentMatches.

@Test
public void methodIsSelectedForDebuggingWithMethodToPrintReturnsTrueIfOutermostParentMatches() throws Exception {
    String methodName = "emptyStaticMethodWithoutAnnotations";
    NormalMethod nm = getNormalMethodForTest(methodName);
    CompiledMethod cm = new OptCompiledMethod(-1, nm);
    OptOptions opts = buildOptionsWithMethodToPrintOptionSet(methodName);
    InlineOracle io = new DefaultInlineOracle();
    GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
    ExceptionHandlerBasicBlockBag ebag = getMockEbag();
    NormalMethod callee = getNormalMethodForTest("emptyStaticMethodWithNoCheckStoreAnnotation");
    Instruction noCheckStoreInstr = buildCallInstructionForStaticMethodWithoutReturn(callee, nm);
    GenerationContext nextInnerContext = gc.createChildContext(ebag, callee, noCheckStoreInstr);
    NormalMethod nextInnerCallee = getNormalMethodForTest("emptyStaticMethodWithNoNullCheckAnnotation");
    Instruction noNullCheckInstr = buildCallInstructionForStaticMethodWithoutReturn(callee, nextInnerCallee);
    GenerationContext innermostContext = nextInnerContext.createChildContext(ebag, nextInnerCallee, noNullCheckInstr);
    assertThat(innermostContext.methodIsSelectedForDebuggingWithMethodToPrint(), is(true));
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineOracle(org.jikesrvm.compilers.opt.inlining.InlineOracle) NormalMethod(org.jikesrvm.classloader.NormalMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) OptOptions(org.jikesrvm.compilers.opt.OptOptions) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) Test(org.junit.Test)

Example 4 with ExceptionHandlerBasicBlockBag

use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag in project JikesRVM by JikesRVM.

the class GenerationContextTest method contextReturnedByGetSynthethicContextContainsOnlyCFG.

@Test(expected = NullPointerException.class)
public void contextReturnedByGetSynthethicContextContainsOnlyCFG() throws Exception {
    GenerationContext gc = createMostlyEmptyContext("methodForInliningTests");
    ExceptionHandlerBasicBlockBag mockEbag = getMockEbag();
    int parentCfgNodeNumber = gc.getCfg().numberOfNodes();
    GenerationContext synthethicContext = GenerationContext.createSynthetic(gc, mockEbag);
    int synthethicNodeNumber = -100000;
    assertThat(synthethicContext.getCfg().numberOfNodes(), is(synthethicNodeNumber));
    assertThat(synthethicContext.getPrologue().firstInstruction().getBytecodeIndex(), is(PROLOGUE_BCI));
    assertThat(synthethicContext.getPrologue().firstInstruction().position(), is(gc.getInlineSequence()));
    assertThat(synthethicContext.getPrologue().getNumber(), is(parentCfgNodeNumber));
    assertThat(synthethicContext.getPrologue().exceptionHandlers(), is(mockEbag));
    assertThat(synthethicContext.getEpilogue().firstInstruction().getBytecodeIndex(), is(EPILOGUE_BCI));
    assertThat(synthethicContext.getEpilogue().firstInstruction().position(), is(gc.getInlineSequence()));
    assertThat(synthethicContext.getEpilogue().getNumber(), is(parentCfgNodeNumber + 1));
    assertThat(synthethicContext.getEpilogue().exceptionHandlers(), is(mockEbag));
    assertThat(gc.getCfg().numberOfNodes(), is(4));
    assertThat(synthethicContext.getCfg().numberOfNodes(), is(synthethicNodeNumber));
    assertThat(synthethicContext.getCfg().firstInCodeOrder(), is(synthethicContext.getPrologue()));
    assertThat(synthethicContext.getCfg().lastInCodeOrder(), is(synthethicContext.getEpilogue()));
    assertFalse(synthethicContext.requiresStackFrame());
    assertNull(synthethicContext.getArguments());
    assertNull(synthethicContext.getBranchProfiles());
    assertNull(synthethicContext.getEnclosingHandlers());
    assertNull(synthethicContext.getExit());
    assertFalse(synthethicContext.generatedExceptionHandlers());
    assertNull(synthethicContext.getInlinePlan());
    assertNull(synthethicContext.getInlineSequence());
    assertNull(synthethicContext.getMethod());
    assertNull(synthethicContext.getOptions());
    assertNull(synthethicContext.getOriginalCompiledMethod());
    assertNull(synthethicContext.getOriginalMethod());
    assertNull(synthethicContext.getResult());
    assertNull(synthethicContext.getResultReg());
    assertNull(synthethicContext.getTemps());
    assertNull(synthethicContext.getUnlockAndRethrow());
    // check that nc_guards are null
    synthethicContext.resync();
}
Also used : ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) Test(org.junit.Test)

Example 5 with ExceptionHandlerBasicBlockBag

use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag in project JikesRVM by JikesRVM.

the class GenerationContextTest method assertThatUnlockAndRethrowBlockIsCorrectForInlinedMethod.

private void assertThatUnlockAndRethrowBlockIsCorrectForInlinedMethod(GenerationContext parentContext, GenerationContext childContext, InlineSequence inlineSequence, BasicBlock prologue, Operand lockObject, BasicBlock epilogue) {
    ExceptionHandlerBasicBlockBag ehbb = childContext.getEnclosingHandlers();
    Enumeration<BasicBlock> enumerator = ehbb.enumerator();
    assertThat(childContext.getUnlockAndRethrow().exceptionHandlers(), is(parentContext.getEnclosingHandlers()));
    ExceptionHandlerBasicBlock rethrow = (ExceptionHandlerBasicBlock) enumerator.nextElement();
    assertSame(rethrow, childContext.getUnlockAndRethrow());
    assertThatRethrowBlockIsCorrect(inlineSequence, lockObject, rethrow);
    checkCodeOrderForRethrowBlock(childContext, prologue, epilogue, rethrow);
    ExceptionHandlerBasicBlockBag parentHandlers = parentContext.getEnclosingHandlers();
    Enumeration<BasicBlock> parentHandlerBBEnum = parentHandlers.enumerator();
    HashSet<BasicBlock> parentHandlerBBs = new HashSet<BasicBlock>();
    while (parentHandlerBBEnum.hasMoreElements()) {
        parentHandlerBBs.add(parentHandlerBBEnum.nextElement());
    }
    BasicBlock childRethrow = childContext.getUnlockAndRethrow();
    OutEdgeEnumeration outEdges = childRethrow.outEdges();
    boolean linkedToAllBlocksFromParentHandler = true;
    while (outEdges.hasMoreElements()) {
        BasicBlock target = (BasicBlock) outEdges.nextElement().to();
        if (!parentHandlerBBs.contains(target) && target != childContext.getExit()) {
            linkedToAllBlocksFromParentHandler = false;
            break;
        }
    }
    assertTrue(linkedToAllBlocksFromParentHandler);
    ExceptionHandlerBasicBlockBag ehbbb = childContext.getEnclosingHandlers();
    assertSame(parentContext.getEnclosingHandlers(), ehbbb.getCaller());
    assertThatEnclosingHandlersContainRethrow(rethrow, ehbbb);
}
Also used : OutEdgeEnumeration(org.jikesrvm.compilers.opt.util.SpaceEffGraphNode.OutEdgeEnumeration) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) HashSet(java.util.HashSet)

Aggregations

ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)22 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)16 Test (org.junit.Test)16 NormalMethod (org.jikesrvm.classloader.NormalMethod)15 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)14 OptOptions (org.jikesrvm.compilers.opt.OptOptions)14 DefaultInlineOracle (org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle)14 InlineOracle (org.jikesrvm.compilers.opt.inlining.InlineOracle)14 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)14 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)10 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)10 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)10 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)9 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 TypeReference (org.jikesrvm.classloader.TypeReference)4 ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)4 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)4 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)4 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)4 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)3