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: cc2c0fb03eaf
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5d8a7a727f0c
Choose a head ref
  • 10 commits
  • 5 files changed
  • 1 contributor

Commits on Oct 6, 2014

  1. Copy the full SHA
    7b8224c View commit details
  2. Copy the full SHA
    27f7e05 View commit details
  3. Copy the full SHA
    64156fa View commit details
  4. Copy the full SHA
    23add9f View commit details
  5. Fix up super forms in jvm6.

    headius committed Oct 6, 2014
    Copy the full SHA
    ffd13e4 View commit details
  6. Copy the full SHA
    db10ae5 View commit details
  7. Copy the full SHA
    c1f81d7 View commit details
  8. Implemeng bignum in jvm6.

    headius committed Oct 6, 2014
    Copy the full SHA
    21c0cf6 View commit details
  9. Copy the full SHA
    866adaf View commit details
  10. Copy the full SHA
    5d8a7a7 View commit details
Original file line number Diff line number Diff line change
@@ -24,7 +24,8 @@ public Instr cloneForInlining(InlinerInfo ii) {
public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) {
IRubyObject object = (IRubyObject) getTarget().retrieve(context, self, currScope, currDynScope, temp);

// FIXME: Why getRealClass? Document
// We store instance variable offsets on the real class, since instance var tables are associated with the
// natural type of an object.
RubyClass clazz = object.getMetaClass().getRealClass();

// FIXME: Should add this as a field for instruction
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -781,7 +781,7 @@ public static IRubyObject setCapturedVar(ThreadContext context, IRubyObject matc
return val;
}

public static IRubyObject instanceSuperSplatArgs(ThreadContext context, IRubyObject self, String methodName, RubyClass definingModule, IRubyObject[] args, Block block, boolean[] splatMap) {
public static IRubyObject instanceSuperSplatArgs(ThreadContext context, IRubyObject self, String methodName, RubyModule definingModule, IRubyObject[] args, Block block, boolean[] splatMap) {
return instanceSuper(context, self, methodName, definingModule, splatArguments(args, splatMap), block);
}

@@ -793,7 +793,7 @@ public static IRubyObject instanceSuper(ThreadContext context, IRubyObject self,
return rVal;
}

public static IRubyObject classSuperSplatArgs(ThreadContext context, IRubyObject self, String methodName, RubyClass definingModule, IRubyObject[] args, Block block, boolean[] splatMap) {
public static IRubyObject classSuperSplatArgs(ThreadContext context, IRubyObject self, String methodName, RubyModule definingModule, IRubyObject[] args, Block block, boolean[] splatMap) {
return classSuper(context, self, methodName, definingModule, splatArguments(args, splatMap), block);
}

42 changes: 42 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter.java
Original file line number Diff line number Diff line change
@@ -266,12 +266,52 @@ public org.objectweb.asm.Label newLabel() {
*/
public abstract void invokeSelf(String name, int arity, boolean hasClosure);

/**
* Invoke a superclass method from an instance context.
*
* Stack required: context, caller, self, start class, arguments[, block]
*
* @param name name of the method to invoke
* @param arity arity of the arguments on the stack
* @param hasClosure whether a block is passed
* @param splatmap a map of arguments to be splatted back into arg list
*/
public abstract void invokeInstanceSuper(String name, int arity, boolean hasClosure, boolean[] splatmap);

/**
* Invoke a superclass method from a class context.
*
* Stack required: context, caller, self, start class, arguments[, block]
*
* @param name name of the method to invoke
* @param arity arity of the arguments on the stack
* @param hasClosure whether a block is passed
* @param splatmap a map of arguments to be splatted back into arg list
*/
public abstract void invokeClassSuper(String name, int arity, boolean hasClosure, boolean[] splatmap);

/**
* Invoke a superclass method from an unresolved context.
*
* Stack required: context, caller, self, arguments[, block]
*
* @param name name of the method to invoke
* @param arity arity of the arguments on the stack
* @param hasClosure whether a block is passed
* @param splatmap a map of arguments to be splatted back into arg list
*/
public abstract void invokeUnresolvedSuper(String name, int arity, boolean hasClosure, boolean[] splatmap);

/**
* Invoke a superclass method from a zsuper in a block.
*
* Stack required: context, caller, self, arguments[, block]
*
* @param name name of the method to invoke
* @param arity arity of the arguments on the stack
* @param hasClosure whether a block is passed
* @param splatmap a map of arguments to be splatted back into arg list
*/
public abstract void invokeZSuper(String name, int arity, boolean hasClosure, boolean[] splatmap);

/**
@@ -332,6 +372,7 @@ public org.objectweb.asm.Label newLabel() {
* Store instance variable into self.
*
* Stack required: self, value
* Stack result: empty
*
* @param name name of variable to store
*/
@@ -341,6 +382,7 @@ public org.objectweb.asm.Label newLabel() {
* Load instance variable from self.
*
* Stack required: self
* Stack result: value from self
*
* @param name name of variable to load
*/
47 changes: 33 additions & 14 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@
import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyBignum;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyEncoding;
@@ -176,7 +177,7 @@ public static void buildArrayFromLocals(SkinnyMethodAdapter adapter2, int base,
adapter2.aload(base + i + j);
j++;
}
adapter2.pushInt(j);
adapter2.pushInt(i);
i += j;
adapter2.invokestatic(p(Helpers.class), "aastoreIRubyObjects", sig(IRubyObject[].class, params(IRubyObject[].class, IRubyObject.class, j, int.class)));
}
@@ -195,26 +196,28 @@ public void invokeClassSuper(String name, int arity, boolean hasClosure, boolean
}

public void invokeUnresolvedSuper(String name, int arity, boolean hasClosure, boolean[] splatmap) {
performSuper(name, arity, hasClosure, splatmap, "unresolvedSuperSplatArgs", false);
performSuper(name, arity, hasClosure, splatmap, "unresolvedSuperSplatArgs", true);
}

public void invokeZSuper(String name, int arity, boolean hasClosure, boolean[] splatmap) {
performSuper(name, arity, hasClosure, splatmap, "zSuperSplatArgs", false);
performSuper(name, arity, hasClosure, splatmap, "zSuperSplatArgs", true);
}

private void performSuper(String name, int arity, boolean hasClosure, boolean[] splatmap, String helperName, boolean unresolved) {
SkinnyMethodAdapter adapter2;
String incomingSig;
String outgoingSig;

String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap);

if (hasClosure) {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, RubyModule.class, String.class, JVM.OBJECT_ARRAY, Block.class));
outgoingSig = unresolved ?
sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, JVM.OBJECT_ARRAY, Block.class, boolean[].class)) :
sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, String.class, RubyModule.class, JVM.OBJECT_ARRAY, Block.class, boolean[].class));
} else {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, RubyModule.class, String.class, JVM.OBJECT_ARRAY, Block.class));
outgoingSig = unresolved ?
sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, JVM.OBJECT_ARRAY, Block.class, boolean[].class)) :
sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class, String.class, RubyModule.class, JVM.OBJECT_ARRAY, Block.class, boolean[].class));
}

String methodName = "invokeSuper" + getClassData().callSiteCount.getAndIncrement() + ":" + JavaNameMangler.mangleMethodName(name);
@@ -232,25 +235,35 @@ private void performSuper(String name, int arity, boolean hasClosure, boolean[]
if (!unresolved) adapter2.ldc(name);
if (!unresolved) adapter2.aload(3);

buildArrayFromLocals(adapter2, 4, arity);

if (hasClosure) {
buildArrayFromLocals(adapter2, 4, arity);
adapter2.aload(4 + arity);
} else {
buildArrayFromLocals(adapter2, 4, arity);
adapter2.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}

adapter2.ldc(splatmapString);
invokeIRHelper("decodeSplatmap", sig(boolean[].class, String.class));
if (splatmap != null || splatmap.length > 0 || anyTrue(splatmap)) {
String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap);
adapter2.ldc(splatmapString);
adapter2.invokestatic(p(IRRuntimeHelpers.class), "decodeSplatmap", sig(boolean[].class, String.class));
} else {
adapter2.getstatic(p(IRRuntimeHelpers.class), "EMPTY_BOOLEAN_ARRAY", ci(boolean[].class));
}

invokeIRHelper(helperName, outgoingSig);
adapter2.invokestatic(p(IRRuntimeHelpers.class), helperName, outgoingSig);
adapter2.areturn();
adapter2.end();

// now call it
adapter.invokestatic(getClassData().clsName, methodName, incomingSig);
}

private static boolean anyTrue(boolean[] booleans) {
for (boolean b : booleans) if (b) return true;
return false;
}

public void searchConst(String name, boolean noPrivateConsts) {
adapter.ldc(name);
adapter.ldc(noPrivateConsts);
@@ -277,15 +290,21 @@ public void pushBoolean(boolean b) {
adapter.invokevirtual(p(Ruby.class), b ? "getTrue" : "getFalse", sig(RubyBoolean.class));
}

public void pushBignum(BigInteger bigint) { throw new RuntimeException("unimplemented for Java 6"); }
public void pushBignum(BigInteger bigint) {
String bigintStr = bigint.toString();

loadRuntime();
adapter.ldc(bigintStr);
adapter.invokestatic(p(RubyBignum.class), "newBignum", sig(RubyBignum.class, Ruby.class, String.class));
}

public void putField(String name) {
adapter.ldc(name);
invokeIRHelper("setInstanceVariable", sig(IRubyObject.class, IRubyObject.class, IRubyObject.class, String.class));
adapter.pop();
}

public void getField(String name) {
loadSelf();
loadRuntime();
adapter.ldc(name);
invokeHelper("getInstanceVariable", sig(IRubyObject.class, IRubyObject.class, Ruby.class, String.class));
25 changes: 11 additions & 14 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -764,10 +764,15 @@ private void compileCallCommon(IRBytecodeAdapter m, String name, Operand[] args,
m.loadContext();
m.loadSelf(); // caller
visit(receiver);

if (numArgs == 1 && args[0] instanceof Splat
|| CallBase.containsArgSplat(args)) {
throw new RuntimeException("splat in non-initial argument for normal call is unexpected in JIT");
int arity = numArgs;

if (numArgs == 1 && args[0] instanceof Splat) {
visit(args[0]);
m.adapter.invokevirtual(p(RubyArray.class), "toJavaArray", sig(IRubyObject[].class));
arity = -1;
} else if (CallBase.containsArgSplat(args)) {
arity = -1;
throw new RuntimeException("splat in non-initial argument for normal call is unsupported in JIT");
} else {
for (Operand operand : args) {
visit(operand);
@@ -783,10 +788,10 @@ private void compileCallCommon(IRBytecodeAdapter m, String name, Operand[] args,
switch (callType) {
case FUNCTIONAL:
case VARIABLE:
m.invokeSelf(name, numArgs, hasClosure);
m.invokeSelf(name, arity, hasClosure);
break;
case NORMAL:
m.invokeOther(name, numArgs, hasClosure);
m.invokeOther(name, arity, hasClosure);
break;
}

@@ -849,8 +854,6 @@ public void ClassSuperInstr(ClassSuperInstr classsuperinstr) {
m.loadContext();
visit(closure);
m.invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class));
} else {
m.adapter.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}

m.invokeClassSuper(name, args.length, hasClosure, splatMap);
@@ -1252,8 +1255,6 @@ public void InstanceSuperInstr(InstanceSuperInstr instancesuperinstr) {
m.loadContext();
visit(closure);
m.invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class));
} else {
m.adapter.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}

m.invokeInstanceSuper(name, args.length, hasClosure, splatMap);
@@ -1866,8 +1867,6 @@ public void UnresolvedSuperInstr(UnresolvedSuperInstr unresolvedsuperinstr) {
m.loadContext();
visit(closure);
m.invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class));
} else {
m.adapter.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}

m.invokeUnresolvedSuper(name, args.length, hasClosure, splatMap);
@@ -1920,8 +1919,6 @@ public void ZSuperInstr(ZSuperInstr zsuperinstr) {
m.loadContext();
visit(closure);
m.invokeIRHelper("getBlockFromObject", sig(Block.class, ThreadContext.class, Object.class));
} else {
m.adapter.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}

m.invokeZSuper(name, args.length, hasClosure, splatMap);