Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Revert until I figure this regression out
  • Loading branch information
enebo committed Dec 16, 2014
1 parent 233fad8 commit ae8e0aa
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 10 deletions.
82 changes: 73 additions & 9 deletions core/src/main/java/org/jruby/ir/IREvalScript.java
@@ -1,13 +1,12 @@
package org.jruby.ir;

import java.util.ArrayList;
import java.util.List;
import org.jruby.EvalType;
import org.jruby.RubyModule;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.interpreter.BeginEndInterpreterContext;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.ClosureLocalVariable;
import org.jruby.ir.operands.Label;
import org.jruby.ir.operands.LocalVariable;
import org.jruby.ir.operands.Operand;
Expand All @@ -19,9 +18,14 @@
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class IREvalScript extends IRClosure {
private static final Logger LOG = LoggerFactory.getLogger("IREvalScript");

private IRScope nearestNonEvalScope;
private int nearestNonEvalScopeDepth;
private List<IRClosure> beginBlocks;
private List<IRClosure> endBlocks;
private EvalType evalType;
Expand All @@ -32,16 +36,23 @@ public IREvalScript(IRManager manager, IRScope lexicalParent, String fileName,

this.evalType = evalType;

int n = 0;
IRScope s = lexicalParent;
while (s instanceof IREvalScript) {
n++;
s = s.getLexicalParent();
}

this.nearestNonEvalScope = s;
this.nearestNonEvalScopeDepth = n;
this.nearestNonEvalScope.initEvalScopeVariableAllocator(false);

if (!getManager().isDryRun() && staticScope != null) {
// SSS FIXME: This is awkward!
if (evalType == EvalType.MODULE_EVAL) {
staticScope.setScopeType(getScopeType());
staticScope.setScopeType(this.getScopeType());
} else {
IRScope s = lexicalParent;
while (s instanceof IREvalScript) {
s = s.getLexicalParent();
}
staticScope.setScopeType(s.getScopeType());
staticScope.setScopeType(this.nearestNonEvalScope.getScopeType());
}
}
}
Expand Down Expand Up @@ -106,19 +117,72 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
return Interpreter.INTERPRET_EVAL(context, self, ic, clazz, new IRubyObject[] {}, backtraceName, block, null);
}

@Override
public LocalVariable lookupExistingLVar(String name) {
return nearestNonEvalScope.evalScopeVars.get(name);
}

@Override
protected LocalVariable findExistingLocalVariable(String name, int scopeDepth) {
// Look in the nearest non-eval scope's shared eval scope vars first.
// If you dont find anything there, look in the nearest non-eval scope's regular vars.
LocalVariable lvar = lookupExistingLVar(name);
if (lvar != null || scopeDepth == 0) return lvar;
else return nearestNonEvalScope.findExistingLocalVariable(name, scopeDepth-nearestNonEvalScopeDepth-1);
}

@Override
public LocalVariable getLocalVariable(String name, int scopeDepth) {
// Reduce lookup depth by 1 since the AST seems to be adding
// an additional static/dynamic scope for which there is no
// corresponding IRScope.
//
// FIXME: Investigate if this is something left behind from
// 1.8 mode support. Or if we need to introduce the additional
// IRScope object.
int lookupDepth = isModuleOrInstanceEval() ? scopeDepth - 1 : scopeDepth;
LocalVariable lvar = findExistingLocalVariable(name, lookupDepth);
if (lvar == null) lvar = getNewLocalVariable(name, lookupDepth);
// Create a copy of the variable usable at the right depth
if (lvar.getScopeDepth() != scopeDepth) lvar = lvar.cloneForDepth(scopeDepth);

return lvar;
}

@Override
public LocalVariable getNewLocalVariable(String name, int depth) {
assert depth == nearestNonEvalScopeDepth: "Local variable depth in IREvalScript:getNewLocalVariable for " + name + " must be " + nearestNonEvalScopeDepth + ". Got " + depth;
LocalVariable lvar = new ClosureLocalVariable(this, name, 0, nearestNonEvalScope.evalScopeVars.size());
nearestNonEvalScope.evalScopeVars.put(name, lvar);
// CON: unsure how to get static scope to reflect this name as in IRClosure and IRMethod
return lvar;
}

@Override
public LocalVariable getNewFlipStateVariable() {
String flipVarName = "%flip_" + allocateNextPrefixedName("%flip");
LocalVariable v = lookupExistingLVar(flipVarName);
if (v == null) {
v = getNewLocalVariable(flipVarName, 0);
}
return v;
}

return v == null ? getNewLocalVariable(flipVarName, 0) : v;
@Override
public int getUsedVariablesCount() {
return 1 + nearestNonEvalScope.evalScopeVars.size()+ getPrefixCountSize("%flip");
}

@Override
public boolean isScriptScope() {
return true;
}

@Override
public boolean isTopLocalVariableScope() {
return false;
}

@Override
public boolean isFlipScope() {
return true;
Expand Down
16 changes: 16 additions & 0 deletions core/src/main/java/org/jruby/ir/IRScope.java
Expand Up @@ -5,6 +5,7 @@
import org.jruby.RubyModule;
import org.jruby.ir.dataflow.DataFlowProblem;
import org.jruby.ir.instructions.*;
import org.jruby.ir.interpreter.ClosureInterpreterContext;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.*;
import org.jruby.ir.operands.Float;
Expand Down Expand Up @@ -121,6 +122,7 @@ public abstract class IRScope implements ParseResult {
private TemporaryLocalVariable currentScopeVariable;

Map<String, LocalVariable> localVars;
Map<String, LocalVariable> evalScopeVars;

EnumSet<IRFlags> flags = EnumSet.noneOf(IRFlags.class);

Expand All @@ -130,6 +132,9 @@ public abstract class IRScope implements ParseResult {
/** # of thread poll instrs added to this scope */
private int threadPollInstrsCount;

/** Should we re-run compiler passes -- yes after we've inlined, for example */
private boolean relinearizeCFG;

private IRManager manager;

// Used by cloning code
Expand All @@ -156,6 +161,7 @@ protected IRScope(IRScope s, IRScope lexicalParent) {

this.localVars = new HashMap<String, LocalVariable>(s.localVars);
this.scopeId = globalScopeCount.getAndIncrement();
this.relinearizeCFG = false;

this.executedPasses = new ArrayList<CompilerPass>();

Expand Down Expand Up @@ -202,6 +208,7 @@ public IRScope(IRManager manager, IRScope lexicalParent, String name,

this.localVars = new HashMap<String, LocalVariable>();
this.scopeId = globalScopeCount.getAndIncrement();
this.relinearizeCFG = false;

this.executedPasses = new ArrayList<CompilerPass>();

Expand Down Expand Up @@ -543,6 +550,10 @@ public List<CompilerPass> getExecutedPasses() {
// and we may need to update the method to return the new method. Also,
// if this scope is held in multiple locations how do we update all references?
private void runCompilerPasses(List<CompilerPass> passes) {
// SSS FIXME: Why is this again? Document this weirdness!
// Forcibly clear out the shared eval-scope variable allocator each time this method executes
initEvalScopeVariableAllocator(true);

// All passes are disabled in scopes where BEGIN and END scopes might
// screw around with escaped variables. Optimizing for them is not
// worth the effort. It is simpler to just go fully safe in scopes
Expand Down Expand Up @@ -856,6 +867,10 @@ public LocalVariable getNewLocalVariable(String name, int scopeDepth) {
return lvar;
}

protected void initEvalScopeVariableAllocator(boolean reset) {
if (reset || evalScopeVars == null) evalScopeVars = new HashMap<String, LocalVariable>();
}

public TemporaryLocalVariable createTemporaryVariable() {
return getNewTemporaryVariable(TemporaryVariableType.LOCAL);
}
Expand Down Expand Up @@ -1025,6 +1040,7 @@ public InterpreterContext getInterpreterContext() {

public void resetLinearizationData() {
linearizedBBList = null;
relinearizeCFG = false;
}

public List<BasicBlock> buildLinearization() {
Expand Down
Expand Up @@ -49,7 +49,7 @@ public IRubyObject[] getValues() {
* @return the value here
*/
public IRubyObject getValue(int offset, int depth) {
// assert depth != 0: SIZE_ERROR;
assert depth != 0: SIZE_ERROR;
return parent.getValue(offset, depth - 1);
}

Expand Down

0 comments on commit ae8e0aa

Please sign in to comment.