Invokedynamic Deep Dive -W-

From JVMLangSummit
Revision as of 11:30, 17 September 2009 by Jrose (talk | contribs) (New page: == Invocation Modes Issue == Shall MethodHandle support (a) an exactly typed invocation mode, (b) a freely converting invocation mode, or (c) both? (Default answer: (c).) Background: (a...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Invocation Modes Issue

Shall MethodHandle support (a) an exactly typed invocation mode, (b) a freely converting invocation mode, or (c) both? (Default answer: (c).)

Background:

(a) Power users want exact mode so they can know that they are getting full optimization. (b) Most use cases, however, can benefit from generic invocation (MHs.convertArguments conversions) and tolerate the modest performance hit.

Current RI state:

We have MH.invoke as exact invocation, and MHs.invoke as generic. Note that the first is virtual and the second is static. The second has no signature specialization magic.

Desired Specification:

(As arrived at in the mlvm workshop yesterday.)

Two virtual-final methods: MH.invokeExact, MH.invokeGeneric. Both have special Java language support. Also add (non-magic) MH.invokeVarargs, for symmetry (was a static in MHs). Retire the name MH.invoke (reserve for future use, in case we ever get closures and/or a better exception story).

// Example code
abstract class MethodHandle {
    final MethodType type();  //pre-existing
    //void invoke();  // no longer present

    // JVM-specific invokers, a minimal but complete kit:
    @PolymorphicSignature <R,A> abstract R invokeExact(A... args) throws Throwable;
    @PolymorphicSignature <R,A> abstract R invokeGeneric(A... args) throws Throwable;
    abstract  Object invokeVarargs(Object/*...*/ x, Object... va) throws Throwable;
}

Also, probably: Add a couple more virtual methods to MH to make MH a "microkernel" type, from which (in principle) all other statics in MHs may be derived. (Though Hotspot probably won't do this.) As Fredrik Öhrström points out, spread, collect, and argument binding combinators are enough. With these, you can always (a) capture an arbitrary (wild) incoming argument list into a Object array, then (b) pass that in a pre-bound virtual call to an argument processor object of your choice, and finally (c) re-spread the argument list to another arbitrary outgoing argument list. This assumes certain JVM optimizations on varargs processing.

// Example code
abstract class MethodHandle {
    ...
    // And maybe, for a microkernel:
    abstract MethodHandle insertArgument(Object x);
    // And then, to complete the microkernel:
    abstract MethodHandle collectArguments(MethodType newType);
    abstract MethodHandle spreadArguments(MethodType newType);
}