Skip to content

Commit

Permalink
Make inliner return false on failure so we do not just blunder throug…
Browse files Browse the repository at this point in the history
…h and try

and setup up something incomplete.
  • Loading branch information
enebo committed Oct 23, 2018
1 parent ba93500 commit a916473
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
7 changes: 4 additions & 3 deletions core/src/main/java/org/jruby/ir/IRScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -1126,15 +1126,16 @@ private FullInterpreterContext inlineMethodCommon(IRMethod methodToInline, long
CallBase call = (CallBase) basicBlock.siteOf(callsiteId); // we know it is callBase and not a yield
RubyModule implClass = compilable.getImplementationClass();

new CFGInliner(newContext).inlineMethod(methodToInline, implClass, classToken, basicBlock, call, cloneHost);
boolean success = new CFGInliner(newContext).inlineMethod(methodToInline, implClass, classToken, basicBlock, call, cloneHost);

return newContext;
return success ? newContext : null;
}

public void inlineMethod(IRMethod methodToInline, long callsiteId, int classToken, boolean cloneHost) {
if (alreadyHasInline) return;

FullInterpreterContext newContext = inlineMethodCommon(methodToInline, callsiteId, classToken, cloneHost);
if (newContext == null) return;
newContext.generateInstructionsForInterpretation();
this.optimizedInterpreterContext = newContext;

Expand All @@ -1145,7 +1146,7 @@ public void inlineMethodJIT(IRMethod methodToInline, long callsiteId, int classT
if (alreadyHasInline) return;

FullInterpreterContext newContext = inlineMethodCommon(methodToInline, callsiteId, classToken, cloneHost);

if (newContext == null) return;
// We are not running any JIT-specific passes here.

newContext.linearizeBasicBlocks();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,17 @@ private void printInlineSplitBBs(BasicBlock beforeBB, BasicBlock afterBB) {
// methodScope - scope of the method to be inlined
// callBB - BB where callsite is located
// call - callsite where we want to inline the methods body.
public void inlineMethod(IRScope scopeToInline, RubyModule implClass, int classToken, BasicBlock callBB, CallBase call, boolean cloneHost) {
public boolean inlineMethod(IRScope scopeToInline, RubyModule implClass, int classToken, BasicBlock callBB, CallBase call, boolean cloneHost) {
// Temporarily turn off inlining of recursive methods
// Conservative turning off for inlining of a method in a closure nested within the same method
if (isRecursiveInline(scopeToInline)) return;
if (isRecursiveInline(scopeToInline)) return false;
if (debug) printInlineDebugPrologue(scopeToInline, call);

if (callBB == null) {
callBB = findCallsiteBB(call);
if (callBB == null) {
if (debug) printInlineCannotFindCallsiteBB(call);
return;
return false;
} else {
if (debug) printInlineFoundBB(callBB);
}
Expand Down Expand Up @@ -287,9 +287,9 @@ public void inlineMethod(IRScope scopeToInline, RubyModule implClass, int classT
if (closureArg != null && !yieldSites.isEmpty()) {
// Detect unlikely but contrived scenarios where there are far too many yield sites that could lead to code blowup
// if we inline the closure at all those yield sites!
if (yieldSites.size() > 1) {
throw new RuntimeException("Encountered " + yieldSites.size() + " yield sites. Convert the yield to a call by converting the closure into a dummy method (have to convert all frame vars to call arguments, or at least convert the frame into a call arg");
}

// currently we will only inline a single block into a single yield.
if (yieldSites.size() > 1) return false;

if (!(closureArg instanceof WrappedIRClosure)) {
throw new RuntimeException("Encountered a dynamic closure arg. Cannot inline it here! Convert the yield to a call by converting the closure into a dummy method (have to convert all frame vars to call arguments, or at least convert the frame into a call arg");
Expand Down Expand Up @@ -319,6 +319,7 @@ public void inlineMethod(IRScope scopeToInline, RubyModule implClass, int classT
System.out.println("final cfg :" + cfg.toStringGraph());
System.out.println("final instrs:" + cfg.toStringInstrs());
*/
return true;
}

// FIXME: Adding some more similar logic and we could make a CFG verifier looking for invalid CFGs (e.g. mismatched edge vs instrs in it).
Expand Down

0 comments on commit a916473

Please sign in to comment.