What can we improve in JSR292 for Java 9?

Marcus Lagergren marcus.lagergren at oracle.com
Tue Mar 3 11:12:28 UTC 2015


At the VM language summit at JFokus 2015, we discussed having ways to get new dynamic language functions into the JVM without having to resort to generating a class wrapping their byte code. A class is currently the smallest possible compilation unit for the JVM, and its installation carries various overheads. Installing a non-anonymous class, as a lot of our classes need to be, for security reasons, also involve synchronizing on the system dictionary, and it seems that runtime has just given up on fixing that particular bottleneck [1] (I don’t agree at all with the conclusions in the CR). 

Currently, in Nashorn, whenever we regenerate a method due to a failed assumption or type specialization, we need to generate a new byte code method, wrap it in a synthetic class created for just that purpose, and then installing the class.

When John and Vladimir were over in Stockholm we discussed a “magic” combinator that basically would allow you to create your own collection of MethodHandles for code versions of a callsite. Combined with constant pool indexes it would allow code installation without going through classes. New could would mean adding a {MethodHandle, ConstantPoolData} tuple to a particular callsite’s representation.

/M

[1] https://bugs.openjdk.java.net/browse/JDK-8046708
 
> On 26 Feb 2015, at 13:42, MacGregor, Duncan (GE Energy Management) <duncan.macgregor at ge.com> wrote:
> 
> MH.spreadArguments would certainly be useful from my point of view. We
> have many cases where we need to take a trailing argument array and turn
> it into some arguments, and array contain the remainder. This involves a
> depressing amount of shuffling at the moment, and should be better.
> 
> On 26/02/2015 02:29, "John Rose" <john.r.rose at oracle.com> wrote:
> 
>> On Feb 25, 2015, at 4:02 PM, Charles Oliver Nutter <headius at headius.com>
>> wrote:
>>> 
>>> After talking with folks at the Jfokus VM Summit, it seems like
>>> there's a number of nice-to-have and a few need-to-have features we'd
>>> like to see get into java.lang.invoke. Vladimir suggested I start a
>>> thread on these features.
>>> 
>>> A few from me:
>>> 
>>> * A loop handle :-)
>>> 
>>> Given a body and a test, run the body until the test is false. I'm
>>> guessing there's a good reason we don't have this already.
>> 
>> A few reasons:   1. You can code your own easily.
>> 2. There's no One True Loop the way there is a One True If.
>> The "run until test is false" model assumes all the real work is
>> done with side-effects, which are off-center from the MH model.
>> 3. A really clean looping mechanism probably needs a sprinkle
>> of tail call optimization.
>> 
>> I'm not saying that loops should never have side effects, but I
>> am saying that a loop mechanism should not mandate them.
>> 
>> Maybe this is general enough:
>> 
>>   MHs.loop(init, predicate, body)(*a)
>>   => { let i = init(*a); while (predicate(i, *a)) { i = body(i, *a); }
>> return i; }
>> 
>> ...where the type of i depends on init, and if init returns void then you
>> have a classic side-effect-only loop.
>> 
>>> * try/finally as a core atom of MethodHandles API.
>>> 
>>> Libraries like invokebinder provide a shortcut API To generating the
>>> large tree of handles needed for try/finally, but the JVM may not be
>>> able to optimize that tree as well as a purpose-built adapter.
>> 
>> I agree there.  We should put this in.
>> 
>>  MHs.tryFinally(target, cleanup)(*a)
>>    => { try { return target(*a); } finally { cleanup(*a); } }
>> 
>> (Even here there are non-universalities; what if the cleanup
>> wants to see the return value and/or the thrown exception?
>> Should it take those as one or two leading arguments?)
>> 
>>> * Argument grouping operations in the middle of the argument list.
>>> 
>>> JRuby has many signatures that vararg somewhere other than the end of
>>> the argument list, and the juggling required to do that logic in
>>> handles is complex: shift to-be-boxed args to end, box them, shift box
>>> back.
>> 
>> We now have MHs.collectArguments.  Do you want MHs.spreadArguments
>> to reverse the effect?  Or is there something else I'm missing?
>> 
>>> Another point about these more complicated forms: they're ESPECIALLY
>>> slow early in execution, before LFs have been compiled to bytecode.
>>> 
>>> * Implementation-specific inspection API.
>>> 
>>> I know there are different ways to express a MH tree on different JVMs
>>> (e.g. J9) but it would still be a big help for me if there were a good
>>> way to get some debug-time structural information about a handle I'm
>>> using. Hidden API would be ok if it's not too hidden :-)
>> 
>> Idea of the day:  An ASM-like library for method handles.
>> Make a MethodHandleReader which can run a visitor over the MH.
>> The ops of the visitor would be a selection of public MH operations
>> like filter, collect, spread, lookup, etc.
>> Also ASM-like, the library would have a MethodHandleWriter
>> would could be hooked up with the reader to make filters.
>> 
>> ‹ John
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> 
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev



More information about the mlvm-dev mailing list