-
Bug
-
Resolution: Fixed
-
P3
-
21, 22
-
b03
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8310137 | 21 | Roberto Castaneda Lozano | P3 | Resolved | Fixed | b28 |
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
# 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
- backported by
-
JDK-8310137 C2: LoadKlassNode::make fails with 'expecting TypeKlassPtr'
- Resolved
- relates to
-
JDK-8310219 C2: add a minimal regression test for JDK-8303513
- Open
-
JDK-8310524 C2: record parser-generated LoadN nodes for IGVN
- Resolved
-
JDK-8059299 assert(adr_type != NULL) failed: expecting TypeKlassPtr
- Closed
- links to
-
Commit openjdk/jdk21/39e98e7b
-
Commit openjdk/jdk/83d92672
-
Review openjdk/jdk21/21
-
Review openjdk/jdk/14463
(3 links to)