From e2ba1845d9f52a5261c39dd1e1306c9e182e70d4 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Wed, 15 Mar 2023 12:16:53 -0500 Subject: [PATCH] Move call info setup into indy sites This moves the update of call info state into the indy call site for all normal and super invocations. The call info update happens in a method handle "fold" combiner just prior to calling the target method body. --- .../ir/targets/indy/ArrayDerefInvokeSite.java | 2 +- .../jruby/ir/targets/indy/AsStringSite.java | 4 +- .../ir/targets/indy/ClassSuperInvokeSite.java | 5 +- .../indy/ClassSuperIterInvokeSite.java | 5 +- .../targets/indy/IndyInvocationCompiler.java | 46 ++++++++----------- .../targets/indy/InstanceSuperInvokeSite.java | 5 +- .../indy/InstanceSuperIterInvokeSite.java | 5 +- .../org/jruby/ir/targets/indy/InvokeSite.java | 43 +++++++++++++---- .../targets/indy/ResolvedSuperInvokeSite.java | 10 ++-- .../jruby/ir/targets/indy/SelfInvokeSite.java | 14 +++--- .../ir/targets/indy/SuperInvokeSite.java | 22 ++++----- .../indy/UnresolvedSuperInvokeSite.java | 5 +- .../indy/UnresolvedSuperIterInvokeSite.java | 5 +- .../ir/targets/indy/ZSuperInvokeSite.java | 5 +- .../ir/targets/simple/NormalInvokeSite.java | 14 +++--- .../runtime/invokedynamic/MathLinker.java | 4 +- 16 files changed, 110 insertions(+), 84 deletions(-) diff --git a/core/src/main/java/org/jruby/ir/targets/indy/ArrayDerefInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/ArrayDerefInvokeSite.java index c4bd99b245e..eb295855bd8 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/ArrayDerefInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/ArrayDerefInvokeSite.java @@ -31,7 +31,7 @@ */ public class ArrayDerefInvokeSite extends NormalInvokeSite { public ArrayDerefInvokeSite(MethodType type, String file, int line) { - super(type, "[]", false, file, line); + super(type, "[]", false, 0, file, line); } public static final Handle BOOTSTRAP = new Handle( diff --git a/core/src/main/java/org/jruby/ir/targets/indy/AsStringSite.java b/core/src/main/java/org/jruby/ir/targets/indy/AsStringSite.java index ca346992224..9fc9a64d4b3 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/AsStringSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/AsStringSite.java @@ -29,7 +29,7 @@ */ public class AsStringSite extends NormalInvokeSite { public AsStringSite(MethodType type, String file, int line) { - super(type, "to_s", false, file, line); + super(type, "to_s", false, 0, file, line); } public static final Handle BOOTSTRAP = new Handle( @@ -46,7 +46,7 @@ public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, Metho } public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, IRubyObject[] args, Block block) throws Throwable { - NormalInvokeSite toS = new NormalInvokeSite(type(), "to_s", false, file, line); + NormalInvokeSite toS = new NormalInvokeSite(type(), "to_s", false, 0, file, line); MethodHandle toS_handle = toS.dynamicInvoker(); MethodHandle checkcast = Binder.from(type().changeReturnType(boolean.class)) diff --git a/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperInvokeSite.java index 68be97fc6fd..29f16c53af5 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperInvokeSite.java @@ -12,8 +12,8 @@ * Created by headius on 10/23/14. */ public class ClassSuperInvokeSite extends ResolvedSuperInvokeSite { - public ClassSuperInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public ClassSuperInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } @Override @@ -26,6 +26,7 @@ protected RubyClass getSuperClass(RubyClass definingModule) { public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.classSuperSplatArgs(context, self, superName, definingModule, args, block, splatMap); } } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperIterInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperIterInvokeSite.java index 449a403ee60..7f5db24ea04 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperIterInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/ClassSuperIterInvokeSite.java @@ -12,8 +12,8 @@ * Created by headius on 10/23/14. */ public class ClassSuperIterInvokeSite extends ResolvedSuperInvokeSite { - public ClassSuperIterInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public ClassSuperIterInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } @Override @@ -26,6 +26,7 @@ protected RubyClass getSuperClass(RubyClass definingModule) { public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.classSuperIterSplatArgs(context, self, superName, definingModule, args, block, splatMap); } } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/IndyInvocationCompiler.java b/core/src/main/java/org/jruby/ir/targets/indy/IndyInvocationCompiler.java index 6eae7c18e6b..d28d80469d5 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/IndyInvocationCompiler.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/IndyInvocationCompiler.java @@ -41,18 +41,20 @@ public void invokeOther(String file, String scopeFieldName, CallBase call, int a return; } + int flags = call.getFlags(); + IRBytecodeAdapter.BlockPassType blockPassType = IRBytecodeAdapter.BlockPassType.fromIR(call); if (blockPassType.given()) { if (arity == -1) { - compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), CodegenUtils.sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), NormalInvokeSite.BOOTSTRAP, blockPassType.literal(), file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), CodegenUtils.sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), NormalInvokeSite.BOOTSTRAP, blockPassType.literal(), flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2, Block.class)), NormalInvokeSite.BOOTSTRAP, blockPassType.literal(), file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 2, Block.class)), NormalInvokeSite.BOOTSTRAP, blockPassType.literal(), flags, file, compiler.getLastLine()); } } else { if (arity == -1) { - compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY)), NormalInvokeSite.BOOTSTRAP, false, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT_ARRAY)), NormalInvokeSite.BOOTSTRAP, false, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity)), NormalInvokeSite.BOOTSTRAP, false, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invoke:" + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, JVM.OBJECT, arity)), NormalInvokeSite.BOOTSTRAP, false, flags, file, compiler.getLastLine()); } } } @@ -94,8 +96,6 @@ public void invokeOtherOneFloat(String file, CallBase call, double flote) { String signature = sig(IRubyObject.class, params(ThreadContext.class, IRubyObject.class, IRubyObject.class)); - setCallInfo(call.getFlags()); - compiler.adapter.invokedynamic( "floatOperator:" + JavaNameMangler.mangleMethodName(id), signature, @@ -124,21 +124,21 @@ public void invokeSelf(String file, String scopeFieldName, CallBase call, int ar return; } - setCallInfo(call.getFlags()); + int flags = call.getFlags(); String action = call.getCallType() == CallType.FUNCTIONAL ? "callFunctional" : "callVariable"; IRBytecodeAdapter.BlockPassType blockPassType = IRBytecodeAdapter.BlockPassType.fromIR(call); if (blockPassType != IRBytecodeAdapter.BlockPassType.NONE) { if (arity == -1) { - compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), SelfInvokeSite.BOOTSTRAP, blockPassType.literal(), file, compiler.getLastLine()); + compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT_ARRAY, Block.class)), SelfInvokeSite.BOOTSTRAP, blockPassType.literal(), flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 1, Block.class)), SelfInvokeSite.BOOTSTRAP, blockPassType.literal(), file, compiler.getLastLine()); + compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, arity + 1, Block.class)), SelfInvokeSite.BOOTSTRAP, blockPassType.literal(), flags, file, compiler.getLastLine()); } } else { if (arity == -1) { - compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT_ARRAY)), SelfInvokeSite.BOOTSTRAP, false, file, compiler.getLastLine()); + compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT_ARRAY)), SelfInvokeSite.BOOTSTRAP, false, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, arity)), SelfInvokeSite.BOOTSTRAP, false, file, compiler.getLastLine()); + compiler.adapter.invokedynamic(action + ':' + JavaNameMangler.mangleMethodName(id), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, arity)), SelfInvokeSite.BOOTSTRAP, false, flags, file, compiler.getLastLine()); } } } @@ -147,14 +147,12 @@ public void invokeInstanceSuper(String file, String name, int arity, boolean has if (arity > IRBytecodeAdapter.MAX_ARGUMENTS) throw new NotCompilableException("call to instance super has more than " + IRBytecodeAdapter.MAX_ARGUMENTS + " arguments"); - setCallInfo(flags); - String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap); if (hasClosure) { String operation = literalClosure ? "invokeInstanceSuperIter" : "invokeInstanceSuper"; - compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invokeInstanceSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invokeInstanceSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } } @@ -162,14 +160,12 @@ public void invokeClassSuper(String file, String name, int arity, boolean hasClo if (arity > IRBytecodeAdapter.MAX_ARGUMENTS) throw new NotCompilableException("call to class super has more than " + IRBytecodeAdapter.MAX_ARGUMENTS + " arguments"); - setCallInfo(flags); - String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap); if (hasClosure) { String operation = literalClosure ? "invokeClassSuperIter" : "invokeClassSuper"; - compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invokeClassSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invokeClassSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } } @@ -177,14 +173,12 @@ public void invokeUnresolvedSuper(String file, String name, int arity, boolean h if (arity > IRBytecodeAdapter.MAX_ARGUMENTS) throw new NotCompilableException("call to unresolved super has more than " + IRBytecodeAdapter.MAX_ARGUMENTS + " arguments"); - setCallInfo(flags); - String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap); if (hasClosure) { String operation = literalClosure ? "invokeUnresolvedSuperIter" : "invokeUnresolvedSuper"; - compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic(operation + ":" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invokeUnresolvedSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invokeUnresolvedSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } } @@ -192,13 +186,11 @@ public void invokeZSuper(String file, String name, int arity, boolean hasClosure if (arity > IRBytecodeAdapter.MAX_ARGUMENTS) throw new NotCompilableException("call to zsuper has more than " + IRBytecodeAdapter.MAX_ARGUMENTS + " arguments"); - setCallInfo(flags); - String splatmapString = IRRuntimeHelpers.encodeSplatmap(splatmap); if (hasClosure) { - compiler.adapter.invokedynamic("invokeZSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invokeZSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity, Block.class)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } else { - compiler.adapter.invokedynamic("invokeZSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, file, compiler.getLastLine()); + compiler.adapter.invokedynamic("invokeZSuper:" + JavaNameMangler.mangleMethodName(name), sig(JVM.OBJECT, params(ThreadContext.class, JVM.OBJECT, JVM.OBJECT, RubyClass.class, JVM.OBJECT, arity)), Bootstrap.invokeSuper(), splatmapString, flags, file, compiler.getLastLine()); } } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperInvokeSite.java index bb9240fcf1f..22330a9f621 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperInvokeSite.java @@ -12,8 +12,8 @@ * Created by headius on 10/23/14. */ public class InstanceSuperInvokeSite extends ResolvedSuperInvokeSite { - public InstanceSuperInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public InstanceSuperInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } @Override @@ -26,6 +26,7 @@ protected RubyClass getSuperClass(RubyClass definingModule) { public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.instanceSuperSplatArgs(context, self, superName, definingModule, args, block, splatMap); } } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperIterInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperIterInvokeSite.java index 2bdb814a6ab..308f27d8554 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperIterInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/InstanceSuperIterInvokeSite.java @@ -12,8 +12,8 @@ * Created by headius on 10/23/14. */ public class InstanceSuperIterInvokeSite extends ResolvedSuperInvokeSite { - public InstanceSuperIterInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public InstanceSuperIterInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } @Override @@ -26,6 +26,7 @@ protected RubyClass getSuperClass(RubyClass definingModule) { public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.instanceSuperIterSplatArgs(context, self, superName, definingModule, args, block, splatMap); } } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/InvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/InvokeSite.java index 38d53828007..033be8d1cdd 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/InvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/InvokeSite.java @@ -18,6 +18,7 @@ import org.jruby.internal.runtime.methods.DynamicMethod; import org.jruby.internal.runtime.methods.PartialDelegatingMethod; import org.jruby.ir.JIT; +import org.jruby.ir.runtime.IRRuntimeHelpers; import org.jruby.ir.targets.SiteTracker; import org.jruby.java.invokers.InstanceFieldGetter; import org.jruby.java.invokers.InstanceFieldSetter; @@ -46,6 +47,7 @@ import java.util.Map; import static java.lang.invoke.MethodHandles.constant; +import static java.lang.invoke.MethodHandles.foldArguments; import static java.lang.invoke.MethodHandles.insertArguments; import static java.lang.invoke.MethodHandles.lookup; import static org.jruby.runtime.invokedynamic.JRubyCallSite.SITE_ID; @@ -73,6 +75,7 @@ public abstract class InvokeSite extends MutableCallSite { public final boolean functional; protected final String file; protected final int line; + protected final int flags; private boolean boundOnce; private boolean literalClosure; protected CacheEntry cache = CacheEntry.NULL_CACHE; @@ -83,17 +86,14 @@ public String name() { public final CallType callType; - public InvokeSite(MethodType type, String name, CallType callType, String file, int line) { - this(type, name, callType, false, file, line); - } - - public InvokeSite(MethodType type, String name, CallType callType, boolean literalClosure, String file, int line) { + public InvokeSite(MethodType type, String name, CallType callType, boolean literalClosure, int flags, String file, int line) { super(type); this.methodName = name; this.callType = callType; this.literalClosure = literalClosure; this.file = file; this.line = line; + this.flags = flags; Signature startSig; @@ -232,6 +232,15 @@ private void finishBinding(CacheEntry entry, MethodHandle mh, IRubyObject self, .invoke(mh); } + SmartHandle callInfoWrapper; + SmartBinder baseBinder = SmartBinder.from(signature.changeReturn(void.class)).permute("context"); + if (flags == 0) { + callInfoWrapper = baseBinder.invokeVirtualQuiet(LOOKUP, "clearCallInfo"); + } else { + callInfoWrapper = baseBinder.append("flags", flags).invokeStaticQuiet(LOOKUP, IRRuntimeHelpers.class, "setCallInfo"); + } + mh = foldArguments(mh, callInfoWrapper.handle()); + updateInvocationTarget(mh, self, selfClass, entry.method, switchPoint); } @@ -239,6 +248,8 @@ private IRubyObject performIndirectCall(ThreadContext context, IRubyObject self, RubyModule sourceModule = entry.sourceModule; DynamicMethod method = entry.method; + IRRuntimeHelpers.setCallInfo(context, flags); + if (literalClosure) { try { if (methodMissing) { @@ -282,6 +293,8 @@ public IRubyObject fail(ThreadContext context, IRubyObject caller, IRubyObject s String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, args, block); } @@ -305,6 +318,8 @@ public IRubyObject failf(ThreadContext context, IRubyObject self, IRubyObject[] String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, args, block); } @@ -342,6 +357,8 @@ public IRubyObject fail(ThreadContext context, IRubyObject caller, IRubyObject s String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, block); } @@ -365,6 +382,8 @@ public IRubyObject failf(ThreadContext context, IRubyObject self, IRubyObject ar String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, block); } @@ -388,6 +407,8 @@ public IRubyObject fail(ThreadContext context, IRubyObject caller, IRubyObject s String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, arg1, block); } @@ -411,6 +432,8 @@ public IRubyObject failf(ThreadContext context, IRubyObject self, IRubyObject ar String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, arg1, block); } @@ -434,6 +457,8 @@ public IRubyObject fail(ThreadContext context, IRubyObject caller, IRubyObject s String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, arg1, arg2, block); } @@ -457,6 +482,8 @@ public IRubyObject failf(ThreadContext context, IRubyObject self, IRubyObject ar String name = methodName; CacheEntry entry = cache; + IRRuntimeHelpers.setCallInfo(context, flags); + if (entry.typeOk(selfClass)) { return entry.method.call(context, self, entry.sourceModule, name, arg0, arg1, arg2, block); } @@ -609,7 +636,7 @@ MethodHandle buildNewInstanceHandle(CacheEntry entry, IRubyObject self) { // Bind a second site as a dynamic invoker to guard against changes in new object's type MethodType type = type(); if (!functional) type = type.dropParameterTypes(1, 2); - CallSite initSite = SelfInvokeSite.bootstrap(LOOKUP, "callFunctional:initialize", type, literalClosure ? 1 : 0, file, line); + CallSite initSite = SelfInvokeSite.bootstrap(LOOKUP, "callFunctional:initialize", type, literalClosure ? 1 : 0, flags, file, line); MethodHandle initHandle = initSite.dynamicInvoker(); if (!functional) initHandle = MethodHandles.dropArguments(initHandle, 1, IRubyObject.class); @@ -655,7 +682,7 @@ MethodHandle buildNotEqualHandle(CacheEntry entry, IRubyObject self) { // unknown negatable call for us return null; } - equalSite = SelfInvokeSite.bootstrap(LOOKUP, negatedCall, type, literalClosure ? 1 : 0, file, line); + equalSite = SelfInvokeSite.bootstrap(LOOKUP, negatedCall, type, literalClosure ? 1 : 0, flags, file, line); if (equalSite != null) { // Bind a second site as a dynamic invoker to guard against changes in new object's type @@ -696,7 +723,7 @@ MethodHandle buildAliasHandle(CacheEntry entry, IRubyObject self) throws Throwab // Use a second site to mimic invocation from AliasMethod MethodType type = type(); if (!functional) type = type.dropParameterTypes(1, 2); - InvokeSite innerSite = (InvokeSite) SelfInvokeSite.bootstrap(LOOKUP, "callFunctional:" + name, type, literalClosure ? 1 : 0, file, line); + InvokeSite innerSite = (InvokeSite) SelfInvokeSite.bootstrap(LOOKUP, "callFunctional:" + name, type, literalClosure ? 1 : 0, flags, file, line); mh = innerSite.getHandle(self, new CacheEntry(innerMethod, entry.sourceModule, entry.token)); if (!functional) mh = MethodHandles.dropArguments(mh, 1, IRubyObject.class); diff --git a/core/src/main/java/org/jruby/ir/targets/indy/ResolvedSuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/ResolvedSuperInvokeSite.java index f8a6e3b133f..301d596021a 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/ResolvedSuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/ResolvedSuperInvokeSite.java @@ -18,14 +18,14 @@ public abstract class ResolvedSuperInvokeSite extends SelfInvokeSite { protected final String superName; protected final boolean[] splatMap; - public ResolvedSuperInvokeSite(MethodType type, String superName, String splatmapString, String file, int line) { - super(type, superName, CallType.SUPER, file, line); + public ResolvedSuperInvokeSite(MethodType type, String superName, String splatmapString, int flags, String file, int line) { + super(type, superName, CallType.SUPER, flags, file, line); this.superName = superName; this.splatMap = IRRuntimeHelpers.decodeSplatmap(splatmapString); } - public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String splatmapString, String file, int line) { + public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String splatmapString, int flags, String file, int line) { String[] targetAndMethod = name.split(":"); String superName = JavaNameMangler.demangleMethodName(targetAndMethod[1]); @@ -33,10 +33,10 @@ public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, Metho switch (targetAndMethod[0]) { case "invokeInstanceSuper": - site = new InstanceSuperInvokeSite(type, superName, splatmapString, file, line); + site = new InstanceSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeClassSuper": - site = new ClassSuperInvokeSite(type, superName, splatmapString, file, line); + site = new ClassSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; default: throw new RuntimeException("invalid super call: " + name); diff --git a/core/src/main/java/org/jruby/ir/targets/indy/SelfInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/SelfInvokeSite.java index eb8046885bd..f62e484ed22 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/SelfInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/SelfInvokeSite.java @@ -21,27 +21,27 @@ * Created by headius on 10/23/14. */ public class SelfInvokeSite extends InvokeSite { - public SelfInvokeSite(MethodType type, String name, CallType callType, boolean literalClosure, String file, int line) { - super(type, name, callType, literalClosure, file, line); + public SelfInvokeSite(MethodType type, String name, CallType callType, boolean literalClosure, int flags, String file, int line) { + super(type, name, callType, literalClosure, flags, file, line); } - public SelfInvokeSite(MethodType type, String name, CallType callType, String file, int line) { - this(type, name, callType, false, file, line); + public SelfInvokeSite(MethodType type, String name, CallType callType, int flags, String file, int line) { + this(type, name, callType, false, flags, file, line); } public static final Handle BOOTSTRAP = new Handle( Opcodes.H_INVOKESTATIC, p(SelfInvokeSite.class), "bootstrap", - sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, String.class, int.class), + sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, int.class, String.class, int.class), false); - public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int closureInt, String file, int line) { + public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int closureInt, int flags, String file, int line) { boolean literalClosure = closureInt != 0; List nameComponents = StringSupport.split(name, ':'); String methodName = JavaNameMangler.demangleMethodName(nameComponents.get(1)); CallType callType = nameComponents.get(0).equals("callFunctional") ? CallType.FUNCTIONAL : CallType.VARIABLE; - InvokeSite site = new SelfInvokeSite(type, methodName, callType, literalClosure, file, line); + InvokeSite site = new SelfInvokeSite(type, methodName, callType, literalClosure, flags, file, line); return InvokeSite.bootstrap(site, lookup); } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/SuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/SuperInvokeSite.java index 98e7962dcad..f018360cbe3 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/SuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/SuperInvokeSite.java @@ -26,8 +26,8 @@ public abstract class SuperInvokeSite extends SelfInvokeSite { protected final String superName; protected final boolean[] splatMap; - public SuperInvokeSite(MethodType type, String superName, String splatmapString, String file, int line) { - super(type, superName, CallType.SUPER, file, line); + public SuperInvokeSite(MethodType type, String superName, String splatmapString, int flags, String file, int line) { + super(type, superName, CallType.SUPER, flags, file, line); this.superName = superName; this.splatMap = IRRuntimeHelpers.decodeSplatmap(splatmapString); @@ -37,10 +37,10 @@ public SuperInvokeSite(MethodType type, String superName, String splatmapString, Opcodes.H_INVOKESTATIC, p(SuperInvokeSite.class), "bootstrap", - sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, String.class, int.class), + sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class, String.class, int.class), false); - public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String splatmapString, String file, int line) { + public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, String splatmapString, int flags, String file, int line) { List targetAndMethod = StringSupport.split(name, ':'); String superName = JavaNameMangler.demangleMethodName(targetAndMethod.get(1)); @@ -48,25 +48,25 @@ public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, Metho switch (targetAndMethod.get(0)) { case "invokeInstanceSuper": - site = new InstanceSuperInvokeSite(type, superName, splatmapString, file, line); + site = new InstanceSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeInstanceSuperIter": - site = new InstanceSuperIterInvokeSite(type, superName, splatmapString, file, line); + site = new InstanceSuperIterInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeClassSuper": - site = new ClassSuperInvokeSite(type, superName, splatmapString, file, line); + site = new ClassSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeClassSuperIter": - site = new ClassSuperIterInvokeSite(type, superName, splatmapString, file, line); + site = new ClassSuperIterInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeUnresolvedSuper": - site = new UnresolvedSuperInvokeSite(type, superName, splatmapString, file, line); + site = new UnresolvedSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeUnresolvedSuperIter": - site = new UnresolvedSuperIterInvokeSite(type, superName, splatmapString, file, line); + site = new UnresolvedSuperIterInvokeSite(type, superName, splatmapString, flags, file, line); break; case "invokeZSuper": - site = new ZSuperInvokeSite(type, superName, splatmapString, file, line); + site = new ZSuperInvokeSite(type, superName, splatmapString, flags, file, line); break; default: throw new RuntimeException("invalid super call: " + name); diff --git a/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperInvokeSite.java index 4cc32bc600d..8c0d86001be 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperInvokeSite.java @@ -12,13 +12,14 @@ * Created by headius on 10/23/14. */ public class UnresolvedSuperInvokeSite extends SuperInvokeSite { - public UnresolvedSuperInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public UnresolvedSuperInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.unresolvedSuperSplatArgs(context, self, args, block, splatMap); } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperIterInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperIterInvokeSite.java index 9392ec9fc5d..c2a755d5672 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperIterInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/UnresolvedSuperIterInvokeSite.java @@ -12,13 +12,14 @@ * Created by headius on 10/23/14. */ public class UnresolvedSuperIterInvokeSite extends SuperInvokeSite { - public UnresolvedSuperIterInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public UnresolvedSuperIterInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.unresolvedSuperIterSplatArgs(context, self, args, block, splatMap); } diff --git a/core/src/main/java/org/jruby/ir/targets/indy/ZSuperInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/indy/ZSuperInvokeSite.java index e7ee44dc972..a5e73d02c58 100644 --- a/core/src/main/java/org/jruby/ir/targets/indy/ZSuperInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/indy/ZSuperInvokeSite.java @@ -12,14 +12,15 @@ * Created by headius on 10/23/14. */ public class ZSuperInvokeSite extends SuperInvokeSite { - public ZSuperInvokeSite(MethodType type, String name, String splatmapString, String file, int line) { - super(type, name, splatmapString, file, line); + public ZSuperInvokeSite(MethodType type, String name, String splatmapString, int flags, String file, int line) { + super(type, name, splatmapString, flags, file, line); } public IRubyObject invoke(ThreadContext context, IRubyObject caller, IRubyObject self, RubyClass definingModule, IRubyObject[] args, Block block) throws Throwable { // TODO: get rid of caller // TODO: caching if (block == null || !block.isGiven()) block = context.getFrameBlock(); + IRRuntimeHelpers.setCallInfo(context, flags); return IRRuntimeHelpers.zSuperSplatArgs(context, self, args, block, splatMap); } diff --git a/core/src/main/java/org/jruby/ir/targets/simple/NormalInvokeSite.java b/core/src/main/java/org/jruby/ir/targets/simple/NormalInvokeSite.java index e136cfa2ed4..fef79175753 100644 --- a/core/src/main/java/org/jruby/ir/targets/simple/NormalInvokeSite.java +++ b/core/src/main/java/org/jruby/ir/targets/simple/NormalInvokeSite.java @@ -22,26 +22,26 @@ */ public class NormalInvokeSite extends InvokeSite { - public NormalInvokeSite(MethodType type, String name, boolean literalClosure, String file, int line) { - super(type, name, CallType.NORMAL, literalClosure, file, line); + public NormalInvokeSite(MethodType type, String name, boolean literalClosure, int flags, String file, int line) { + super(type, name, CallType.NORMAL, literalClosure, flags, file, line); } public static final Handle BOOTSTRAP = new Handle( Opcodes.H_INVOKESTATIC, p(NormalInvokeSite.class), "bootstrap", - sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, String.class, int.class), + sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, int.class, String.class, int.class), false); - public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int closureInt, String file, int line) { + public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int closureInt, int flags, String file, int line) { boolean literalClosure = closureInt != 0; String methodName = JavaNameMangler.demangleMethodName(StringSupport.split(name, ':').get(1)); - return newSite(lookup, methodName, type, literalClosure, file, line); + return newSite(lookup, methodName, type, literalClosure, flags, file, line); } - public static NormalInvokeSite newSite(MethodHandles.Lookup lookup, String methodName, MethodType type, boolean literalClosure, String file, int line) { - NormalInvokeSite site = new NormalInvokeSite(type, methodName, literalClosure, file, line); + public static NormalInvokeSite newSite(MethodHandles.Lookup lookup, String methodName, MethodType type, boolean literalClosure, int flags, String file, int line) { + NormalInvokeSite site = new NormalInvokeSite(type, methodName, literalClosure, flags, file, line); InvokeSite.bootstrap(site, lookup); diff --git a/core/src/main/java/org/jruby/runtime/invokedynamic/MathLinker.java b/core/src/main/java/org/jruby/runtime/invokedynamic/MathLinker.java index d0a06e57407..5c02c89e8ac 100644 --- a/core/src/main/java/org/jruby/runtime/invokedynamic/MathLinker.java +++ b/core/src/main/java/org/jruby/runtime/invokedynamic/MathLinker.java @@ -116,7 +116,7 @@ public static IRubyObject fixnumOperator(ThreadContext context, IRubyObject call // fall back on a normal call site MethodType fallbackType = site.type().appendParameterTypes(IRubyObject.class); - CallSite normalSite = NormalInvokeSite.newSite(LOOKUP, site.name, fallbackType, false, site.file(), site.line()); + CallSite normalSite = NormalInvokeSite.newSite(LOOKUP, site.name, fallbackType, false, 0, site.file(), site.line()); MethodHandle fallback = Binder.from(site.type()) .append(IRubyObject.class, runtime.newFixnum(value)) @@ -258,7 +258,7 @@ public static IRubyObject floatOperator(ThreadContext context, IRubyObject calle // fall back on a normal call site MethodType fallbackType = site.type().appendParameterTypes(IRubyObject.class); - CallSite normalSite = NormalInvokeSite.newSite(LOOKUP, site.name, fallbackType, false, site.file(), site.line()); + CallSite normalSite = NormalInvokeSite.newSite(LOOKUP, site.name, fallbackType, false, 0, site.file(), site.line()); MethodHandle fallback = Binder.from(site.type()) .append(IRubyObject.class, runtime.newFloat(value))