On invoke dynamic and method handles

Iulian Dragos jaguarul at gmail.com
Wed Dec 17 14:16:11 PST 2008


On Wed, Dec 17, 2008 at 10:09 PM, John Rose <John.Rose at sun.com> wrote:
> The most recent version of JVM specs. (headed for HotSpot integration
> RSN) is here for engineering review:
>   http://webrev.invokedynamic.info/jrose/6655638.meth/
>
> That review copy is changing also; it's now a month old.

John, thanks for your answers. I had a look and things things become clearer.

We have two targets right now: short term, to evaluate performance
relative to reflection, and long term, to update the Scala compiler to
use the new features of the JVM. The short term goal is for a paper
about structural subtyping in Scala, due this Saturday :D. That means
we are stuck with the current state of the implementation. For the
long term goal, we'd be very interested to 'be in the loop' and try
things early.

> The new instruction is (almost certainly) going to use the previously-
> unused bytecode point 0xba, will be a five-byte format with a two-
> byte CONSTANT_NameAndType index followed by two MBZ padding bytes
> (for possible interpreter use).  The type Dynamic (charming as it is)
> does not play a role in the bytecodes.

This is where we're heading. But the current implementation is using
the JSR292 convention, so for my tests I should still use it?

>>> The contract of 'bootstrap' is that it makes the call and returns a
>>> value, possibly setting a target for future calls. In the current
>>> implementation, one would have to create a new array and strip the
>>> first element:
>>>
>>> cs.setTarget(mh);
>>> Object[] args1 = new Object[args.length - 1];
>>> System.arraycopy(args, 1, args1, 0, args.length - 1);
>>> return rm.invoke(args[0], args1);
>>>
>>> I find this to be a typical scenario, so I wonder why this deviation
>>> from the JSR.
>
> It never made perfect sense to do things this way, because many dyn.
> langs. (see Groovy) use static methods as units of pluggable
> behavior.  But it was that way because the syntax for invokedynamic
> was receiver-based.  Now it is completely symmetric in all arguments.

Unfortunately (for us), Scala takes an opposite stance: there are no
static methods. But we can live with a slow first call, since we
should be able to resolve most calls and install a target.

I noticed a very useful method mentioned in the JSR is missing from
the implementation, MethodHandles.guardWithTest. I hope it will make
its way into the new spec. Our use case for invoke dynamic is to
resolve calls to methods we know they exist in the receiver, but the
receiver type does not show it. Resolved call sites are very likely to
change, as the receiver class might change, so it would be great to
have more fine grained control over invalidating call sites.

>> You can directly call a MethodHandle without put object in a array
>> by calling a invoke method with any arguments you want:
>> MethodHandle mh=...
>> mh.invoke(3,"foo");     // here 3 is not boxed
>
> You may also prefer to write signature-polymorphic code.  (Write
> once, run every case more slowly.)  To support this, the newest spec
> for method handles has a "varargs" bit on MethodType and appropriate
> adapter constructors.  So it's easy to spread or gather argument
> groups, independently of the reflective API, or in concert with it.

I see. I wanted to avoid changes in the type checker to treat
MethodHandle.invoke as special. But maybe that's the best solution.

One last question: does mlvm currently recognize the
BootstrapInvokeDynamic classfile attribute? My tests were
unsuccessful, so I'm wondering if my code generator is wrong, or I
need to resort to static initializers.

Thanks,
iulian


-- 
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais



More information about the mlvm-dev mailing list