JDK-8072008 : Emit direct call instead of linkTo* for recursive indy/MH.invoke* calls
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-01-30
  • Updated: 2019-08-08
  • Resolved: 2015-11-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b97Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Reported by Remi: http://mail.openjdk.java.net/pipermail/mlvm-dev/2014-December/006192.html

If a MemberName is constant, direct call is faster than linkTo* call. 

Consider simple recursive call:
    static void rec(int depth) throws Throwable {
        if (depth > 0) {
            recMH.invokeExact(depth-1);
        } else {
            return;
        }
    }

C2 -XX:+PrintCompilation:
jsr292.RecursiveCall::rec (18 bytes)
@ 10   java.lang.invoke.LambdaForm$MH/537548559::invokeExact_MT (16 bytes)   force inline by annotation
  @ 2   java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by annotation
    @ 11   java.lang.invoke.MethodHandle::type (5 bytes)   accessor
  @ 12   java.lang.invoke.LambdaForm$DMH/1617791695::invokeStatic_I_V (14 bytes)   force inline by annotation
    @ 1   java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)   force inline by annotation
    @ 10   jsr292.RecursiveCall::rec (18 bytes)   inline (hot)
      @ 10   java.lang.invoke.LambdaForm$MH/537548559::invokeExact_MT (16 bytes)   force inline by annotation
        @ 2   java.lang.invoke.Invokers::checkExactType (30 bytes)   force inline by annotation
          @ 11   java.lang.invoke.MethodHandle::type (5 bytes)   accessor
        @ 12   java.lang.invoke.LambdaForm$DMH/1617791695::invokeStatic_I_V (14 bytes)   force inline by annotation
          @ 1   java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)   force inline by annotation
          @ 10   jsr292.RecursiveCall::rec (18 bytes)   recursive inlining is too deep

Non-inlined recursive call can be a direct call, but it is a ::linkToStatic call:
[...]
  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}
                                                ;*invokestatic linkToStatic
                                                ; - java.lang.invoke.LambdaForm$DMH/1617791695::invokeStatic_I_V@10
                                                ; - java.lang.invoke.LambdaForm$MH/537548559::invokeExact_MT@12
                                                ; - jsr292.RecursiveCall::rec@10 (line 28)
                                                ; - java.lang.invoke.LambdaForm$DMH/1617791695::invokeStatic_I_V@10
                                                ; - java.lang.invoke.LambdaForm$MH/537548559::invokeExact_MT@12
                                                ; - jsr292.RecursiveCall::rec@10 (line 28)
                                                ;   {static_call}
 [...]