Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8303513

C2: LoadKlassNode::make fails with 'expecting TypeKlassPtr'

XMLWordPrintable

    • b03

        RunThese8M/RunThese30M fails with "assert(adr_type != 0LL) failed: expecting TypeKlassPtr" on a fastdebug build of Generational ZGC (see attached HotSpot error files, pid78296 for windows-x64 and pid1054514 for linux-x64). The failure is observed on a Generational ZGC build using -XX:+UseZGC, but it is not GC-specific (can also be reproduced using -XX:+UseParallelGC -XX:-UseCompressedOops).

        # A fatal error has been detected by the Java Runtime Environment:
        #
        # Internal Error (c:\sb\prod\1677586887\workspace\open\src\hotspot\share\opto\memnode.cpp:2289), pid=78296, tid=48652
        # assert(adr_type != 0LL) failed: expecting TypeKlassPtr

        Current CompileTask:
        C2:1229395 128231 % 4 javasoft.sqe.tests.api.java.util.Collections.ncopies.Stream::lambda$getStreamFactory$2 @ 11 (73 bytes)

        Stack: [0x0000002fc8e00000,0x0000002fc8f00000]
        Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
        (...)
        V [jvm.dll+0xbaebeb] LoadKlassNode::make+0x5b (memnode.cpp:2289)
        V [jvm.dll+0xdf4b83] SubTypeCheckNode::load_klass+0x153 (subtypenode.cpp:212)
        V [jvm.dll+0xdf51eb] SubTypeCheckNode::verify+0x32b (subtypenode.cpp:183)
        V [jvm.dll+0xdf4973] SubTypeCheckNode::Ideal+0x2a3 (subtypenode.cpp:113)
        V [jvm.dll+0xcac915] PhaseIterGVN::transform_old+0xe5 (phaseX.cpp:1356)
        V [jvm.dll+0xca8cb3] PhaseIterGVN::optimize+0x2b3 (phaseX.cpp:1206)
        V [jvm.dll+0x51c682] Compile::Optimize+0x1b2 (compile.cpp:2218)
        V [jvm.dll+0x51a43b] Compile::Compile+0x16bb (compile.cpp:834)
        (...)

        FAILURE ANALYSIS

        The failure is caused by an implicit assumption made by the verification code within SubTypeCheckNode::Ideal() [1]. This code wrongly assumes that if obj_or_subklass (the ObjOrSubKlass input of the SubTypeCheck node) is a klass or OOP pointer, then 'obj_or_subklass->bottom_type() != TOP'. This assumption does not hold if obj_or_subklass is a projection of the TOP constant node, which can happen within IGVN e.g. if 'obj_or_subklass->in(0)' is an unreachable call node that gets replaced with TOP, as can be seen in before-after-removing-call.png (attached).

        The consequence is that 'adr', the node computing the klass address of obj_or_subklass [2], has bottom type TOP, which triggers the reported assertion failure in LoadKlassNode::make() [3]. The failure is not specific to ZGC. It has only been observed with this GC configuration because a specific intermediate Idealization step in the IGVN sequence that leads to the above situation is only performed if UseCompressedOops is disabled. This step replaces a LoadP node with the value stored by a dominating StoreP node that writes into the same address, as can be seen in before-after-load-idealization.png (attached).

        This Idealization is not performed if UseCompressedOops is enabled because, unlike LoadP, the corresponding LoadN node is not recorded for IGVN upon creation -- only its successor DecodeN node is [4,5]. This missing optimization opportunity should be addressed separately.

        SUGGESTED SOLUTION

        To skip verification of SubtypeCheck nodes [1] if 'obj_or_subklass->bottom_type == TOP'. This is a low-risk fix affecting debug-only code. An alternative, more invasive solution, would be to skip the entire SubtypeCheckNode::Ideal() call in this case.

        [1] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/subtypenode.cpp#L113
        [2] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/subtypenode.cpp#L211
        [3] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/memnode.cpp#L2289
        [4] https://github.com/openjdk/jdk/blob/bac02b6e9d9e1e93db27c7888188f29631e07f47/src/hotspot/share/opto/graphKit.cpp#L1561-L1566
        [5] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/memnode.cpp#L956

          1. before-after-load-idealization.png
            491 kB
            Roberto Castaneda Lozano
          2. before-after-removing-call.png
            449 kB
            Roberto Castaneda Lozano
          3. before-igvn.pdf
            5 kB
            Roberto Castaneda Lozano
          4. hs_err_pid1054514.log
            1.21 MB
            Roberto Castaneda Lozano
          5. hs_err_pid78296.log
            502 kB
            Roberto Castaneda Lozano
          6. on-failure.pdf
            3 kB
            Roberto Castaneda Lozano
          7. replay_pid78296.log
            19.09 MB
            Roberto Castaneda Lozano

              rcastanedalo Roberto Castaneda Lozano
              rcastanedalo Roberto Castaneda Lozano
              Votes:
              0 Vote for this issue
              Watchers:
              9 Start watching this issue

                Created:
                Updated:
                Resolved: