On 05/19/2012 08:04 AM, Per Bothner wrote: > On 05/16/2012 05:52 PM, Charles Oliver Nutter wrote: > > Thanks for a detailed and helpful response! > >> On Wed, May 16, 2012 at 12:55 PM, Per Bothner<p...@bothner.com> wrote: >>> The attachment ProcUsingMH.java is a sketch of an alternative implementation >>> where each apply[01N] method has a matching MethodHandle field. The >>> apply[01N] >>> method is now final and just invokes the corresponding MethodHandle. >> I don't think this would optimize like you're hoping. > I'm not expecting a big performance gain. > I'm hoping for a slight gain getting rid of using a dispatch-switch, > partly because it avoids an extra indirection (and virtual dispatch), and > partly because (as you mentioned) HotSpot may have trouble > optimizing switches, at least large ones. > > To summarize my questions, before I actually try to implement this: > (1) A change to replace a virtual applyX method by a final method > that calls a InvokeMethod in a final field: My guess is this would > performancewise be more-or-less a wash, with neither major gain > or less. Is that likely? > (2) My guess is using the new MethodHandle scheme might be slighly > more efficient than using a switch on a "procedure-index". It be > be significantly more efficient in cases of big switch. Is that likely? > > I think there may be additional benefits to getting rid of the > dispatch-switch: More helpful exception stack traces; > plus avoiding the need to generate the dispatch classes. > >>> Finally, it seems that if Kawa in the future makes use of invokedynamic, >>> having the MethodHandles in the Procedure would be an advantage. >> We do keep a method handle in each method object, but only so we can >> more easily retrieve it and bind it to the invokedynamic call site. I >> don't think your'e going to see the performance gain you're hoping for >> with the Procedure object that aggregates handles. You really need the >> invokedynamic call site for the whole thing to optimize together well. > It probably makes sense to not implement a switch to using MethodHandles > until I have a design (roadmap) for using invokedynamic, since the > benefit of the former change is at best modest and probably not worth the > effort unless Kawa also makes use of invokedynamic. Does that match > your advice?
As Charles said, you will not see big gain to use method handle until you use invokedynamic, but I think it worth a test. Here a version of Procedure that doesn't use inheritance at all and that you be more or less backward compatible with code that are already compiled with Procedure. import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; class Procedure { public final MethodHandle mh; // Used for classical call. private MethodHandle varargsMH; // Used for varargs call, allocated lazily Procedure(MethodHandle mh) { this.mh = mh; } /** backward compatibility. */ public final Object apply0() throws Throwable { if (mh.type().parameterCount() != 0) throw new RuntimeException(); return mh.invokeExact(); } /** backward compatibility. */ public final Object apply1(Object arg1) throws Throwable { if (mh.type().parameterCount() != 1) throw new RuntimeException(); return mh.invokeExact(arg1); } /** backward compatibility. */ public final Object applyN(Object[] args) throws Throwable { MethodHandle varargsMH = this.varargsMH; if (varargsMH == null) { varargsMH = mh.asSpreader(Object[].class, mh.type().parameterCount()); } return varargsMH.invokeExact(args); } } class Builtins { public static final Object hash(Object arg1) { return arg1.hashCode(); } private static Procedure createProcedure(Lookup lookup, String name, int parameterCount) { MethodHandle mh; try { mh = lookup.findStatic(Builtins.class, name, MethodType.genericMethodType(parameterCount)); } catch (NoSuchMethodException | IllegalAccessException e) { throw (LinkageError)new LinkageError().initCause(e); } return new Procedure(mh); } static final Procedure hash; static { Lookup lookup = MethodHandles.lookup(); hash = createProcedure(lookup, "hash", 1); } } class Main { public static void main(String[] args) throws Throwable { // new way, get the method handle and call System.out.println(Builtins.hash.mh.invokeExact((Object)"foo")); // old way - apply1 System.out.println(Builtins.hash.apply1("foo")); // old way - applyN System.out.println(Builtins.hash.applyN(new Object[]{"foo"})); } } cheers, Rémi _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev