[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