[9] RFR (S): 8148994: Replacing MH::invokeBasic with a direct call breaks LF customization
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Fri Feb 5 16:29:52 UTC 2016
Thanks, John.
On 2/4/16 9:52 PM, John Rose wrote:
> Looks good. Except I don't recall how is_inline interacts, if at all, with customization. It's not clear what is being gated, and which optimizations get let through.
Inlining through MH::invokeBasic doesn't happen when there's @DontInline
on the target. It is the case for GWT which has CountingWrapper on both
paths. It starts with a reinvoker.dontInline LF and then switches to a
reinvoker LF (after 30 invocations). If a compilation happens when
reinvoker.dontInline is used, a direct call is generated and even if the
branch becomes hot, all the calls goes through reinvoker.dontInline.
Update to reinvoker LF isn't visible unless the dispatch goes through
MH::invokeBasic linker.
I had an impression that I introduced LF customization logic to the
non-inlined case in GWT, but I can't find it in the code. So, it seems
the regression is caused by repeated checks performed by
reinvoker.dontInline LF and not by LF customization missed in generated
code.
Also, I stumbled upon a quirk in inlining policy: inlining through
linkers can't be delayed. It happens when JIT hits some limit on IR
size. So, right now inlining can stop in the middle of MH chain and a
linker call is generated.
But after JDK-8072008 there's no problem with delaying inlining. C2 can
decide whether to keep the direct call or inline through it. So, I
enabled late inlining for all linkers. (Surprisingly, no significant
performance difference on nashorn.)
So, I decided to keep invokeBasic linker call replacement for now, but
piggypack LF customization on the stuck counting LF.
Updated webrev:
http://cr.openjdk.java.net/~vlivanov/8148994/webrev.01/hotspot
http://cr.openjdk.java.net/~vlivanov/8148994/webrev.01/jdk
* enabled late inlining for linkers;
* add LF customization check in CountingWrapper::countDown, so when
counting is stuck, the target will be customized.
Testing: octane, JPRT.
I'm working on JDK-8071793 [1] and will reconsider how LF customization
on non-inlined branch in GWTs works given there is a more JVM-friendly
mechanism to control inlining. With the proposed fix
reinvoker.dontInline is never customized (only the target it points to)
and serves as a trampoline between GWT & target LF. It would be better
to jump right to the customized LF, if non-inlined branch becomes hot.
Best regards,
Vladimir Ivanov
[1] https://bugs.openjdk.java.net/browse/JDK-8071793
"Prune rarely called invokedynamic call sites during inlining"
>
> Maybe a comment about that would be useful
> Reviewed.
>
> – John
>
>> On Feb 4, 2016, at 7:51 AM, Vladimir Ivanov <vladimir.x.ivanov at oracle.com> wrote:
>>
>> http://cr.openjdk.java.net/~vlivanov/8148994/webrev.00
>> https://bugs.openjdk.java.net/browse/JDK-8148994
>>
>> JDK-8072008 [1] introduced an optimization to bypass linker calls in generated code when target method can't be inlined.
>>
>> Unfortunately, it doesn't work well with MH::invokeBasic(), because it clashes with LambdaForm customization: if a call is not inlined, it is important for performance to update (customize) corresponding LambdaForm on-the-fly. MH::invokeBasic() linker does MH -> LF -> Method* -> _from_compiled_entry traversal on every invocation, while direct call points right to the _from_compiled_entry. So, any LambdaForm updates aren't visible until recompilation.
>>
>> The fix is to keep MH::invokeBasic linker, so up-to-date LambdaForm instance is used on every invocation.
>>
>> Also, cleaned up relevant tests a bit.
>>
>> Testing: octane, JPRT.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>> [1] https://bugs.openjdk.java.net/browse/JDK-8072008
>> "Emit direct call instead of linkTo* for recursive indy/MH.invoke* calls"
More information about the core-libs-dev
mailing list