Skip to content

Commit

Permalink
Use a call site cache for JVM6 generated call sites for now.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Oct 23, 2014
1 parent a33c383 commit 67f4a90
Showing 1 changed file with 72 additions and 32 deletions.
104 changes: 72 additions & 32 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Expand Up @@ -27,10 +27,13 @@
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.callsite.CachingCallSite;
import org.jruby.runtime.callsite.FunctionalCachingCallSite;
import org.jruby.runtime.invokedynamic.InvokeDynamicSupport;
import org.jruby.util.ByteList;
import org.jruby.util.CodegenUtils;
import org.jruby.util.JavaNameMangler;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;

import java.math.BigInteger;
Expand Down Expand Up @@ -106,28 +109,39 @@ public void invokeOther(String name, int arity, boolean hasClosure) {
String outgoingSig;

if (hasClosure) {
if (arity == -1) {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, String.class, JVM.OBJECT_ARRAY, Block.class));
} else {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2, Block.class));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, String.class, JVM.OBJECT_ARRAY, Block.class));
switch (arity) {
default:
case -1:
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class));
break;
case 0:
case 1:
case 2:
case 3:
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity, Block.class));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity, Block.class));
break;
}
} else {
if (arity == -1) {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, String.class, JVM.OBJECT_ARRAY));
} else if (arity == 1) {
// specialize arity-1 calls through callMethod
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, String.class, JVM.OBJECT));
} else {
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, String.class, JVM.OBJECT_ARRAY));
switch (arity) {
default:
case -1:
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY));
break;
case 0:
case 1:
case 2:
case 3:
incomingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity));
outgoingSig = sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity));
break;
}
}

String methodName = "invokeOther" + getClassData().callSiteCount.getAndIncrement() + ":" + JavaNameMangler.mangleMethodName(name);

adapter2 = new SkinnyMethodAdapter(
adapter.getClassVisitor(),
Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
Expand All @@ -136,29 +150,55 @@ public void invokeOther(String name, int arity, boolean hasClosure) {
null,
null);

adapter2.aload(2);
adapter2.aload(0);
// call site object field
adapter.getClassVisitor().visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, methodName, ci(CachingCallSite.class), null, null).visitEnd();

// lazily construct it
adapter2.getstatic(getClassData().clsName, methodName, ci(CachingCallSite.class));
adapter2.dup();
Label doCall = new Label();
adapter2.ifnonnull(doCall);
adapter2.pop();
adapter2.newobj(p(FunctionalCachingCallSite.class));
adapter2.dup();
adapter2.ldc(name);

if (hasClosure) {
if (arity == -1) {
adapter2.invokespecial(p(FunctionalCachingCallSite.class), "<init>", sig(void.class, String.class));
adapter2.dup();
adapter2.putstatic(getClassData().clsName, methodName, ci(CachingCallSite.class));

// use call site to invoke
adapter2.label(doCall);
adapter2.aload(0); // context
adapter2.aload(1); // caller
adapter2.aload(2); // self

switch (arity) {
case -1:
case 1:
adapter2.aload(3);
adapter2.aload(4);
} else {
buildArrayFromLocals(adapter2, 3, arity);
adapter2.aload(3 + arity);
}
} else {
if (arity == -1) {
if (hasClosure) adapter2.aload(4);
break;
case 0:
if (hasClosure) adapter2.aload(3);
break;
case 2:
adapter2.aload(3);
} else if (arity == 1) {
adapter2.aload(4);
if (hasClosure) adapter2.aload(5);
break;
case 3:
adapter2.aload(3);
} else {
adapter2.aload(4);
adapter2.aload(5);
if (hasClosure) adapter2.aload(6);
break;
default:
buildArrayFromLocals(adapter2, 3, arity);
}
if (hasClosure) adapter2.aload(3 + arity);
break;
}

adapter2.invokeinterface(p(IRubyObject.class), "callMethod", outgoingSig);
adapter2.invokevirtual(p(CachingCallSite.class), "call", outgoingSig);
adapter2.areturn();
adapter2.end();

Expand Down

0 comments on commit 67f4a90

Please sign in to comment.