JDK-8239083 : C1 assert(known_holder == NULL || (known_holder->is_instance_klass() && (!known_holder->is_interface() || ((ciInstanceKlass*)known_holder)->has_nonstatic_concrete_methods())), "should be non-static concrete method");
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u231,9,11,14,15
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-02-14
  • Updated: 2023-09-26
  • Resolved: 2020-06-02
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 11 JDK 15
11.0.9-oracleFixed 15 b26Fixed
Related Reports
Duplicate :  
Description
Running the following code:

public class Test {

     static final MethodHandle MH_m;

     static {
         try {
             MH_m = lookup().findStatic(MyInterface.class, "m", MethodType.methodType(void.class));
         } catch (ReflectiveOperationException e) {
             throw new BootstrapMethodError(e);
         }
     }

     public static void main(String[] args) throws Throwable {
         for (int i = 0; i < 20_000; i++) {
             payload();
         }
     }

     static void payload() throws Throwable {
         MH_m.invokeExact();
     }

}

interface MyInterface {
     static void m() {}
} 

With `-Xbatch -XX:TieredStopAtLevel=3` fails with the assertion from the title in c1_GraphBuilder::profile_call.

The MethodHandle is significant here since known_holder in the assert is null with a regular call to a static interface method.
Comments
Fix request (11u) -- will label after testing completed. I would like to downport this for parity with 11.0.9-oracle. Applies clean.
22-06-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/b6864bc6ef86 User: chagedorn Date: 2020-06-02 10:24:42 +0000
02-06-2020

http://cr.openjdk.java.net/~chagedorn/8239083/webrev.00/ The assert fails in the test case when invoking the only static interface method with a method handle. In this case, known_holder is non-NULL. However, known_holder would be set to NULL at [1] since the call returns NULL when known_holder is an interface. In the failing test case, known_holder is non-NULL since GraphBuilder::try_method_handle_inline() calls GraphBuilder::try_inline() with holder_known set to true which eventually lets profile_call() to be called with a non-NULL known_holder argument. On the other hand, when calling a static method without a method handle, known_holder seems to be always NULL: profile_call() is called directly at [2] with NULL or indirectly via try_inline() [3]. In the latter case, cha_monomorphic_target and exact_target are always NULL for static methods and therefore known_holder will also be always NULL in profile_call(). We could therefore just remove the assert which seems to be too strong (not handling this edge case). Another option would be to change the call to try_inline() in try_method_handle_inline() to only set holder_known to true if the target is not static. The known_holder is eventually only used in LIR_Assembler::emit_profile_call() [4] but only if op->should_profile_receiver_type() holds [5]. This is only true if the callee is not static [6]. The webrev uses the second approach.
15-05-2020

Some prior discussion: https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2020-February/037013.html
14-02-2020