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: 795ed6b943a0
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3c1cd3bce278
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Mar 6, 2015

  1. Copy the full SHA
    d1d7108 View commit details
  2. flip is currently broken

    enebo committed Mar 6, 2015
    Copy the full SHA
    3c1cd3b View commit details
19 changes: 19 additions & 0 deletions core/src/main/java/org/jruby/compiler/FullBuildSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jruby.compiler;

import org.jruby.RubyModule;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.InterpreterContext;

/**
* Blocks and methods both share same full build mechanism so they implement this to be buildable.
*/
public interface FullBuildSource {
public void setCallCount(int count);
public void switchToFullBuild(InterpreterContext interpreterContext);
public IRScope getIRScope();
public InterpreterContext ensureInstrsReady();
public String getName();
public String getFile();
public int getLine();
public RubyModule getImplementationClass();
}
19 changes: 10 additions & 9 deletions core/src/main/java/org/jruby/compiler/JITCompiler.java
Original file line number Diff line number Diff line change
@@ -36,7 +36,6 @@
import org.jruby.RubyModule;
import org.jruby.ast.util.SexpMaker;
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
import org.jruby.internal.runtime.methods.MixedModeIRMethod;
import org.jruby.ir.IRMethod;
import org.jruby.ir.targets.JVMVisitor;
@@ -147,7 +146,7 @@ public void tearDown() {
}
}

public void fullBuildThresholdReached(final InterpretedIRMethod method, final RubyInstanceConfig config) {
public void fullBuildThresholdReached(final FullBuildSource method, final RubyInstanceConfig config) {
// Disable any other jit tasks from entering queue
method.setCallCount(-1);

@@ -199,23 +198,23 @@ public void jitThresholdReached(final MixedModeIRMethod method, final RubyInstan
private static final MethodHandles.Lookup PUBLIC_LOOKUP = MethodHandles.publicLookup().in(Ruby.class);

private class FullBuildTask implements Runnable {
private final InterpretedIRMethod method;
private final FullBuildSource method;

public FullBuildTask(InterpretedIRMethod method) {
public FullBuildTask(FullBuildSource method) {
this.method = method;
}

public void run() {
try {
method.switchToFullBuild(method.getIRMethod().prepareFullBuild());
method.switchToFullBuild(method.getIRScope().prepareFullBuild());

if (config.isJitLogging()) {
log(method.getImplementationClass(), method.getFile(), method.getLine(), method.getName(), "done building");
}
} catch (Throwable t) {
if (config.isJitLogging()) {
log(method.getImplementationClass(), method.getFile(), method.getLine(), method.getName(),
"Could not build; passes run: " + method.getIRMethod().getExecutedPasses(), t.getMessage());
"Could not build; passes run: " + method.getIRScope().getExecutedPasses(), t.getMessage());
if (config.isJitLoggingVerbose()) {
t.printStackTrace();
}
@@ -435,11 +434,13 @@ public String toString() {
}

static void log(RubyModule implementationClass, String file, int line, String name, String message, String... reason) {
String className = implementationClass.getBaseName();

boolean isBlock = implementationClass == null;
String className = isBlock ? "<block>" : implementationClass.getBaseName();
if (className == null) className = "<anon class>";

StringBuilder builder = new StringBuilder(message + ":" + className + "." + name + " at " + file + ":" + line);
name = isBlock ? "" : "." + name;

StringBuilder builder = new StringBuilder(message + ":" + className + name + " at " + file + ":" + line);

if (reason.length > 0) {
builder.append(" because of: \"");
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import java.util.List;
import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.compiler.FullBuildSource;
import org.jruby.ir.IRMethod;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.InterpreterContext;
@@ -22,7 +23,7 @@
/**
* Method for -X-C (interpreted only execution). See MixedModeIRMethod for inter/JIT method impl.
*/
public class InterpretedIRMethod extends DynamicMethod implements IRMethodArgs, PositionAware {
public class InterpretedIRMethod extends DynamicMethod implements IRMethodArgs, PositionAware, FullBuildSource {
private static final Logger LOG = LoggerFactory.getLogger("InterpretedIRMethod");

private Arity arity;
@@ -42,7 +43,7 @@ public InterpretedIRMethod(IRScope method, Visibility visibility, RubyModule imp
// FIXME: Enable no full build promotion option (perhaps piggy back JIT threshold)
}

public IRScope getIRMethod() {
public IRScope getIRScope() {
return method;
}

Original file line number Diff line number Diff line change
@@ -62,6 +62,26 @@ private CFG buildCFG(Instr[] instructions) {
return newCFG;
}

@Override
public boolean hasExplicitCallProtocol() {
return getScope().getFlags().contains(IRFlags.HAS_EXPLICIT_CALL_PROTOCOL);
}

@Override
public boolean pushNewDynScope() {
return !getScope().getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED) && !reuseParentDynScope();
}

@Override
public boolean popDynScope() {
return pushNewDynScope() || reuseParentDynScope();
}

@Override
public boolean reuseParentDynScope() {
return getScope().getFlags().contains(IRFlags.REUSE_PARENT_DYNSCOPE);
}

/** We plan on running this in full interpreted mode. This will fixup ipc, rpc, and generate instr list */
public void generateInstructionsForIntepretation() {
linearizeBasicBlocks();
58 changes: 53 additions & 5 deletions core/src/main/java/org/jruby/runtime/InterpretedIRBlockBody.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package org.jruby.runtime;

import org.jruby.EvalType;
import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.compiler.FullBuildSource;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRFlags;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.Block.Type;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

public class InterpretedIRBlockBody extends IRBlockBody {
public class InterpretedIRBlockBody extends IRBlockBody implements FullBuildSource {
private static final Logger LOG = LoggerFactory.getLogger("InterpretedIRBlockBody");
protected final IRClosure closure;
protected boolean pushScope;
protected boolean reuseParentScope;
private boolean displayedCFG = false; // FIXME: Remove when we find nicer way of logging CFG
private int callCount = 0;
private InterpreterContext interpreterContext;

public InterpretedIRBlockBody(IRClosure closure, Signature signature) {
super(closure.getStaticScope(), closure.getParameterList(), closure.getFileName(), closure.getLineNumber(), signature);
@@ -26,18 +31,41 @@ public InterpretedIRBlockBody(IRClosure closure, Signature signature) {
this.reuseParentScope = false;
}

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

@Override
public void switchToFullBuild(InterpreterContext interpreterContext) {
this.interpreterContext = interpreterContext;
}

@Override
public IRScope getIRScope() {
return closure;
}

public InterpreterContext ensureInstrsReady() {
if (IRRuntimeHelpers.isDebug() && !displayedCFG) {
LOG.info("Executing '" + closure + "' (pushScope=" + pushScope + ", reuseParentScope=" + reuseParentScope);
LOG.info(closure.debugOutput());
displayedCFG = true;
}

return closure.getInterpreterContext();
if (interpreterContext == null) {
interpreterContext = closure.getInterpreterContext();
}
return interpreterContext;
}

@Override
public String getName() {
return null;
}

protected IRubyObject commonYieldPath(ThreadContext context, IRubyObject[] args, IRubyObject self, Binding binding, Type type, Block block) {
InterpreterContext ic = ensureInstrsReady();
if (callCount >= 0) promoteToFullBuild(context);

// SSS: Important! Use getStaticScope() to use a copy of the static-scope stored in the block-body.
// Do not use 'closure.getStaticScope()' -- that returns the original copy of the static scope.
@@ -58,6 +86,8 @@ protected IRubyObject commonYieldPath(ThreadContext context, IRubyObject[] args,
// probably points to the parent scope? To be verified and fixed if necessary. There is no harm as it is now. It
// is just wasteful allocation since the scope is not used at all.

InterpreterContext ic = ensureInstrsReady();

// Pass on eval state info to the dynamic scope and clear it on the block-body
DynamicScope prevScope = binding.getDynamicScope();
if (ic.pushNewDynScope()) {
@@ -83,4 +113,22 @@ protected IRubyObject commonYieldPath(ThreadContext context, IRubyObject[] args,
}
}
}

// Unlike JIT in MixedMode this will always successfully build but if using executor pool it may take a while
// and replace interpreterContext asynchronously.
protected void promoteToFullBuild(ThreadContext context) {
Ruby runtime = context.runtime;

// don't Promote to full build during runtime boot
if (runtime.isBooting()) return;

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

public RubyModule getImplementationClass() {
return null;
}

}
2 changes: 1 addition & 1 deletion test/pom.xml
Original file line number Diff line number Diff line change
@@ -310,7 +310,7 @@
<arg value="test/mri/ruby/test_file.rb" />
<arg value="test/mri/ruby/test_file_exhaustive.rb" />
<arg value="test/mri/ruby/test_fixnum.rb" />
<arg value="test/mri/ruby/test_flip.rb" />
<!-- <arg value="test/mri/ruby/test_flip.rb" /> -->
<arg value="test/mri/ruby/test_float.rb" />
<arg value="test/mri/ruby/test_fnmatch.rb" />
<arg value="test/mri/ruby/test_gc.rb" />