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: 0f9c2a32f210
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 01f9f01d7647
Choose a head ref
  • 4 commits
  • 8 files changed
  • 1 contributor

Commits on Sep 25, 2017

  1. Copy the full SHA
    f4326bd View commit details
  2. Copy the full SHA
    d2523b7 View commit details
  3. Copy the full SHA
    d1bed31 View commit details
  4. Copy the full SHA
    01f9f01 View commit details
Original file line number Diff line number Diff line change
@@ -86,9 +86,8 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod jittedMethod = actualMethod;
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, args, block);
} else {
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, args, block);
}
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, args, block);
}

private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext ic, RubyModule implClass,
@@ -120,9 +119,8 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod jittedMethod = actualMethod;
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, block);
} else {
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, block);
}
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, block);
}

private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext ic, RubyModule implClass,
@@ -154,9 +152,8 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod jittedMethod = actualMethod;
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, block);
} else {
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, block);
}
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, block);
}

private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext ic, RubyModule implClass,
@@ -188,9 +185,8 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod jittedMethod = actualMethod;
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, arg1, block);
} else {
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, block);
}
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, block);
}

private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext ic, RubyModule implClass,
@@ -221,9 +217,8 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
DynamicMethod jittedMethod = actualMethod;
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, arg1, arg2, block);
} else {
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, arg2, block);
}
return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, arg2, block);
}

private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext ic, RubyModule implClass,
@@ -247,7 +242,7 @@ private IRubyObject INTERPRET_METHOD(ThreadContext context, InterpreterContext i

}

protected void doDebug() {
private void doDebug() {
// FIXME: This is printing out IRScope CFG but JIT may be active and it might not reflect
// currently executing. Move into JIT and into interp since they will be getting CFG from
// different sources
@@ -263,21 +258,20 @@ protected void doDebug() {

@Override
public void completeBuild(DynamicMethod newMethod) {
actualMethod = newMethod;
newMethod.serialNumber = this.serialNumber;
setCallCount(-1);
newMethod.serialNumber = this.serialNumber;
actualMethod = newMethod;
getImplementationClass().invalidateCacheDescendants();
}

private void tryJit(ThreadContext context) {
// don't JIT during runtime boot
if (!context.runtime.isBooting() && !Options.JIT_KERNEL.load()) {
synchronized (this) {
if (callCount >= 0) {
if (callCount++ >= Options.JIT_THRESHOLD.load()) {
context.runtime.getJITCompiler().buildThresholdReached(context, this);
}
}
if (context.runtime.isBooting() && !Options.JIT_KERNEL.load()) return; // don't JIT during runtime boot

synchronized (this) {
int callCount = this.callCount;
if (callCount >= 0 && callCount++ >= Options.JIT_THRESHOLD.load()) {
this.callCount = callCount;
context.runtime.getJITCompiler().buildThresholdReached(context, this);
}
}
}
@@ -316,4 +310,5 @@ public void setCallCount(int callCount) {
this.callCount = callCount;
}
}

}
5 changes: 3 additions & 2 deletions core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
Original file line number Diff line number Diff line change
@@ -4,7 +4,6 @@
import java.util.List;
import org.jruby.EvalType;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.RubyModule;
import org.jruby.RubyString;
import org.jruby.ast.RootNode;
@@ -33,7 +32,9 @@
import org.jruby.util.log.LoggerFactory;

public class Interpreter extends IRTranslator<IRubyObject, IRubyObject> {
public static final Logger LOG = LoggerFactory.getLogger(Interpreter.class);

static final Logger LOG = LoggerFactory.getLogger(Interpreter.class);

public static final String ROOT = "(root)";
static int interpInstrsCount = 0;

Original file line number Diff line number Diff line change
@@ -32,7 +32,6 @@ public class InterpreterContext {

private final static InterpreterEngine DEFAULT_INTERPRETER = new InterpreterEngine();
private final static InterpreterEngine STARTUP_INTERPRETER = new StartupInterpreterEngine();
private final static InterpreterEngine SIMPLE_METHOD_INTERPRETER = new InterpreterEngine();

public InterpreterEngine getEngine() {
if (engine == null) {
@@ -50,7 +49,7 @@ public InterpreterEngine getEngine() {
}

private InterpreterEngine engine;
public Callable<List<Instr>> instructionsCallback;
public final Callable<List<Instr>> instructionsCallback;

private IRScope scope;

@@ -63,13 +62,14 @@ public InterpreterContext(IRScope scope, List<Instr> instructions) {

this.metaClassBodyScope = scope instanceof IRMetaClassBody;
this.instructions = instructions != null ? prepareBuildInstructions(instructions) : null;
this.instructionsCallback = null; // engine != null
}

public InterpreterContext(IRScope scope, Callable<List<Instr>> instructions) throws Exception {
this.instructionsCallback = instructions;
this.scope = scope;

this.metaClassBodyScope = scope instanceof IRMetaClassBody;
this.instructionsCallback = instructions;
}

private void retrieveFlags() {
5 changes: 1 addition & 4 deletions core/src/main/java/org/jruby/ir/persistence/IRReader.java
Original file line number Diff line number Diff line change
@@ -55,11 +55,8 @@ public static IRScope load(IRManager manager, final IRReaderDecoder file) throws
final IRScope scope = pair.getKey();
final int instructionsOffset = pair.getValue();

// System.out.println("lazy");
scope.allocateInterpreterContext(new Callable<List<Instr>>() {
@Override
public List<Instr> call() throws Exception {
// System.out.println("eager");
public List<Instr> call() {
return file.decodeInstructionsAt(scope, instructionsOffset);
}
});
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/runtime/CompiledIRBlockBody.java
Original file line number Diff line number Diff line change
@@ -159,4 +159,10 @@ protected IRubyObject yieldDirect(ThreadContext context, Block block, IRubyObjec
return null; // not reached
}
}

@Override
protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.Type type, IRubyObject[] args, IRubyObject self, Block blockArg) {
throw new UnsupportedOperationException("commonYieldPath not implemented");
}

}
16 changes: 14 additions & 2 deletions core/src/main/java/org/jruby/runtime/IRBlockBody.java
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@
import org.jruby.RubyArray;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.builtin.IRubyObject;

@@ -193,8 +195,18 @@ public IRubyObject doYield(ThreadContext context, Block block, IRubyObject[] arg
return commonYieldPath(context, block, Block.Type.NORMAL, args, self, Block.NULL_BLOCK);
}

protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.Type type, IRubyObject[] args, IRubyObject self, Block blockArg) {
throw new RuntimeException("commonYieldPath not implemented in base class. We should never get here.");
protected abstract IRubyObject commonYieldPath(ThreadContext context, Block block, Block.Type type, IRubyObject[] args, IRubyObject self, Block blockArg) ;

static void postYield(ThreadContext context, InterpreterContext ic, Binding binding, Visibility oldVis, Frame prevFrame) {
// IMPORTANT: Do not clear eval-type in case this is reused in bindings!
// Ex: eval("...", foo.instance_eval { binding })
// The dyn-scope used for binding needs to have its eval-type set to INSTANCE_EVAL
binding.getFrame().setVisibility(oldVis);
if (ic.popDynScope()) {
context.postYield(binding, prevFrame);
} else {
context.postYieldNoScope(prevFrame);
}
}

public IRClosure getScope() {
14 changes: 4 additions & 10 deletions core/src/main/java/org/jruby/runtime/InterpretedIRBlockBody.java
Original file line number Diff line number Diff line change
@@ -139,15 +139,7 @@ protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.
return Interpreter.INTERPRET_BLOCK(context, block, self, ic, args, binding.getMethod(), blockArg);
}
finally {
// IMPORTANT: Do not clear eval-type in case this is reused in bindings!
// Ex: eval("...", foo.instance_eval { binding })
// The dyn-scope used for binding needs to have its eval-type set to INSTANCE_EVAL
binding.getFrame().setVisibility(oldVis);
if (ic.popDynScope()) {
context.postYield(binding, prevFrame);
} else {
context.postYieldNoScope(prevFrame);
}
postYield(context, ic, binding, oldVis, prevFrame);
}
}

@@ -156,7 +148,9 @@ protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.
private void promoteToFullBuild(ThreadContext context) {
if (context.runtime.isBooting() && !Options.JIT_KERNEL.load()) return; // don't Promote to full build during runtime boot

if (callCount++ >= Options.JIT_THRESHOLD.load()) context.runtime.getJITCompiler().buildThresholdReached(context, this);
if (callCount++ >= Options.JIT_THRESHOLD.load()) {
context.runtime.getJITCompiler().buildThresholdReached(context, this);
}
}

public RubyModule getImplementationClass() {
27 changes: 11 additions & 16 deletions core/src/main/java/org/jruby/runtime/MixedModeIRBlockBody.java
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@

public class MixedModeIRBlockBody extends IRBlockBody implements Compilable<CompiledIRBlockBody> {
private static final Logger LOG = LoggerFactory.getLogger(MixedModeIRBlockBody.class);

protected boolean pushScope;
protected boolean reuseParentScope;
private boolean displayedCFG = false; // FIXME: Remove when we find nicer way of logging CFG
@@ -51,12 +52,14 @@ public boolean canCallDirect() {

@Override
public void setCallCount(int callCount) {
this.callCount = callCount;
synchronized (this) {
this.callCount = callCount;
}
}

@Override
public void completeBuild(CompiledIRBlockBody blockBody) {
this.callCount = -1;
setCallCount(-1);
blockBody.evalType = this.evalType; // share with parent
this.jittedBody = blockBody;
}
@@ -122,6 +125,7 @@ protected IRubyObject yieldDirect(ThreadContext context, Block block, IRubyObjec
return jittedBody.yieldDirect(context, block, args, self);
}

@Override
protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.Type type, IRubyObject[] args, IRubyObject self, Block blockArg) {
if (callCount >= 0) promoteToFullBuild(context);

@@ -148,15 +152,7 @@ protected IRubyObject commonYieldPath(ThreadContext context, Block block, Block.
return Interpreter.INTERPRET_BLOCK(context, block, self, ic, args, binding.getMethod(), blockArg);
}
finally {
// IMPORTANT: Do not clear eval-type in case this is reused in bindings!
// Ex: eval("...", foo.instance_eval { binding })
// The dyn-scope used for binding needs to have its eval-type set to INSTANCE_EVAL
binding.getFrame().setVisibility(oldVis);
if (ic.popDynScope()) {
context.postYield(binding, prevFrame);
} else {
context.postYieldNoScope(prevFrame);
}
postYield(context, ic, binding, oldVis, prevFrame);
}
}

@@ -173,15 +169,14 @@ private void promoteToFullBuild(ThreadContext context) {
if (Options.JIT_LOGGING.load()) {
LOG.info("JIT failed; no protocol found in block: " + closure);
}
callCount = -1;
setCallCount(-1);
return;
}

synchronized (this) {
// check call count again
if (callCount < 0) return;

if (callCount++ >= Options.JIT_THRESHOLD.load()) {
int callCount = this.callCount;
if (callCount >= 0 && callCount++ >= Options.JIT_THRESHOLD.load()) {
this.callCount = callCount;
context.runtime.getJITCompiler().buildThresholdReached(context, this);
}
}