How to get rid of MethodHandle::linkTo* call when target method is known but not inlined?
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Fri Feb 13 21:46:58 UTC 2015
>> Do you suggest to create prelinked call site and skip fixup logic?
>
> That was my naive suggestion.
>
>> Considering VM sometimes resets call sites (e.g. class redefinition
>> happens), it becomes complicated. The call site should either stay
>> "resolvable" or special patching logic should be introduced.
>
> What happens currently, when we are calling linkToStatic with a constant
> MemberName, and the class gets redefined?
> Do we patch/reset the inline MemberName constant?
No, we don't touch the inlined constant, but vmtarget field is updated
instead (see MemberNameTable::adjust_method_entries).
Best regards,
Vladimir Ivanov
>
> dl
>
>> Best regards,
>> Vladimir Ivanov
>>
>> On 2/13/15 9:17 AM, Dean Long wrote:
>>> OK, I think I understand what you are suggesting. My idea is a little
>>> different. When you see
>>> "invokestatic MH.linkToStatic" in the bytecodes, and the MemberName is
>>> constant, how about
>>> if you extract the Method * from the MemberName, then generate a
>>> CallStaticJava? So you
>>> are basically inlining linkToStatic as a special case, regardless of the
>>> inlining depth.
>>>
>>> dl
>>>
>>> On 2/12/2015 1:09 AM, Vladimir Ivanov wrote:
>>>> Dean,
>>>>
>>>> No, the problem is not with detecting compile-time constants, but how
>>>> to pass that info to runtime in some situations.
>>>>
>>>> The code for some particular DirectMethodHandle is the following:
>>>> static int invokeStatic_005_I(java.lang.Object);
>>>> 0: aload_0
>>>> 1: invokestatic #16 // Method
>>>> java/lang/invoke/DirectMethodHandle.internalMemberName:(Ljava/lang/Object;)Ljava/lang/Object;
>>>>
>>>>
>>>> 4: astore_1
>>>> 5: aload_1
>>>> 6: checkcast #18 // class
>>>> java/lang/invoke/MemberName
>>>> 9: invokestatic #24 // Method
>>>> java/lang/invoke/MethodHandle.linkToStatic:(Ljava/lang/invoke/MemberName;)I
>>>>
>>>>
>>>> 12: ireturn
>>>>
>>>> If DMH is constant, it's easy to extract MemberName from it, and
>>>> compiler can inline the method this MemberName points to (see
>>>> CallGenerator::for_method_handle_inline):
>>>>
>>>> The problematic case is when the method MemberName points to isn't
>>>> inlined (for example, recursion depth is over the limit):
>>>> java.lang.invoke.LambdaForm$DMH005/359023572::invokeStatic_005_I (13
>>>> bytes) force inline by annotation
>>>> @ 1 java.lang.invoke.DirectMethodHandle::internalMemberName (8
>>>> bytes) force inline by annotation
>>>> @ 9 jsr292.RecursiveCall::f1 (4 bytes) recursive inlining is too
>>>> deep
>>>>
>>>> Right now, compiler stops at ::linkTo* call, and not at ::f1, though
>>>> MemberName is constant and embedded into the code:
>>>>
>>>> 0x000000010feeabfe: movabs $0x79561d2a0,%rdx ; {oop(a
>>>> 'java/lang/invoke/MemberName' = {method} {0x00000001180a3528} 'rec'
>>>> '(I)V' in 'jsr292/RecursiveCall')}
>>>> 0x000000010feeac08: nop
>>>> 0x000000010feeac09: nop
>>>> 0x000000010feeac0a: nop
>>>> 0x000000010feeac0b: callq 0x000000010fe49900 ; OopMap{off=48}
>>>>
>>>> It is either both ::linkTo* & target method are inlined or none of
>>>> them.
>>>>
>>>> What I want to get is a direct call to ::f1 instead. The problem is
>>>> fixup logic (SharedRuntime::find_callee_info()) doesn't know anything
>>>> about ::f1. What it sees in bytecode is ::linkTo* which is completely
>>>> opaque.
>>>>
>>>> The idea is to attach Method* (or MemberName?) to the nmethod and
>>>> associate it with the call site. SharedRuntime::find_callee_info() can
>>>> use it when it resolves the call site.
>>>>
>>>> Best regards,
>>>> Vladimir Ivanov
>>>>
>>>> On 2/12/15 4:09 AM, Dean Long wrote:
>>>>> I'm not an expert, but it appears that we generate code for linkTo*
>>>>> intrinsics using the assembler, so the compiler,
>>>>> which is good at detecting compile-time constants, isn't allowed to do
>>>>> what it's good at. What if we implement
>>>>> all linkTo* intrinsics (or linkToStatic at least) using IR instead?
>>>>>
>>>>> dl
>>>>>
>>>>> On 2/11/2015 3:37 PM, Vladimir Ivanov wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I'm looking at JDK-8072008 [1]. The idea is to get rid of linkTo*
>>>>>> call
>>>>>> when MemberName is a compile-time constant, but target method isn't
>>>>>> inlined. Direct call to target method is issued instead. It should
>>>>>> help recursive calls, for example.
>>>>>>
>>>>>> The problem is that compiled call sites start in unlinked state and
>>>>>> runtime lacks information to patch them with a correct method
>>>>>> (what it
>>>>>> sees during fixup is just a linkTo* call).
>>>>>>
>>>>>> The only way I see how to get call site linking working is to attach
>>>>>> pre-resolved target method (Method*) to the nmethod and make fixup
>>>>>> logic aware of it, so it can skip bytecode inspection step (in
>>>>>> SharedRuntime::find_callee_info()).
>>>>>>
>>>>>> Do you see any problems with such approach?
>>>>>> Any other ideas how to fix original problem?
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> Best regards,
>>>>>> Vladimir Ivanov
>>>>>>
>>>>>> [1] https://bugs.openjdk.java.net/browse/JDK-8072008
>>>>>
>>>
>
More information about the hotspot-compiler-dev
mailing list