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: 201b3c108eef
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 382748ca6b77
Choose a head ref

Commits on Oct 13, 2014

  1. Copy the full SHA
    b0d5193 View commit details
  2. Copy the full SHA
    f835015 View commit details
  3. [Truffle] Remove a couple inexistant methods.

    * GC.start, not ObjectSpace.start.
    * Time.time_s_from_array does not exist on Rubinius.
    eregon committed Oct 13, 2014
    Copy the full SHA
    a667249 View commit details
  4. [Truffle] Add the GC module.

    eregon committed Oct 13, 2014
    Copy the full SHA
    f444f8c View commit details
  5. Copy the full SHA
    754bf41 View commit details
  6. [Truffle] Rename RubyMethod.withNewVisibility to just withVisibility.

    * The semantics are better reflected with that name.
    eregon committed Oct 13, 2014
    Copy the full SHA
    4db3eb0 View commit details
  7. [Truffle] #initialize and #method_missing should be private.

    * And visibility checking for private with an explicit receiver is always false.
    eregon committed Oct 13, 2014
    Copy the full SHA
    0516e2f View commit details
  8. Copy the full SHA
    735be4a View commit details
  9. Copy the full SHA
    3a46dc1 View commit details
  10. Copy the full SHA
    e6ed0ad View commit details
  11. Copy the full SHA
    8fc5f6f View commit details
  12. Add new fake instr to hold intperpreter state. This instr is destined…

    … to only be instr 0 of the linearized instr list used only by the interpreter. It removes all remaining IRScope state knowledge from interpreter (not currently hooked up).
    enebo committed Oct 13, 2014
    Copy the full SHA
    645093e View commit details
  13. Boo. nested closures need unmolested parent scopes based on passes wh…

    …ich may replace parent variables with temp vars. We cannot use this simpler approach and will end up going the original full-clone route. Commented out cloning in prepareInstructions
    enebo committed Oct 13, 2014
    Copy the full SHA
    2718f60 View commit details
  14. Copy the full SHA
    4ce5caa View commit details
  15. Copy the full SHA
    774952c View commit details
  16. [Truffle] Fix special visibility for accessors on self

    * Such as self.foo=bar and self[foo]=bar
    eregon committed Oct 13, 2014
    Copy the full SHA
    be56d30 View commit details
  17. Copy the full SHA
    ca67379 View commit details
  18. Turn off requireFrame opt for now since it is buggy in some scenarios

    * Fixes some rubyspec failures when this is enabled.
    subbuss committed Oct 13, 2014
    Copy the full SHA
    2499589 View commit details
  19. Copy the full SHA
    f458e0c View commit details
  20. Copy the full SHA
    375d9ce View commit details
  21. Copy the full SHA
    c307409 View commit details
  22. Copy the full SHA
    0a70a39 View commit details

Commits on Oct 14, 2014

  1. Copy the full SHA
    07c0051 View commit details
  2. Copy the full SHA
    d787a8d View commit details
  3. Copy the full SHA
    5464669 View commit details
  4. Copy the full SHA
    0e06efc View commit details
  5. Copy the full SHA
    98c079b View commit details
  6. Copy the full SHA
    8beec2d View commit details
  7. Copy the full SHA
    37049ba View commit details
  8. Copy the full SHA
    1b2d9c1 View commit details
  9. Copy the full SHA
    0a16107 View commit details
  10. Copy the full SHA
    fa50615 View commit details
  11. Copy the full SHA
    905db5f View commit details
  12. Eliminate special-case break/nonlocal return handling for lambdas

    * Lambdas need to trap breaks/nonlocal-returns and terminate them.
      However, whether a block becomes a lambda or not is determined
      at runtime. So, only blocks that becomes lambdas need a try/catch
      to trap these breaks/nonlocal-returns. So far, in the interp,
      we used to tackle these by adding the try/catch at runtime on
      first execution.
    
    * This patch eliminates that runtime check and unconditionally
      adds the try/catch for all blocks (lambdas or not). Did this by
      uncommenting the unconditional handling that was there in
      IRBuilder.
    
      To make sure everything continued to work fine, fixed non-local
      return handling in IRReturnHelpers to ignore them if the
      blockType is not null (methods) or a lambda. This ensures
      that independent of what exists on the scope-stack, we only test
      for a matching non-local returns in lambdas or method scopes.
    
    * Had to fix up addition of global-ensure-blocks in store-local-var
      analysis to only add a GEB if one didn't already exist.
    
    * Eliminated all lambda-specific tests while preparing instructions
      for interpretation/JITting.
    
    * Unrelated:
      - Fixed toStringOutput of BacktickInstr
    subbuss committed Oct 14, 2014
    Copy the full SHA
    4a5d818 View commit details
  13. New {Closure,}InterpreterContext with all state interpreter needs to …

    …execute.
    
    This should eliminate nearly all contention between JIT and intepreter.  There is still
    one remaining bug involving label operands cloning when we don't want them to so
    instr cloning (last bit) is disabled atm.
    enebo committed Oct 14, 2014
    Copy the full SHA
    13cd181 View commit details
  14. Copy the full SHA
    6aefa72 View commit details
  15. Copy the full SHA
    382748c View commit details
Showing with 1,024 additions and 359 deletions.
  1. +3 −2 core/src/main/java/org/jruby/internal/runtime/methods/InterpretedIRMethod.java
  2. +29 −15 core/src/main/java/org/jruby/ir/IRBuilder.java
  3. +15 −45 core/src/main/java/org/jruby/ir/IRClosure.java
  4. +35 −62 core/src/main/java/org/jruby/ir/IRScope.java
  5. +1 −1 core/src/main/java/org/jruby/ir/IRScriptBody.java
  6. +13 −8 core/src/main/java/org/jruby/ir/dataflow/analyses/StoreLocalVarPlacementProblem.java
  7. +1 −1 core/src/main/java/org/jruby/ir/instructions/BacktickInstr.java
  8. +6 −0 core/src/main/java/org/jruby/ir/instructions/ConstMissingInstr.java
  9. +0 −4 core/src/main/java/org/jruby/ir/instructions/specialized/OneFixnumArgNoBlockCallInstr.java
  10. +0 −4 core/src/main/java/org/jruby/ir/instructions/specialized/OneOperandArgBlockCallInstr.java
  11. +0 −4 core/src/main/java/org/jruby/ir/instructions/specialized/OneOperandArgNoBlockCallInstr.java
  12. +0 −4 core/src/main/java/org/jruby/ir/instructions/specialized/OneOperandArgNoBlockNoResultCallInstr.java
  13. +0 −4 core/src/main/java/org/jruby/ir/instructions/specialized/ZeroOperandArgNoBlockCallInstr.java
  14. +24 −20 core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
  15. +3 −3 core/src/main/java/org/jruby/ir/interpreter/Profiler.java
  16. +47 −0 core/src/main/java/org/jruby/ir/operands/ClosureInterpreterContext.java
  17. +76 −0 core/src/main/java/org/jruby/ir/operands/InterpreterContext.java
  18. +1 −0 core/src/main/java/org/jruby/ir/operands/Label.java
  19. +16 −2 core/src/main/java/org/jruby/ir/operands/WrappedIRClosure.java
  20. +22 −3 core/src/main/java/org/jruby/ir/passes/AddCallProtocolInstructions.java
  21. +0 −1 core/src/main/java/org/jruby/ir/passes/AddLocalVarLoadStoreInstructions.java
  22. +0 −4 core/src/main/java/org/jruby/ir/representations/BasicBlock.java
  23. +3 −0 core/src/main/java/org/jruby/ir/representations/CFG.java
  24. +6 −4 core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
  25. +1 −1 core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
  26. +4 −7 core/src/main/java/org/jruby/runtime/InterpretedIRBlockBody.java
  27. +1 −1 core/src/main/java/org/jruby/truffle/nodes/RubyCallNode.java
  28. +101 −0 core/src/main/java/org/jruby/truffle/nodes/RubyValueProfile.java
  29. +22 −20 core/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
  30. +3 −2 core/src/main/java/org/jruby/truffle/nodes/core/BasicObjectNodes.java
  31. +2 −1 core/src/main/java/org/jruby/truffle/nodes/core/ClassNodes.java
  32. +2 −1 core/src/main/java/org/jruby/truffle/nodes/core/CoreMethodNodeManager.java
  33. +0 −30 core/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
  34. +73 −0 core/src/main/java/org/jruby/truffle/nodes/core/GCNodes.java
  35. +33 −0 core/src/main/java/org/jruby/truffle/nodes/core/IONodes.java
  36. +1 −1 core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  37. +3 −3 core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
  38. +2 −24 core/src/main/java/org/jruby/truffle/nodes/core/ObjectSpaceNodes.java
  39. +1 −1 core/src/main/java/org/jruby/truffle/nodes/core/TimeNodes.java
  40. +1 −1 core/src/main/java/org/jruby/truffle/nodes/dispatch/GenericDispatchNode.java
  41. +1 −1 core/src/main/java/org/jruby/truffle/nodes/dispatch/UnresolvedDispatchNode.java
  42. +2 −4 core/src/main/java/org/jruby/truffle/nodes/methods/AddMethodNode.java
  43. +11 −6 core/src/main/java/org/jruby/truffle/nodes/methods/AssertCompilationConstantNode.java
  44. +3 −1 core/src/main/java/org/jruby/truffle/nodes/methods/arguments/ReadPreArgumentNode.java
  45. +2 −0 core/src/main/java/org/jruby/truffle/nodes/objects/SelfNode.java
  46. +3 −11 core/src/main/java/org/jruby/truffle/runtime/RubyArguments.java
  47. +4 −2 core/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
  48. +1 −1 core/src/main/java/org/jruby/truffle/runtime/core/RubyModule.java
  49. +3 −13 core/src/main/java/org/jruby/truffle/runtime/methods/RubyMethod.java
  50. +2 −1 core/src/main/java/org/jruby/truffle/translator/BodyTranslator.java
  51. +0 −1 spec/truffle/tags/core/gc/garbage_collect_tags.txt
  52. +0 −1 spec/truffle/tags/core/gc/start_tags.txt
  53. +1 −0 spec/truffle/truffle.mspec
  54. +4 −1 test/pom.rb
  55. +4 −1 test/pom.xml
  56. +18 −0 test/truffle/pe/core/array_pe.rb
  57. +78 −3 test/truffle/pe/core/fixnum_pe.rb
  58. +70 −2 test/truffle/pe/core/float_pe.rb
  59. +18 −0 test/truffle/pe/core/hash_pe.rb
  60. +33 −0 test/truffle/pe/core/kernel/set_trace_func_pe.rb
  61. +18 −2 test/truffle/pe/core/symbol_pe.rb
  62. +14 −3 test/truffle/pe/core/truefalse_pe.rb
  63. +38 −0 test/truffle/pe/language/metaprogramming_pe.rb
  64. +37 −0 test/truffle/pe/macro/pushing_pixels_pe.rb
  65. +108 −21 test/truffle/pe/pe.rb
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.ir.*;
import org.jruby.ir.operands.InterpreterContext;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.runtime.IRRuntimeHelpers;
@@ -139,8 +140,8 @@ public void ensureInstrsReady() {
// SSS FIXME: Move this out of here to some other place?
// Prepare method if not yet done so we know if the method has an explicit/implicit call protocol
if (method.getInstrsForInterpretation() == null) {
method.prepareForInterpretation(false);
this.pushScope = !method.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);
InterpreterContext context = method.prepareForInterpretation();
this.pushScope = !context.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);
}
}

44 changes: 29 additions & 15 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -212,6 +212,10 @@ public void addInstr(Instr i) {
instrs.add(i);
}

public void addInstrAtBeginning(Instr i) {
instrs.add(0, i);
}

public void emitBody(IRBuilder b, IRScope s) {
b.addInstr(s, new LabelInstr(start));
for (Instr i: instrs) {
@@ -293,6 +297,16 @@ public void addInstr(IRScope s, Instr i) {
}
}

public void addInstrAtBeginning(IRScope s, Instr i) {
// If we are building an ensure body, stash the instruction
// in the ensure body's list. If not, add it to the scope directly.
if (ensureBodyBuildStack.empty()) {
s.addInstrAtBeginning(i);
} else {
ensureBodyBuildStack.peek().addInstrAtBeginning(i);
}
}

private Operand getImplicitBlockArg(IRScope s) {
int n = 0;
while (s != null && s instanceof IRClosure) {
@@ -505,8 +519,7 @@ public Operand buildLambda(LambdaNode node, IRScope s) {
// can be U_NIL if the node is an if node with returns in both branches.
if (closureRetVal != U_NIL) closureBuilder.addInstr(closure, new ReturnInstr(closureRetVal));

// Added as part of 'prepareForInterpretation' code.
// handleBreakAndReturnsInLambdas(closure);
handleBreakAndReturnsInLambdas(closure);

Variable lambda = s.createTemporaryVariable();
// SSS FIXME: Is this the right self here?
@@ -891,8 +904,8 @@ private void handleNonlocalReturnInMethod(IRScope s) {
//
// Add label and marker instruction in reverse order to the beginning
// so that the label ends up being the first instr.
s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(gebLabel));
s.addInstrAtBeginning(new LabelInstr(rBeginLabel));
addInstrAtBeginning(s, new ExceptionRegionStartMarkerInstr(gebLabel));
addInstrAtBeginning(s, new LabelInstr(rBeginLabel));
addInstr(s, new ExceptionRegionEndMarkerInstr());

// Receive exceptions (could be anything, but the handler only processes IRReturnJumps)
@@ -1970,19 +1983,13 @@ public void buildMultipleAsgn19Assignment(final MultipleAsgn19Node multipleAsgnN
}
}

/* ------------------------------------------------------------------
* This code is added on demand at runtime in the interpreter code.
* For JIT, this may have to be added always!
// These two methods could have been DRY-ed out if we had closures.
// For now, just duplicating code.
private void handleBreakAndReturnsInLambdas(IRClosure s) {
Label rBeginLabel = s.getNewLabel();
Label rEndLabel = s.getNewLabel();
Label rescueLabel = s.getNewLabel();
Label rescueLabel = Label.GLOBAL_ENSURE_BLOCK_LABEL;

// protect the entire body as it exists now with the global ensure block
s.addInstrAtBeginning(new ExceptionRegionStartMarkerInstr(rescueLabel));
addInstrAtBeginning(s, new ExceptionRegionStartMarkerInstr(rescueLabel));
addInstr(s, new ExceptionRegionEndMarkerInstr());

// Receive exceptions (could be anything, but the handler only processes IRBreakJumps)
@@ -1992,14 +1999,13 @@ private void handleBreakAndReturnsInLambdas(IRClosure s) {

// Handle break using runtime helper
// --> IRRuntimeHelpers.handleBreakAndReturnsInLambdas(context, scope, bj, blockType)
Variable ret = createTemporaryVariable();
addInstr(s, new RuntimeHelperCall(ret, "handleBreakAndReturnsInLambdas", new Operand[]{exc} ));
Variable ret = s.createTemporaryVariable();
addInstr(s, new RuntimeHelperCall(ret, RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} ));
addInstr(s, new ReturnInstr(ret));

// End
addInstr(s, new LabelInstr(rEndLabel));
}
* ------------------------------------------------------------------ */

public void receiveMethodArgs(final ArgsNode argsNode, IRScope s) {
receiveArgs(argsNode, s);
@@ -2524,6 +2530,14 @@ public Operand buildIter(final IterNode iterNode, IRScope s) {
closureBuilder.addInstr(closure, new ReturnInstr(closureRetVal));
}

// Always add break/return handling even though this
// is only required for lambdas, but we don't know at this time,
// if this is a lambda or not.
//
// SSS FIXME: At a later time, see if we can optimize this and
// do this on demand.
closureBuilder.handleBreakAndReturnsInLambdas(closure);

return new WrappedIRClosure(s.getSelf(), closure);
}

60 changes: 15 additions & 45 deletions core/src/main/java/org/jruby/ir/IRClosure.java
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@ public class IRClosure extends IRScope {

private Arity arity;
private int argumentType;
public boolean addedGEBForUncaughtBreaks;

/** Added for interp/JIT purposes */
private BlockBody body;
@@ -78,7 +77,6 @@ protected IRClosure(IRClosure c, IRScope lexicalParent, int closureId, String fu
} else {
this.body = new InterpretedIRBlockBody(this, c.body.arity(), c.body.getArgumentType());
}
this.addedGEBForUncaughtBreaks = false;
this.blockArgs = new ArrayList<Operand>();
this.arity = c.arity;
}
@@ -111,6 +109,21 @@ public IRClosure(IRManager manager, IRScope lexicalParent, int lineNumber, Stati
this.nestingDepth++;
}

public InterpreterContext getInterpreterContext(Operand self) {
initScope(false);

checkRelinearization();

if (interpreterContext != null) return interpreterContext; // Already prepared

Instr[] linearizedInstrArray = prepareInstructions();
interpreterContext = new ClosureInterpreterContext(getTemporaryVariablesCount(), getBooleanVariablesCount(),
getFixnumVariablesCount(), getFloatVariablesCount(),getFlags().clone(), linearizedInstrArray,
self, getStaticScope(), getBlockBody());

return interpreterContext;
}

public void setBeginEndBlock() {
this.isBeginEndBlock = true;
}
@@ -292,7 +305,6 @@ protected IRClosure cloneForInlining(CloneInfo ii, IRClosure clone) {
// FIXME: This is fragile. Untangle this state.
// Why is this being copied over to InterpretedIRBlockBody?
clone.setParameterList(this.parameterList);
clone.addedGEBForUncaughtBreaks = this.addedGEBForUncaughtBreaks;
clone.isBeginEndBlock = this.isBeginEndBlock;

SimpleCloneInfo clonedII = ii.cloneForCloningClosure(clone);
@@ -327,48 +339,6 @@ public IRClosure cloneForInlining(CloneInfo ii) {
return cloneForInlining(ii, clonedClosure);
}

// Add a global-ensure-block to catch uncaught breaks
// This is usually required only if this closure is being
// used as a lambda, but it is safe to add this for any closure

protected boolean addGEBForUncaughtBreaks() {
// Nothing to do if already done
if (addedGEBForUncaughtBreaks) {
return false;
}

CFG cfg = cfg();
BasicBlock geb = cfg.getGlobalEnsureBB();
if (geb == null) {
geb = new BasicBlock(cfg, new Label("_GLOBAL_ENSURE_BLOCK", 0));
Variable exc = createTemporaryVariable();
geb.addInstr(new ReceiveJRubyExceptionInstr(exc)); // JRuby implementation exception
// Handle uncaught break and non-local returns using runtime helpers
Variable ret = createTemporaryVariable();
geb.addInstr(new RuntimeHelperCall(ret,
RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} ));
geb.addInstr(new ReturnInstr(ret));
cfg.addGlobalEnsureBB(geb);
} else {
// SSS FIXME: Assumptions:
//
// First instr is a 'ReceiveExceptionBase'
// Last instr is a 'ThrowExceptionInstr' -- replaced by handleBreakAndReturnsInLambdas

List<Instr> instrs = geb.getInstrs();
Variable exc = ((ReceiveExceptionBase)instrs.get(0)).getResult();
Variable ret = createTemporaryVariable();
instrs.set(instrs.size()-1, new RuntimeHelperCall(ret,
RuntimeHelperCall.Methods.HANDLE_BREAK_AND_RETURNS_IN_LAMBDA, new Operand[]{exc} ));
geb.addInstr(new ReturnInstr(ret));
}

// Update scope
addedGEBForUncaughtBreaks = true;

return true;
}

@Override
public void setName(String name) {
// We can distinguish closures only with parent scope name
Loading