[BSM-RETURNS-MH] allow invokedynamic BSM to return MethodHandle instead of CallSite

John Rose john.r.rose at oracle.com
Wed Oct 4 20:49:04 UTC 2017

Begin forwarded message:

As we use BSMs more and more, we will want to dispense with the CallSite
infrastructure, in many cases.  I filed an RFE to track this.  If we can agree
on specification, it will be fairly easy to implement.

(I am CC-ing this to valhalla-spec-experts, for visibility to non-OpenJDK people.)

— John

allow invokedynamic BSM to return MethodHandle instead of CallSite

Invokedynamic is defined to return a CallSite in order to allow a CallSite object to support per-call-site mutability, which enables certain advanced optimizations based on argument type speculation (aka. inline caching).

Also, for the same reason, invokedynamic instructions are individually linked, unlike other instructions which refer to the constant pool.  This allows each invokedynamic to operate on a separate "history" of type speculations, when the call site is mutable.

However, most uses of invokedynamic do not use these advanced degrees of freedom; most uses return a ConstantCallSite, and return the same call site (or an equivalent one) for each distinct occurrence of an invokedynamic.

This simpler use case can be referred to as "same CCS every time".  By contrast, the fully general case may be referred to as "possibly a different MCS each time".

We can reduce link overheads and footprint, as well as classfile complexity, if we support this simpler use case direct, instead of as an under-the-covers optimization of the full use case.

We can compatibly extend the JVM Specification, specifically as documented in the "package-info.java" javadoc for java.lang.invoke, by allowing a new behavior from a bootstrap method (BSM) which links an invokedynamic instruction.  This new behavior is simply to return a reference to a MethodHandle instead of a CallSite.  This is currently an illegal response, so it would be a compatible extension.

Specifically, if a MethodHandle is returned from a BSM call in response to linking an invokedynamic instruction, then the linkage of that dynamic call site would directly use the method handle.  In terms of the current specification, it would be as if the BSM had returned a ConstantCallSite wrapping the given method handle.  (Today's JVM can easily perform this optimization under the covers, also, discarding the CCS and just using the MH that it wraps.)

Also, if a BSM for a given CONSTANT_InvokeDynamic constant ever returns a MethodHandle (instead of a CallSite), then, as a new behavior, the JVM records the method handle permanently as the result of linking that constant pool constant.  Future linkage events that refer to the same constant pool entry (of type CONSTANT_InvokeDynamic) must then return the identical method handle, with no further calls to the BSM associated with that constant.

(Corner case:  In the case of race conditions, the present specification says that the JVM is obligated to pick one race winner and publish it as the overriding answer to all racing BSM invocations.  With respect to the proposed change, a race condition may propose a mix of MHs and CSs as potential winners. The JVM must choose a winner, as before, and the new semantics of permanent linkage apply if and only if the winner is an MH.  In such a case any competing CS results would be discarded; if a CS wins any competing MH results would be ignored.  Better luck next time.  If a given BSM always returns an MH, then races might occur but only one winner will apply for all call sites; this will be the common case.)

A side benefit of this extension would be bringing "indy" and "condy" (dynamic constants) closer together, in their linkage behavior.  It would be easier to share BSMs between the two instructions (invokedynamic and ldc).  Perhaps it would make it easier to converge the two facilities further in the future.
mlvm-dev mailing list
mlvm-dev at openjdk.java.net

More information about the valhalla-spec-observers mailing list