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

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Thu Oct 29 21:36:12 UTC 2015


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.


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.

High-level adjustments in C2 and test cases.


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.


   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


Best regards,
Vladimir Ivanov

More information about the hotspot-compiler-dev mailing list