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: 674b3361ba79
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 54960e7bd5da
Choose a head ref
  • 9 commits
  • 12 files changed
  • 1 contributor

Commits on Sep 23, 2014

  1. Copy the full SHA
    dab281f View commit details
  2. Copy the full SHA
    cfd04bb View commit details
  3. Remove another rogue TC push.

    headius committed Sep 23, 2014
    Copy the full SHA
    016d339 View commit details
  4. Copy the full SHA
    a87d0c7 View commit details
  5. Copy the full SHA
    ea20ed6 View commit details
  6. Copy the full SHA
    86eff0e View commit details
  7. Copy the full SHA
    88caad9 View commit details
  8. Does it?

    headius committed Sep 23, 2014
    Copy the full SHA
    a12cc60 View commit details
  9. Copy the full SHA
    54960e7 View commit details
12 changes: 12 additions & 0 deletions core/src/main/java/org/jruby/RubyProc.java
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.JumpException;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.lexer.yacc.SimpleSourcePosition;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Binding;
@@ -73,6 +74,10 @@ protected RubyProc(Ruby runtime, RubyClass rubyClass, Block.Type type, ISourcePo
this.sourcePosition = sourcePosition;
}

protected RubyProc(Ruby runtime, RubyClass rubyClass, Block.Type type, String file, int line) {
this(runtime, rubyClass, type, new SimpleSourcePosition(file, line));
}

public static RubyClass createProcClass(Ruby runtime) {
RubyClass procClass = runtime.defineClass("Proc", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setProc(procClass);
@@ -106,6 +111,13 @@ public static RubyProc newProc(Ruby runtime, Block block, Block.Type type, ISour

return proc;
}

public static RubyProc newProc(Ruby runtime, Block block, Block.Type type, String file, int line) {
RubyProc proc = new RubyProc(runtime, runtime.getProc(), type, file, line);
proc.setup(block);

return proc;
}

/**
* Create a new instance of a Proc object. We override this method (from RubyClass)
11 changes: 7 additions & 4 deletions core/src/main/java/org/jruby/compiler/JITCompiler.java
Original file line number Diff line number Diff line change
@@ -206,11 +206,12 @@ public void run() {
}

String key = SexpMaker.sha1(method.getIRMethod());
JITClassGenerator generator = new JITClassGenerator(className, methodName, key, runtime, method, counts);
JVMVisitor visitor = new JVMVisitor();
JITClassGenerator generator = new JITClassGenerator(className, methodName, key, runtime, method, counts, visitor);

generator.compile();

Class sourceClass = JVMVisitor.defineFromBytecode(method.getIRMethod(), generator.bytecode(), new OneShotClassLoader(runtime.getJRubyClassLoader()));
Class sourceClass = visitor.defineFromBytecode(method.getIRMethod(), generator.bytecode(), new OneShotClassLoader(runtime.getJRubyClassLoader()));

if (sourceClass == null) {
// class could not be found nor generated; give up on JIT and bail out
@@ -290,7 +291,7 @@ public static String getHashForBytes(byte[] bytes) {
}

public static class JITClassGenerator {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, InterpretedIRMethod method, JITCounts counts) {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, InterpretedIRMethod method, JITCounts counts, JVMVisitor visitor) {
this.packageName = JITCompiler.RUBY_JIT_PREFIX;
if (RubyInstanceConfig.JAVA_VERSION == Opcodes.V1_7 || Options.COMPILE_INVOKEDYNAMIC.load() == true) {
// Some versions of Java 7 seems to have a bug that leaks definitions across cousin classloaders
@@ -310,6 +311,7 @@ public JITClassGenerator(String className, String methodName, String key, Ruby r
this.ruby = ruby;
this.counts = counts;
this.method = method;
this.visitor = visitor;
}

@SuppressWarnings("unchecked")
@@ -324,7 +326,7 @@ protected void compile() {

method.ensureInstrsReady();

bytecode = JVMVisitor.compileToBytecode(method.getIRMethod());
bytecode = visitor.compileToBytecode(method.getIRMethod());

counts.compiledCount.incrementAndGet();
counts.compileTime.addAndGet(System.nanoTime() - start);
@@ -362,6 +364,7 @@ public String toString() {
private final JITCounts counts;
private final String digestString;
private final InterpretedIRMethod method;
private final JVMVisitor visitor;

private byte[] bytecode;
private String name;
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/ir/Compiler.java
Original file line number Diff line number Diff line change
@@ -36,7 +36,8 @@ public static Compiler getInstance() {

@Override
protected Script execute(final Ruby runtime, final IRScope scope, JRubyClassLoader classLoader) {
final Class compiled = JVMVisitor.compile(scope, classLoader);
final JVMVisitor visitor = new JVMVisitor();
final Class compiled = visitor.compile(scope, classLoader);
final StaticScope staticScope = scope.getStaticScope();
final IRubyObject runtimeTopSelf = runtime.getTopSelf();
staticScope.setModule(runtimeTopSelf.getMetaClass());
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ public void simplifyOperands(Map<Operand, Operand> valueMap, boolean force) {
lambdaBody = (WrappedIRClosure) lambdaBody.getSimplifiedOperand(valueMap, force);
}

private WrappedIRClosure getLambdaBody() {
public WrappedIRClosure getLambdaBody() {
return lambdaBody;
}

@@ -86,12 +86,17 @@ public Object interpret(ThreadContext context, StaticScope currScope, DynamicSco
// JRUBY-5686: do this before executing so first time sets cref module
getLambdaBody().getClosure().getStaticScope().determineModule();

IRClosure body = getLambdaBody().getClosure();
// CON: This must not be happening, because nil would never cast to Block
// IRClosure body = getLambdaBody().getClosure();
// Block block = (Block) (body == null ? context.runtime.getIRManager().getNil() : getLambdaBody()).retrieve(context, self, currScope, currDynScope, temp);
Block block = (Block)getLambdaBody().retrieve(context, self, currScope, currDynScope, temp);
// ENEBO: Now can live nil be passed as block reference?
// SSS FIXME: Should we do the same %self retrieval as in the case of WrappedIRClosure? Or are lambdas special??
return RubyProc.newProc(context.runtime,
(Block) (body == null ? context.runtime.getIRManager().getNil() : getLambdaBody()).retrieve(context, self, currScope, currDynScope, temp),
Block.Type.LAMBDA, position);
block,
Block.Type.LAMBDA,
position.getFile(),
position.getLine());
}

@Override
11 changes: 9 additions & 2 deletions core/src/main/java/org/jruby/ir/instructions/CallBase.java
Original file line number Diff line number Diff line change
@@ -90,6 +90,10 @@ public CallType getCallType() {
return callType;
}

public boolean containsArgSplat() {
return containsArgSplat;
}

public void blockInlining() {
dontInline = true;
}
@@ -434,11 +438,14 @@ protected IRubyObject[] prepareArgumentsComplex(ThreadContext context, IRubyObje
// But when zsuper is converted to SuperInstr with known args, splats can appear anywhere
// in the list. So, this looping handles both these scenarios, although if we wanted to
// optimize for CallInstr which has splats only in the first position, we could do that.
List<IRubyObject> argList = new ArrayList<IRubyObject>();
List<IRubyObject> argList = new ArrayList<IRubyObject>(args.length * 2);
for (Operand arg : args) {
IRubyObject rArg = (IRubyObject) arg.retrieve(context, self, currScope, currDynScope, temp);
if (arg instanceof Splat) {
argList.addAll(Arrays.asList(((RubyArray) rArg).toJavaArray()));
RubyArray array = (RubyArray) rArg;
for (int i = 0; i < array.size(); i++) {
argList.add(array.eltOk(i));
}
} else {
argList.add(rArg);
}
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ public Object interpret(ThreadContext context, StaticScope currScope, DynamicSco
DynamicScope argsDynScope = currDynScope;

// Find args that need to be passed into super
// CON FIXME: Does this need to be done every time?
int i = 0, offset = 0;
while (!argsDynScope.getStaticScope().isArgumentScope()) {
argsDynScope = argsDynScope.getNextCapturedScope();
58 changes: 56 additions & 2 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -7,8 +7,11 @@
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.UndefinedMethod;
import org.jruby.ir.IRScope;
import org.jruby.ir.IRScopeType;
import org.jruby.ir.operands.IRException;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.Splat;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.javasupport.JavaUtil;
import org.jruby.parser.StaticScope;
@@ -188,7 +191,7 @@ public static IRubyObject handlePropagatedBreak(ThreadContext context, DynamicSc
}

// Used by JIT
public static void defCompiledIRMethod(ThreadContext context, MethodHandle handle, String rubyName, DynamicScope currDynScope, IRubyObject self, String scopeDesc,
public static void defCompiledIRMethod(ThreadContext context, MethodHandle handle, String rubyName, DynamicScope currDynScope, IRubyObject self, IRScope irScope, String scopeDesc,
String filename, int line, String parameterDesc, boolean hasExplicitCallProtocol) {
Ruby runtime = context.runtime;
StaticScope parentScope = currDynScope.getStaticScope();
@@ -198,14 +201,15 @@ public static void defCompiledIRMethod(ThreadContext context, MethodHandle handl
Visibility newVisibility = Helpers.performNormalMethodChecksAndDetermineVisibility(runtime, containingClass, rubyName, currVisibility);

StaticScope scope = Helpers.decodeScope(context, parentScope, scopeDesc);
scope.setIRScope(irScope);

DynamicMethod method = new CompiledIRMethod(handle, rubyName, filename, line, scope, newVisibility, containingClass, parameterDesc, hasExplicitCallProtocol);

Helpers.addInstanceMethod(containingClass, rubyName, method, currVisibility, context, runtime);
}

// Used by JIT
public static void defCompiledIRClassMethod(ThreadContext context, IRubyObject obj, MethodHandle handle, String rubyName, StaticScope parentScope, String scopeDesc,
public static void defCompiledIRClassMethod(ThreadContext context, IRubyObject obj, MethodHandle handle, String rubyName, StaticScope parentScope, IRScope irScope, String scopeDesc,
String filename, int line, String parameterDesc, boolean hasExplicitCallProtocol) {
Ruby runtime = context.runtime;

@@ -218,6 +222,7 @@ public static void defCompiledIRClassMethod(ThreadContext context, IRubyObject o
RubyClass containingClass = obj.getSingletonClass();

StaticScope scope = Helpers.decodeScope(context, parentScope, scopeDesc);
scope.setIRScope(irScope);

DynamicMethod method = new CompiledIRMethod(handle, rubyName, filename, line, scope, Visibility.PUBLIC, containingClass, parameterDesc, hasExplicitCallProtocol);

@@ -798,4 +803,53 @@ public static Object classSuper(ThreadContext context, IRubyObject self, IRubyOb
: method.call(context, self, superClass, methodName, args, block);
return rVal;
}

public static IRubyObject[] splatArguments(IRubyObject[] args, boolean[] splatMap) {
if (splatMap != null && splatMap.length > 0) {
int count = 0;
for (int i = 0; i < splatMap.length; i++) {
count += splatMap[i] ? ((RubyArray)args[i]).size() : 1;
}

IRubyObject[] newArgs = new IRubyObject[count];
int actualOffset = 0;
for (int i = 0; i < splatMap.length; i++) {
if (splatMap[i]) {
RubyArray ary = (RubyArray) args[i];
for (int j = 0; j < ary.size(); j++) {
newArgs[actualOffset++] = ary.eltOk(j);
}
} else {
newArgs[actualOffset++] = args[i];
}
}

args = newArgs;
}
return args;
}

public static String encodeSplatmap(boolean[] splatmap) {
if (splatmap == null) return "";
StringBuilder builder = new StringBuilder();
for (boolean b : splatmap) {
builder.append(b ? '1' : '0');
}
return builder.toString();
}

public static boolean[] buildSplatMap(Operand[] args, boolean containsArgSplat) {
boolean[] splatMap = new boolean[args.length];

if (containsArgSplat) {
for (int i = 0; i < args.length; i++) {
Operand operand = args[i];
if (operand instanceof Splat) {
splatMap[i] = true;
}
}
}

return splatMap;
}
}
Loading