[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 23:27:36 UTC 2015


No, it's not needed. All relocations refer to recorded metadata section 
in the nmethod:

+ Method* virtual_call_Relocation::method_value() {
+   Metadata* m = code()->metadata_at(_method_index);
+   assert(m != NULL || _method_index == 0, "should be non-null for 
non-zero index");
+   assert(m == NULL || m->is_method(), "not a method");
+   return (Method*)m;
+ }

The following code in nmethod::metadata_do should enumerate them:

   // Visit the metadata section
   for (Metadata** p = metadata_begin(); p < metadata_end(); p++) {
     if (*p == Universe::non_oop_word() || *p == NULL)  continue;  // 
skip non-oops
     Metadata* md = *p;
     f(md);
   }

Special cases are needed for embedded metadata.

And recording happens in resolved_method_index (see *.ad changes):

src/share/vm/opto/machnode.hpp:
+   int resolved_method_index(CodeBuffer &cbuf) const {
+     if (_override_symbolic_info) {
+       // Attach corresponding Method* to the call site, so VM can use 
it during resolution
+       // instead of querying symbolic info from bytecode.
+       assert(_method != NULL, "method should be set");
+       assert(_method->constant_encoding()->is_method(), "should point 
to a Method");
+       return 
cbuf.oop_recorder()->find_index(_method->constant_encoding());
+     }
+     return 0; // Use symbolic info from bytecode (resolved_method == 
NULL).
+   }
Best regards,
Vladimir Ivanov

On 10/30/15 10:46 PM, Dean Long wrote:
> Do you need *_call_Relocation::method_value() to be scanned in any new
> places,
> like nmethod::metadata_do?
>
> dl
>
> On 10/29/2015 2:36 PM, 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