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

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Wed Mar 25 21:56:38 UTC 2015

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.

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

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