How to get rid of MethodHandle::linkTo* call when target method is known but not inlined?

Dean Long dean.long at oracle.com
Fri Feb 13 18:57:11 UTC 2015


On 2/13/2015 3:59 AM, Vladimir Ivanov wrote:
> Dean,
>
> The question is what CallStaticJava should point to?
>
> Right now, it's SharedRuntime::get_resolve_static_call_stub() (see 
> DirectCallGenerator::generate).
>
> 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?

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