Skip to content

Commit

Permalink
Clone instructions properly before rebuilding interpreter context.
Browse files Browse the repository at this point in the history
* This fixes failing tests on this branch.
  • Loading branch information
subbuss committed Feb 18, 2015
1 parent ce466f2 commit 8899356
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions core/src/main/java/org/jruby/ir/IRScope.java
Expand Up @@ -142,7 +142,7 @@ public abstract class IRScope implements ParseResult {

// What state is this scope in?
enum ScopeState {
INIT, INSTRS_CLONED, CFG_BUILT
INIT, INTERPED, INSTRS_CLONED, CFG_BUILT
};

private ScopeState state = ScopeState.INIT;
Expand Down Expand Up @@ -455,6 +455,13 @@ public CFG buildCFG() {
return getCFG();
}

// If the scope has already been interpreted once,
// the scope can be on the call stack right now.
// So, clone instructions before building the CFG.
if (this.state == ScopeState.INTERPED) {
this.cloneInstrs();
}

CFG newCFG = new CFG(this);
newCFG.build(getInstrs());
// Clear out instruction list after CFG has been built.
Expand Down Expand Up @@ -637,7 +644,7 @@ public InterpreterContext prepareForInterpretation() {
}

protected void cloneInstrs() {
if (this.state == ScopeState.INIT) {
if (getCFG() == null) {
// Clone instrs before modifying them
SimpleCloneInfo cloneInfo = new SimpleCloneInfo(this, false);
List<Instr> newInstrList = new ArrayList<Instr>(this.instrList.size());
Expand All @@ -647,20 +654,22 @@ protected void cloneInstrs() {
this.instrList = newInstrList;
this.state = ScopeState.INSTRS_CLONED;
}
for (IRClosure cl: getClosures()) {
cl.cloneInstrs();
}
}

/** Run any necessary passes to get the IR ready for interpretation */
public synchronized InterpreterContext prepareForInterpretation(boolean rebuild) {
if (interpreterContext != null) {
if (interpreterContext == null) {
this.state = ScopeState.INTERPED;
} else {
if (!rebuild || getCFG() != null) {
return interpreterContext; // Already prepared/rebuilt
}

// If rebuilding, clone instrs before building cfg, running passes, etc.
this.cloneInstrs();
for (IRClosure cl: getClosures()) {
cl.cloneInstrs();
}

// Build CFG, run passes, etc.
initScope(false);
Expand Down

0 comments on commit 8899356

Please sign in to comment.