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 11:59:10 UTC 2015
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?
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.
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