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 

— 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 "" 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

Reply via email to