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);
}
}
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));
}
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));
}
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();
}
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);
}
Aggregations