Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: d1b6d5e41a20
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 50882dc6adb9
Choose a head ref
  • 3 commits
  • 12 files changed
  • 1 contributor

Commits on Jul 28, 2016

  1. Remove IPC from Instr. Not really used beyond inlining and our inlining

    branch no longer is using IPC for this.  So comments look like I am making
    broken code but this code is already broken and will be replaced when I
    merge the inliner stuff.
    enebo committed Jul 28, 2016
    Copy the full SHA
    a24633e View commit details
  2. Remove RPC from instr. Remove unused interpreter engines (at least for

    now).
    
    The RPC not resides in a table in the FIC.  It is looked up via a list
    of pairs.  I have not measured performance but O(n) compared vs O(1)
    where n is the number of BBs (which is generally fairly small).  If
    we see any slowdown this can be changed to O(ln(n)).
    enebo committed Jul 28, 2016
    Copy the full SHA
    4175f39 View commit details

Commits on Aug 5, 2016

  1. Copy the full SHA
    50882dc View commit details
1 change: 0 additions & 1 deletion core/src/main/java/org/jruby/ir/IRFlags.java
Original file line number Diff line number Diff line change
@@ -57,6 +57,5 @@ public enum IRFlags {

DYNSCOPE_ELIMINATED, // local var load/stores have been converted to tmp var accesses
REUSE_PARENT_DYNSCOPE, // for closures -- reuse parent's dynscope
SIMPLE_METHOD, // probably temporary flag. Can this method scope fit into a simple method interpreter
CODE_COVERAGE, // Was marked as needing code coverage (only used by lazy methods and converting closures->methods)
}
16 changes: 0 additions & 16 deletions core/src/main/java/org/jruby/ir/instructions/Instr.java
Original file line number Diff line number Diff line change
@@ -38,17 +38,13 @@
public abstract class Instr {
public static final Operand[] EMPTY_OPERANDS = new Operand[0];

private transient int ipc; // Interpreter-only: instruction pointer
private transient int rpc; // Interpreter-only: rescue pointer
private transient final Operation operation;
// Is this instruction live or dead? During optimization passes, if this instruction
// causes no side-effects and the result of the instruction is not needed by anyone else,
// we can remove this instruction altogether without affecting program correctness.
private boolean isDead;

public Instr(Operation operation) {
this.ipc = -1;
this.rpc = -1;
this.operation = operation;
}

@@ -146,18 +142,6 @@ public Operation getOperation() {
return operation;
}

@Interp
public int getIPC() { return ipc; }

@Interp
public void setIPC(int ipc) { this.ipc = ipc; }

@Interp
public int getRPC() { return rpc; }

@Interp
public void setRPC(int rpc) { this.rpc = rpc; }

// Does this instruction have side effects as a result of its operation
// This information is used in optimization phases to impact dead code elimination
// and other optimization passes
232 changes: 0 additions & 232 deletions core/src/main/java/org/jruby/ir/interpreter/BodyInterpreterEngine.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -9,12 +9,12 @@
import org.jruby.ir.IRScope;
import org.jruby.ir.dataflow.DataFlowProblem;
import org.jruby.ir.instructions.Instr;
import org.jruby.ir.instructions.LabelInstr;
import org.jruby.ir.instructions.ReceiveSelfInstr;
import org.jruby.ir.passes.CompilerPass;
import org.jruby.ir.representations.BasicBlock;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.representations.CFGLinearizer;
import org.jruby.ir.representations.IGVCFGVisitor;

/**
* Created by enebo on 2/27/15.
@@ -26,6 +26,11 @@ public class FullInterpreterContext extends InterpreterContext {
// FIXME: At some point when we relinearize after running another phase of passes we should document that here to know how this field is changed
private BasicBlock[] linearizedBBList = null;

// Contains pairs of values. The first value is number of instrs in this range + number of instrs before
// this range. The second number is the rescuePC. getRescuePC(ipc) will walk this list and first odd value
// less than this value will be the rpc.
private int[] rescueIPCs = null;

/** Map of name -> dataflow problem */
private Map<String, DataFlowProblem> dataFlowProblems;

@@ -86,7 +91,6 @@ public boolean reuseParentDynScope() {
/** We plan on running this in full interpreted mode. This will fixup ipc, rpc, and generate instr list */
public void generateInstructionsForIntepretation() {
linearizeBasicBlocks();
boolean simple_method = getScope() instanceof IRMethod;

// Pass 1. Set up IPCs for labels and instructions and build linear instr list
List<Instr> newInstrs = new ArrayList<>();
@@ -101,32 +105,37 @@ public void generateInstructionsForIntepretation() {
// FIXME: Can be replaced with System.arrayCopy to avoid call newInstrs.add a zillion times
for (int i = 0; i < bbInstrsLength; i++) {
Instr instr = bbInstrs.get(i);
if (simple_method && SimpleMethodInterpreterEngine.OPERATIONS.get(instr.getOperation()) == null) simple_method = false;
if (!(instr instanceof ReceiveSelfInstr)) {
instr.setIPC(ipc);
if (instr instanceof LabelInstr) ((LabelInstr) instr).getLabel().setTargetPC(ipc);
newInstrs.add(instr);
ipc++;
}
}
}

if (simple_method) getScope().getFlags().add(IRFlags.SIMPLE_METHOD);

cfg.getExitBB().getLabel().setTargetPC(ipc + 1); // Exit BB ipc

Instr[] linearizedInstrArray = newInstrs.toArray(new Instr[newInstrs.size()]);

BasicBlock[] basicBlocks = getLinearizedBBList();
rescueIPCs = new int[2 * basicBlocks.length];

// Pass 2: Use ipc info from previous to mark all linearized instrs rpc
ipc = 0;
for (BasicBlock b : getLinearizedBBList()) {
BasicBlock rescuerBB = cfg.getRescuerBBFor(b);
for (int i = 0; i < basicBlocks.length; i++) {
BasicBlock bb = basicBlocks[i];
BasicBlock rescuerBB = cfg.getRescuerBBFor(bb);
int rescuerPC = rescuerBB == null ? -1 : rescuerBB.getLabel().getTargetPC();
for (Instr instr : b.getInstrs()) {
rescueIPCs[i * 2] = ipc + bb.getInstrs().size();
rescueIPCs[i * 2 + 1] = rescuerPC;

for (Instr instr : bb.getInstrs()) {
// FIXME: If we did not omit instrs from previous pass, we could end up just doing
// a size and for loop this n times instead of walking an examining each instr
if (!(instr instanceof ReceiveSelfInstr)) {
linearizedInstrArray[ipc].setRPC(rescuerPC);
ipc++;
} else {
rescueIPCs[i * 2]--;
}
}
}
@@ -170,4 +179,13 @@ public BasicBlock[] getLinearizedBBList() {
public String toStringInstrs() {
return "\nCFG:\n" + cfg.toStringGraph() + "\nInstructions:\n" + cfg.toStringInstrs();
}

public int determineRPC(int ipc) {
int length = rescueIPCs.length;
for (int i = 0; i + 1 < length; i += 2) {
if (ipc <= rescueIPCs[i]) return rescueIPCs[i + 1];
}

throw new RuntimeException("BUG: no RPC found for " + getFileName() + ":" + getName() + ":" + ipc + getInstructions());
}
}
Loading