[9] RFR (L): 8072008: Emit direct call instead of linkTo* for recursive indy/MH.invoke* calls

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri Oct 30 00:01:52 UTC 2015

In addition, here are some excerpts from InvokeTest compilation log on 
x86 [1]:

(I) Optimized virtual call

0x000000010af78b03: callq  0x000000010aeb9580

;*invokestatic linkToVirtual {reexecute=0 rethrow=0 return_oop=1}
;   {optimized virtual_call java.lang.invoke.InvokeTest$T::f1}

          @0x000000010af78954: f0053413
relocInfo at 0x000000010af78956 [type=3(opt_virtual_call) 
addr=0x000000010af78b03 offset=19 format=1 data=5] | 
[destination=0x000000010aeb9580 metadata=0x000000011b994a20]

Recorded metadata:
#  5: 0x000000011b994a20 {method} {0x000000011b994a20} 'f1' 
'()Ljava/lang/Class;' in 'java/lang/invoke/InvokeTest$T'

(II) Virtual call

0x000000010af741e3: callq  0x000000010aeb9800

;*invokestatic linkToVirtual {reexecute=0 rethrow=0 return_oop=1}
;   {virtual_call java.lang.invoke.InvokeTest$T::f1}

          @0x000000010af74152: f802000a0004241d
relocInfo at 0x000000010af74158 [type=2(virtual_call) 
addr=0x000000010af741e3 offset=29 format=1 data={000a0004}] | 
[destination=0x000000010aeb9800 cached_value=0x000000010af741d9 

Recorded metadata:

#  4: 0x000000011b994a20 {method} {0x000000011b994a20} 'f1' 
'()Ljava/lang/Class;' in 'java/lang/invoke/InvokeTest$T'

(III) Static call

0x000000010af91e0f: callq  0x000000010aeb9a80

;*invokestatic linkToStatic {reexecute=0 rethrow=0 return_oop=1}
;   {static_call java.lang.invoke.InvokeTest$T::f2}

          @0x000000010af91dd0: f004440f
relocInfo at 0x000000010af91dd2 [type=4(static_call) 
addr=0x000000010af91e0f offset=15 format=1 data=4] | 
[destination=0x000000010aeb9a80 metadata=0x000000011b994ae8]

Recorded metadata:
#  4: 0x000000011b994ae8 {method} {0x000000011b994ae8} 'f2' 
'()Ljava/lang/Class;' in 'java/lang/invoke/InvokeTest$T'

Best regards,
Vladimir Ivanov

[1] http://cr.openjdk.java.net/~vlivanov/8072008/webrev.01/InvokeTest.log

On 10/30/15 12:36 AM, Vladimir Ivanov wrote:
> http://cr.openjdk.java.net/~vlivanov/8072008/webrev.01/
> https://bugs.openjdk.java.net/browse/JDK-8072008
> NB! It touches aarch64 & ppc code, so I'd like to hear from the
> maintainers whether the changes are fine.
> To simplify review process, the changes can be split in 2 parts.
> http://cr.openjdk.java.net/~vlivanov/8072008/webrev.01/hotspot.reloc/
> Platform-dependent changes in macro assembler to switch from relocation
> types to relocation instances, and attach pre-resolved method to call
> sites in generated code.
> http://cr.openjdk.java.net/~vlivanov/8072008/webrev.01/hotspot.attach/
> High-level adjustments in C2 and test cases.
> Overview
> There's a performance problem with inlining through
> MH.linkTo*/invokeBasic linkers. When MemberName/receiver is constant and
> VM sees the target method during compilation, but decides not to inline
> (e.g. recursive inlining), a call to linker is generated, but more
> optimal code shape is to call target method directly.
> The problem with substituting a linker call by a direct/virtual call is
> that call site resolution logic relies on bytecode info (see
> SharedRuntime::resolve_{static,opt_virtual,virtual}_call_C and
> SharedRuntime::find_callee_info_helper). But on bytecode level symbolic
> reference points to the linker method, which doesn't tell anything about
> target method.
> The fix is to attach additional metadata (Method*) to the call site, so
> VM can use it instead of inspecting bytecode when linking the call site.
> The Method* is placed in relocation table (for static_call,
> opt_virtual_call, and virtual_call relocation types) and contains a
> Method* the call site is resolved to by JIT compiler (_method from a
> call IR node).
> It is used only in C2 generated code.
> Example:
>    MemberName mn = ... <<T.f1>> ... ; // compile-time constant
>    MethodHandle.linkToStatic(..., mn)
> compiles to:
>    callq  0x0000000109cb1900  ; OopMap{off=28}
>                               ; *invokestatic linkToStatic
>                               ; - Test::invokeStatic at 3 (line 108)
>                               ; {static_call T.f1}
> It's a call to MethodHandle.linkToStatic on bytecode level, but in
> generated code it's a direct call to T.f1.
> For testing purposes, 2 new WhiteBox methods are introduced:
>    - clearInlineCaches
>    - deoptimize
> They are used in unit tests (test/compiler/jsr292/NonInlinedCall/*)
> which stresses new code shapes.
> WhiteBox changes require some adjustments in build scripts, since
> @HotSpotIntrinsicCandidate isn't part of JDK8. But it will be fixed
> separately (the idea is to start building wb.jar with JDK9).
> Testing: JPRT, java/lang/invoke, nashorn, octane
> Thanks!
> Best regards,
> Vladimir Ivanov

More information about the hotspot-compiler-dev mailing list