JDK-8016582 : JSR 292 generic invoke needs to be fast
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: hs25,8,9,10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2013-06-13
  • Updated: 2018-10-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Description
The execution path through generic method handle invocation (MH.invoke not MH.invokeExact) involves complicate type tests which do not optimize well.
A generic call through a constant MH should fold up all argument adaptations into the call site as inlined operations.
A generic call through a non-constant but monomorphic MH should optimistically use inlined operations.  (See JDK-6919064 and JDK-8016581.)
A generic call through an arbitrary MH will be megamorphic, but should quickly locate and run through a well-optimized adapter stub before jumping into the MH.form.vmentry code.
Comments
It would help to have representative micro-benchmarks. Dynamically monomorphic MH.invoke calls should be fast enough, as of JDK-8024761: http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/44da760eed4b This "should be" should be tested, of course. A series of inexact (generic) calls to a single MH is "dynamically monomorphic" if the requested MethodType is always the same. In that particular case, the asTypeCache will hit cleanly, and the adapted MH will be reused and (we hope) inlined when necessary. (We should check that in fact the JIT is willing to use the asTypeCache if nothing better is available.) To make inexact invocation more robust, the single-element asTypeCache should be backed up by a slower cache, such that dynamically polymorphic calls (to a given MH) are processed without creating new lambda-forms, in the steady state (where the number if distinct requested MethodTypes is bounded). Moreover, the cache should be placed on the shared element (the non-customized LF) of the MH, so that the optimization can serve a stream of polymorphic calls to an open-ended population of MHs (where the number of distinct MTs and LFs is bounded). Moreover, the JIT should have same way to access these caches, or (perhaps) create its own wrapper logic, so that an inexact call to a given MH can be optimized even if (for whatever reason) a cached asType version is not available at JIT time.
02-03-2015

8-pool is an invalid affects version. Set 8 and hs25.
12-11-2013

If we from our side can make optimistic guesses (working on it), but hotspot also inlines and removes boxing for cases which are defacto primitive but compile time unprovable I think we have A LOT to gain. Finding invariant static type information in a JavaScript program is like finding oases in the desert, and we use what we have, but the most common case with no specialization is that YES IT IS A PRIMITIVE, but WE DON'T KNOW. See for example crypto.am3 which is called with almost integers only (and one object), but only in one of the 7 (or so) callsites can we prove at compile time that this is the case. Assuming that the callsite looks like the most narrow and primitive and adding guards as described in the previous comment gets us 25% extra performance on crypto, but I believe nowhere near where it would be if boxing was neatly removed and inlining aggressively done.
14-06-2013

I think this is very important, because the indys that we construct for JavaScript calls rarely have enough static type information to go on from the JavaScript compiler to avoid generic descriptors for all parameters, if we don't do optimistic callsite regeneration (which has problems of its own). The better inlining/boxing removal a generic invoke gets, the better. Typically we get a lot of calls like func(IILjava/lang/Object;) where the object parameter ALWAYS is a java.lang.Number instance like Integer or Double, even though we don't see that at compile time. Some performance can be gained by generating a specialized method based on the runtime type and adding a guard, checking that the Object parameter is still, say, a java.lang.Double as it was the last 1000 times we called this method. While this is faster, we still need a guard that adds overhead, and we still need boxing in order to implement the guard. I have a feeling we pay a LOT for this and it's quite simple to write microbenchmarks in JavaScript that illustrates this. Suggest a priority bump to P3 or higher.
14-06-2013