[9] Preliminary RFR (M): Emit direct call instead of linkTo* for recursive indy/MH.invoke* calls

Vladimir Kozlov vladimir.kozlov at oracle.com
Wed Mar 25 22:57:07 UTC 2015

On 3/25/15 2:56 PM, Vladimir Ivanov wrote:
> Thanks for the feedback, Vladimir.
>> Why JIT have to generate calls to linkToStatic() and not directly to
>> T.f1() when it knows already what is called?
> That's exactly what the fix is designed for - bypass
> MH.linkTo*/MH.invokeBasic linkers and call target method directly.
> It can be either direct call (both static and optimized virtual) or
> virtual call (IC or truly virtual).
> The change isn't trivial since VM can't find out what the target method
> is w/o help. SharedRuntime::resolve_{static,opt_virtual,virtual}_call_C
> inspect bytecode, but MH.linkTo*/MH.invokeBasic are completely opaque
> about what is called.
> That's why I have to attach a Method* which represents resolved method
> to such call sites.

Yes, I understand that runtime resolution code extract callee 
information from bytecode and constantpool where linkTo* is specified. I 
thought about direct static calls without using runtime resolution. But 
your code covers virtual calls too.

After thinking more about this and also talking to John I agree with 
your solution.

>> What about C1 changes?
> IMO it is not important for C1. It's a performance-driven change which
> mostly affects recursive calls.


Can it help in non-recursive calls? We don't inline for different 
reasons and your changes are general for all jsr292 call sites.

You have leftover in callGenerator.cpp:
+          if (UseNewCode) {


> Best regards,
> Vladimir Ivanov
>> thanks,
>> Vladimir K
>> On 3/25/15 10:38 AM, Vladimir Ivanov wrote:
>>> http://cr.openjdk.java.net/~vlivanov/8072008/webrev.00
>>> https://bugs.openjdk.java.net/browse/JDK-8072008
>>> I'd like to get early feedback on the approach I chose.
>>> So far, only x86 is supported. Other platforms are WIP.
>>> The idea is to get rid of MH.invokeBasic/linkTo* linkers when
>>> receiver/MemberName is constant, but VM doesn't inline target method.
>>> The problem with substituting a linker call with a direct/virtual call
>>> is that call site resolution relies on bytecode info (see
>>> SharedRuntime::resolve_{static,opt_virtual,virtual}_call_C). But on
>>> bytecode level the call site refers to linker method, which is almost
>>> useless.
>>> The idea of the fix is to attach additional metadata (Method*) to the
>>> call site, so VM can use it instead of querying bytecode. The metadata
>>> is placed in relocation table (static_call, opt_virtual_call,
>>> virtual_call relocation types) and contains a Method* the call site is
>>> resolved to by JIT compiler (_method from a call IR node).
>>> Example:
>>>    MemberName mn = ...; // compile-time constant
>>>    MethodHandle.linkToStatic(..., mn)
>>>    callq  0x0000000109cb1900  ; OopMap{off=28}
>>>                               ; *invokestatic linkToStatic
>>>                               ; - Test::invokeStatic at 3 (line 108)
>>>                               ; {static_call T.f1}
>>> It's call to MethodHandle.linkToStatic on bytecode level, but in
>>> generated code it's a direct call to T.f1.
>>> I enhanced diagnostic output to provide additional information call site
>>> targets when additional info is present.
>>> Also, for testing purposes, I introduced 2 new methods for whitebox
>>> testing:
>>>    - WhiteBox::clearInlineCaches
>>>    - WhiteBox::deoptimize
>>> Testing: JPRT, java/lang/invoke, nashorn, octane
>>> Thanks!
>>> Best regards,
>>> Vladimir Ivanov

More information about the hotspot-compiler-dev mailing list