JDK-8329797 : Shenandoah: Default case invoked for: "MaxL" (bad AD file)
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 23,repo-shenandoah
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-04-05
  • Updated: 2024-04-29
  • Resolved: 2024-04-25
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 23
23 b20Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Running dacapo benchmarks with Shenandoah crashes.

```
./build/linux-x86_64-server-fastdebug/jdk/bin/java -jar -XX:+UseShenandoahGC -Xmx4g -jar ~/benchmark-artifacts/dacapo-23.8-chopin-RC1.jar --scratch-directory /tmp/dacapo --no-validation --variance 5 --no-pre-iteration-gc --iterations 10 --size small avrora batik eclipse h2 jython luindex lusearch pmd sunflow xalan tomcat
```

Usually encounter this crash by the time it gets to h2 or jython.

```
Default case invoked for: 
   opcode  = 210, "MaxL"
o5552  MaxL  === _ o5408 o371  [[ o5404 ]] 

--N: o5552  MaxL  === _ o5408 o371  [[ o5404 ]] 

   --N: o5408  DivL  === o5488 o31 o5411  [[ o5552 ]] 
   RREGL  4000  divL_rReg
   NO_RAX_RDX_REGL  4000  divL_rReg
   RAX_REGL  4000  divL_rReg
   RCX_REGL  4000  divL_rReg
   RDX_REGL  4000  divL_rReg
   NO_RBP_R13_REGL  4000  divL_rReg
   STACKSLOTL  4100  storeSSL

      --N:  o31  AddL  === _ o12 o30  [[ o680 o4152 o678 o657 o623 o265 o85 o85 o475 o351 o322 o3373 o647 o463 o567 o370 o214 o445 o5408 o5416 ]] 
      RREGL  0  RREGL
      NO_RAX_RDX_REGL  0  NO_RAX_RDX_REGL
      RAX_REGL  0  RAX_REGL
      RCX_REGL  0  RCX_REGL
      RDX_REGL  0  RDX_REGL
      NO_RBP_R13_REGL  0  NO_RBP_R13_REGL
      STACKSLOTL  100  storeSSL

      --N: o5411  SubL  === _ o5413 o5412  [[ o5408 o5410 o5521 ]] 
      RREGL  0  RREGL
      NO_RAX_RDX_REGL  0  NO_RAX_RDX_REGL
      RAX_REGL  0  RAX_REGL
      RCX_REGL  0  RCX_REGL
      RDX_REGL  0  RDX_REGL
      NO_RBP_R13_REGL  0  NO_RBP_R13_REGL
      STACKSLOTL  100  storeSSL

   --N: o371  ConL  === o0  [[ o5552 o5553 o4218 o4288 ]]  #long:1
   IMML  20  IMML
   IMML8  5  IMML8
   IMMUL32  10  IMMUL32
   IMML32  15  IMML32
   IMML_POW2  15  IMML_POW2
   IMML1  0  IMML1
   RREGL  70  loadConUL32
   NO_RAX_RDX_REGL  70  loadConUL32
   RAX_REGL  70  loadConUL32
   RCX_REGL  70  loadConUL32
   RDX_REGL  70  loadConUL32
   NO_RBP_R13_REGL  70  loadConUL32
   STACKSLOTL  170  storeSSL

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/home/ANT.AMAZON.COM/kemperw/Development/genshen/src/hotspot/share/opto/matcher.cpp:1727), pid=3275617, tid=3277838
#  assert(false) failed: bad AD file
#
# JRE version: OpenJDK Runtime Environment (23.0) (fastdebug build 23-kemperw-openjdk-master.4a11db8b606)
# Java VM: OpenJDK 64-Bit Server VM (fastdebug 23-kemperw-openjdk-master.4a11db8b606, mixed mode, tiered, compressed oops, compressed class ptrs, shenandoah gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x13a1677]  Matcher::Label_Root(Node const*, State*, Node*, Node*&)+0x507
#
```

Seems the `MaxL` node was introduced recently: https://bugs.openjdk.org/browse/JDK-8324655.

Comments
Changeset: d32f1092 Author: Joshua Cao <joshcao@amazon.com> Committer: Tobias Hartmann <thartmann@openjdk.org> Date: 2024-04-25 07:11:12 +0000 URL: https://git.openjdk.org/jdk/commit/d32f10921985031505718ec29fb97a36f9ba24c0
25-04-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/18824 Date: 2024-04-17 18:44:57 +0000
17-04-2024

The issue occurs in h2 here https://github.com/h2database/h2database/blob/0f2922171f4606bbd8e0f15265adf1bc078795a6/h2/src/main/org/h2/index/Index.java#L579. I believe any loop that includes a `ShenandoahLoadReferenceBarrier` and a `MaxL` node will crash along the following stacktrace: ``` #0 CMoveNode::Ideal_minmax (phase=0x7fffd117a4b0, cmove=0x7ffe540d5bb8) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/movenode.cpp:224 #1 0x00007ffff575424f in CMoveNode::Ideal (this=0x7ffe540d5bb8, phase=0x7fffd117a4b0, can_reshape=true) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/movenode.cpp:100 #2 0x00007ffff5844d7c in PhaseGVN::apply_ideal (this=0x7fffd117a4b0, k=0x7ffe540d5bb8, can_reshape=true) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/phaseX.cpp:668 #3 0x00007ffff5846c7f in PhaseIterGVN::transform_old (this=0x7fffd117a4b0, n=0x7ffe540d5bb8) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/phaseX.cpp:1198 #4 0x00007ffff5846466 in PhaseIterGVN::optimize (this=0x7fffd117a4b0) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/phaseX.cpp:1046 #5 0x00007ffff4ee4f0c in PhaseIdealLoop::optimize (igvn=..., mode=LoopOptsShenandoahPostExpand) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/loopnode.hpp:1200 #6 0x00007ffff4ed570e in Compile::optimize_loops (this=0x7fffd117c7b0, igvn=..., mode=LoopOptsShenandoahPostExpand) at /home/joshcao/jdk/shenandoah/src/hotspot/share/opto/compile.cpp:2189 #7 0x00007ffff59ff7fb in ShenandoahBarrierC2Support::expand (C=0x7fffd117c7b0, igvn=...) at /home/joshcao/jdk/shenandoah/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp:59 #8 0x00007ffff5927955 in ShenandoahBarrierSetC2::expand_barriers (this=0x7fffec0e4420, C=0x7fffd117c7b0, igvn=...) at /home/joshcao/jdk/shenandoah/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp:859 ``` In particular, we need a loop + barrier to trigger execution of https://github.com/openjdk/jdk/blob/040c93565c0dff6270911eb9e58d78aa01bbb925/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp#L58. I created a simpler reproducer: ``` class Repro { public static class Dummy { long i; public Dummy(long i) { this.i = i; } } public static long test(Dummy[] arr) { long result = 0; for (int i = 0; i < arr.length; ++i) { Dummy d = arr[i]; result += Math.max(d.i, 1); } return result; } public static void main(String []args) throws Exception { Dummy[] arr = new Dummy[100]; for (int i = 0; i < 100; ++i) { arr[i] = new Dummy(i - 50); } for (int i = 0; i < 10000; ++i) { test(arr); } } } ``` ``` java -XX:-TieredCompilation -XX:CompileOnly=Repro::test -XX:+UseShenandoahGC Repro ```
16-04-2024

Repro steps: 1. Download jar file from https://github.com/dacapobench/dacapobench/releases/tag/v23.9-RC1-chopin and unzip 2. `unzip dacapo-23.8-chopin-RC1/jar/lib/h2/h2-2.1.214.jar` 3. Download attached replay file to current directory 4. java -cp "dacapo-23.8-chopin-RC1.jar:." -XX:+UseShenandoahGC -XX:+ReplayCompiles -XX:ReplayDataFile=replay_pid3306889.log -XX:+ReplayIgnoreInitErrors h2 I am using the Shenandoah build with HEAD at f43034d8d1dc571390f357dc3617f376cafa085f ``` openjdk version "23-internal" 2024-09-17 OpenJDK Runtime Environment (slowdebug build 23-internal-adhoc.joshcao.shenandoah) OpenJDK 64-Bit Server VM (slowdebug build 23-internal-adhoc.joshcao.shenandoah, mixed mode, sharing) ```
16-04-2024

I believe the problem is when we transform `CMoveNode` into `MaxLNode` in https://github.com/openjdk/jdk/blob/862e6156960639564aed5de16de9a26320770a80/src/hotspot/share/opto/movenode.cpp#L198. `MaxLNode`'s are macro nodes which must not be emitted after macro expansion. The code assumes that if macro expansion is completed, loop opts must have also been completed. This assumption breaks when Shenandoah optimizations resets loop opts in https://github.com/openjdk/jdk/blob/040c93565c0dff6270911eb9e58d78aa01bbb925/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp#L52. In this case, macro expansion is completed, but string opts are marked as incomplete, and `CMoveNode` can be transformed into `MaxLNode`. The new `MaxLNode` never gets a chance to be macro expanded.
05-04-2024