JDK-8238812 : assert(false) failed: bad AD file
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11.0.8,14,15,16
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-02-10
  • Updated: 2021-03-29
  • Resolved: 2021-03-10
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 17
11.0.12-oracleFixed 17 b13Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Generated test from example cause following crash:
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (open/src/hotspot/share/opto/matcher.cpp:1563), pid=3847, tid=3864
#  assert(false) failed: bad AD file
#
# JRE version: Java(TM) SE Runtime Environment (15.0+9) (fastdebug build 15+9-264)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 15+9-264, mixed mode, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x110e2de]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x59e
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %d %P" (or dumping to /home/lmesnik/Downloads/r2-23/core.3847)
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#

---------------  S U M M A R Y ------------

Command Line: Test

Host: lmesnik-linux, Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz, 8 cores, 31G, Ubuntu 18.04.3 LTS
Time: Mon Feb 10 13:03:17 2020 PST elapsed time: 0 seconds (0d 0h 0m 0s)

---------------  T H R E A D  ---------------

Current thread (0x00007f92a81ca800):  JavaThread "C2 CompilerThread1" daemon [_thread_in_native, id=3864, stack(0x00007f92c2629000,0x00007f92c272a000)]


Current CompileTask:
C2:    616  419 %     4       Test::vMeth1 @ 124 (1491 bytes)

Stack: [0x00007f92c2629000,0x00007f92c272a000],  sp=0x00007f92c2724a30,  free space=1006k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x110e2de]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x59e
V  [libjvm.so+0x110e34a]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x60a
V  [libjvm.so+0x110ebb7]  Matcher::match_tree(Node const*)+0x1d7
V  [libjvm.so+0x1112231]  Matcher::xform(Node*, int)+0xc51
V  [libjvm.so+0x1116345]  Matcher::match()+0xc55
V  [libjvm.so+0x86fdc4]  Compile::Code_Gen()+0x84
V  [libjvm.so+0x874191]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x1171
V  [libjvm.so+0x6e2d50]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x110
V  [libjvm.so+0x880e70]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x3e0
V  [libjvm.so+0x881f18]  CompileBroker::compiler_thread_loop()+0x458
V  [libjvm.so+0x152bf1a]  JavaThread::thread_main_inner()+0x26a
V  [libjvm.so+0x15342c5]  JavaThread::run()+0x345
V  [libjvm.so+0x15311c6]  Thread::call_run()+0xf6
V  [libjvm.so+0x1265f0e]  thread_native_entry(Thread*)+0x10e

Register to memory mapping:

Comments
Fix Request (11u) Should get backported for parity with 11.0.12-oracle. Applies cleanly, but test requires a small modification. Review thread: http://mail.openjdk.java.net/pipermail/jdk-updates-dev/2021-March/005481.html
26-03-2021

Changeset: 4b5be40a Author: Rahul Raghavan <rraghavan@openjdk.org> Date: 2021-03-10 15:59:38 +0000 URL: https://git.openjdk.java.net/jdk/commit/4b5be40a
10-03-2021

Fix update done to set CastIINode::_carry_dependency to prevent the CastIINode with TypeInt::INT from being removed by IGVN. (revised fix to add a _carry_dependeny argument to constrained_convI2L and set it to true for the CastII introduced by lookupswitch.) (found no issues with reported java_fuzzer cases / unit tests and tier & pre-integration tests in progress) Also created followup enhancement task - JDK-8263252.
10-03-2021

PR - https://github.com/openjdk/jdk/pull/2758 Thanks to comments from [Roland] : "This fixes the bug when the tests that need to be optimized out are next to one an another and the logic for folding comparisons can be used. It's hard to be certain that it's not possible for the 2 tests be separated by some other control flow. In that case the fix would fail. A conservative fix would be to not use a narrow type in the CastII that tableswitch/lookupswitch switch introduces. It would be a simpler fix and a more robust one." Based on the review comments now planning to - i. Do proposal by Roland and remove the narrow type from the CastII as fix for this bug task. ii. Integrate the other proposed fix to improve fold_compares optimizations as a separate enhancement. i. Confirmed no issues with reported java_fuzzer cases / unit tests, mach5 tier 1-7 & pre-integration tests for the following changes to avoid use any narrow type in the CastII that lookupswitch introduces [src/hotspot/share/opto/parse2.cpp] // Clean the 32-bit int into a real 64-bit offset. // Otherwise, the jint value 0 might turn into an offset of 0x0800000000. - const TypeInt* ikeytype = TypeInt::make(0, num_cases, Type::WidenMin); // Make I2L conversion control dependent to prevent it from // floating above the range check during loop optimizations. - key_val = C->conv_I2X_index(&_gvn, key_val, ikeytype, control()); + // Do not use a narrow int type here to prevent the data path from dying + // while the control path is not removed. This can happen if the type of key_val + // is later known to be out of bounds of [0, num_cases] and therefore a narrow cast + // would be replaced by TOP while C2 is not able to fold the corresponding range checks. +#ifdef _LP64 + key_val = C->constrained_convI2L(&_gvn, key_val, TypeInt::INT, control()); +#endif ii. Believe following two types of changes done in initial fix proposal is needed - (and can be done as a separate task) 1. Extracting existing non-CmpU changes from fold_compares_helper 2. Support fold_compares to handle CmpU nodes (after addressing the comments in filtered_int_type())
09-03-2021

Found that the earlier PR bug analysis and fix details done is wrong. Now understood need to fix two types of issues related to the bug- (i). Crash with only CmpI nodes case. ------------------------- Sample test case - public static void test2() { for (int i = 5; i > -20; i -= 5) { switch (i) { case 0: case 10: case 20: case 30: case 40: case 50: case 60: case 100: res = 42; break; } } } ------------------------- // This generates the following subgraph: /* // i: -20..0 if (i != 0) { // i: -20..-1 if (i < 0) { <- /*This is always true but not folded by C2*/ // Fall through } else { ... CastII(i-1, 0..4) <- /*Replaced by TOP because i-1 range is -21..-1 but still considered reachable by C2 although it is dead code*/ ... } } else { StoreI <- Due to this additional store on, IfNode::has_shared_region returns false and the fold compares optimization does not kick in } */ --------------------------- Sample IR extracts - 77 Phi === 399 25 389 [[ 658 664 389 80 662 660 659 ]] 25 ConI === 0 [[ 80 77 ]] #int:0 80 CmpI === _ 77 25 [[ 81 89 ]] 81 Bool === _ 80 [[ 82 ]] [ne] 82 If === 399 81 [[ 85 87 ]] 85 IfFalse === 82 [[ 102 336 ]] 87 IfTrue === 82 [[ 90 ]] #1 89 Bool === _ 80 [[ 90 ]] [lt] 90 If === 87 89 [[ 91 92 ]] 91 IfTrue === 90 [[ 102 ]] #1 92 IfFalse === 90 [[ 156 ]] #0 336 StoreI === 85 359 335 332 [[ 337 ]] 156 Jump === 92 1 [[ 157 160 ....... --------------------------- Fix proposal applied here includes : - Extract the existing non-CmpU related optimization out of old fold_compares_helper(), - form new method (new fold_dominated_if() added and renamed old_compares_helper as fold_to_unsigned()). - Call it properly from fold_compares() and related code adjustments. (ii). 'fold_compares()' not handling CmpU nodes cases. ------------------------- Sample basic test case - public static void test3() { int local = 0; for (int i = 5; i > -20; i -= 5) { switch (i) { case 0: case 10: case 20: case 30: case 40: case 50: case 100: local = 42; break; } } } ------------------------- // This generates the following subgraph: /* // i: -20..0 if (i != 0) { // i: -20..-1 if (i u< 101) { <- /*This is always false but not folded by C2 because CmpU is not handled*/ CastII(i-1, 0..49) <- /*Replaced by TOP because i-1 range is -21..-1 but still considered reachable by C2 although it is dead code*/ } else { ... } } else { ... } */ ------------------------- Sample IR extracts - 77 Phi === 363 20 353 [[ 573 577 572 80 575 353 345 574 ]] 20 ConI === 0 [[ 80 77 ]] #int:0 80 CmpI === _ 77 20 [[ 81 ]] 81 Bool === _ 80 [[ 82 ]] [ne] 82 If === 363 81 [[ 85 87 ]] 85 IfFalse === 82 [[ 102 ]] #0 87 IfTrue === 82 [[ 337 ]] #1 95 ConI === 0 [[ 345 ]] #int:101 345 CmpU === _ 77 95 [[ 346 ]] 346 Bool === _ 345 [[ 337 ]] [lt] 337 If === 87 346 [[ 338 339 ]] 338 IfFalse === 337 [[ 102 ]] #0 339 IfTrue === 337 [[ 135 ]] #1 135 Jump === 339 1 [[ 136 139 142 ..... ------------------------- Proposed fix includes - - Enabling Op_CmpU support in 'cmpi_folds()'. - 'filtered_int_type()' - returns possible restrictive type for input value based on condition control flow for the if (supported CmpU for various condition control types). - 'fold_dominated_if()' - checks if dominating if determines the result of current if and above example test case is a basic variant possibility where both CmpNodes compare a common value directly. (Node 77 Phi in above sample). But as mentioned in the comments of new helper function get_base_comparing_value(), there are other possibilities where there might be an AddINode with a constant increment present in between the CmpNodes and the common value compared. All these variants are handled and test cases added. - and related changes in fold_compares(). Found no issues with proposed fix for various unit tests, reported java_fuzzer case, tier1-6 and pre-integeration tests.
01-03-2021

Found the root cause of the problem as that the following two checks are not folded into one for the sample test: 170 ConI === 0 [[ 171 ]] #int:31 171 CmpI === _ 144 170 [[ 172 179 ]] 172 Bool === _ 171 [[ 173 ]] [ne] 173 If === 158 172 [[ 176 177 ]] 176 IfFalse === 173 [[ 168 ]] #0 177 IfTrue === 173 [[ 180 ]] #1 179 Bool === _ 171 [[ 180 ]] [lt] 180 If === 177 179 [[ 181 182 ]] 181 IfTrue === 180 [[ 168 ]] #1 182 IfFalse === 180 [[ 218 ]] #0 Where 144 is the value and the ifs check for: value != 31 value < 31 Now if we reach 182 IfFalse, the following holds: value != 31 && !(value < 31) => value != 31 && value >= 31 => value > 31 But the type of value (144) becomes #int:16..31 : 140 ConI === 0 [[ 141 ]] #int:2 135 Phi === 534 481 528 [[ ... ]] #int:1..4 #tripcount 141 LShiftI === _ 135 140 [[ 142 ]] #int:4..16 143 ConI === 0 [[ 144 ]] #int:11 142 AddI === _ 141 135 [[ 144 500 485 ]] #int:5..20 144 AddI === _ 142 143 [[ ... ]] #int:16..31 And that means that value > 31 is always false and should be folded. The root cause of the bug is that this does not happen. Understood that the fix by Tobias for JDK-8236721 should optimize exactly above type cases https://hg.openjdk.java.net/jdk/jdk/rev/9c53fdf6ba63 Found the IfNode::fold_compares optmization (and 8236721 related changes by Tobias) is not called for 180-If, after the type of 144-AddI is set to #int:16..31. because the _worklist is not correctly updated! Following changes helped to add the required If node to _worklist (after the correct type setting of related value) and with this change no failure due to existing fold_compares optimization happening later on. diff -r bdc20ee1a68d src/hotspot/share/opto/phaseX.cpp --- a/src/hotspot/share/opto/phaseX.cpp Fri Sep 04 23:51:26 2020 -0400 +++ b/src/hotspot/share/opto/phaseX.cpp Tue Sep 22 22:27:22 2020 +0530 @@ -1560,6 +1560,18 @@ } } if (use_op == Op_CmpI) { + // Put If on worklist to enable fold_compares optimization (see IfNode::cmpi_folds) + if (use->outcnt() > 0) { + for (uint i = 0; i < use->outcnt(); i++) { + Node* bol = use->raw_out(i); + if (bol->outcnt() > 0) { + Node* iff = bol->raw_out(0); + if (iff->Opcode() == Op_If && iff->outcnt() == 2) { + add_users_to_worklist0(bol); + } + } + } + } Node* phi = countedloop_phi_from_cmp((CmpINode*)use, n); if (phi != NULL) { // If an opaque node feeds into the limit condition of a related graph nodes from the test - ============================================ Issue fixed when add_users_to_worklist() gets called for 144-AddI Node with the fix (after correct type set by PhaseIterGVN - optimize() > transform_old() optimizations) 144 AddI === _ 142 143 [[ 812 146 811 810 162 171 809 808 186 807 194 806 805 ]] !jvms: Test::vMeth1 @ bci:28 170 ConI === 0 [[ 171 548 694 ]] #int:31 171 CmpI === _ 144 170 [[ 172 179 ]] !jvms: Test::vMeth1 @ bci:29 172 Bool === _ 171 [[ 173 ]] [ne] !jvms: Test::vMeth1 @ bci:29 173 If === 516 172 [[ 176 177 ]] P=0.000001, C=1458.000000 !jvms: Test::vMeth1 @ bci:29 176 IfFalse === 173 [[ 168 ]] #0 !jvms: Test::vMeth1 @ bci:29 177 IfTrue === 173 [[ 180 ]] #1 !jvms: Test::vMeth1 @ bci:29 179 Bool === _ 171 [[ 180 ]] [lt] !jvms: Test::vMeth1 @ bci:29 180 If === 177 179 [[ 181 182 ]] P=0.000001, C=0.000003 !jvms: Test::vMeth1 @ bci:29 181 IfTrue === 180 [[ 168 ]] #1 !jvms: Test::vMeth1 @ bci:29 168 Region === 168 176 151 515 508 219 222 225 236 239 242 245 248 259 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 329 332 335 338 341 344 347 350 353 364 367 370 373 376 379 382 385 388 391 394 181 492 477 [[ 168 529 ]] !orig=447 !jvms: Test::vMeth1 @ bci:130 182 IfFalse === 180 [[ 510 ]] #0 !jvms: Test::vMeth1 @ bci:29 185 ConI === 0 [[ 186 550 696 ]] #int:84 186 CmpI === _ 144 185 [[ 509 ]] !jvms: Test::vMeth1 @ bci:29 509 Bool === _ 186 [[ 510 ]] [lt] 510 If === 182 509 [[ 511 512 ]] P=0.166667, C=0.000156 !orig=[188] !jvms: Test::vMeth1 @ bci:29 512 IfTrue === 510 [[ 212 218 ]] #1 !orig=[190] !jvms: Test::vMeth1 @ bci:29 212 CastII === 512 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 218 Jump === 512 217 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 511 IfFalse === 510 [[ 506 ]] #0 !orig=[189] !jvms: Test::vMeth1 @ bci:29 193 ConI === 0 [[ 194 552 698 ]] #int:313 194 CmpI === _ 144 193 [[ 505 ]] !jvms: Test::vMeth1 @ bci:29 505 Bool === _ 194 [[ 506 ]] [le] 506 If === 511 505 [[ 507 508 ]] P=0.999999, C=-1.000000 !orig=[196] !jvms: Test::vMeth1 @ bci:29 507 IfFalse === 506 [[ 800 ]] #0 !orig=[197] !jvms: Test::vMeth1 @ bci:29 508 IfTrue === 506 [[ 168 ]] #1 !orig=[198] !jvms: Test::vMeth1 @ bci:29 800 Region === 800 799 507 [[ 800 654 807 820 ]] ========================================
02-12-2020

* Notes - Pointers tried and failed to get root cause. [1]. For the sample test - CastII node generated from create_jump_tables() - .e.g: 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 Tried checking why/where the type of input to this CastII becomes 'int:-16..-1' (which leads to changing this CastII to TOP and eventually crash) .e.g.: (rr) p phase->type(this)->dump() int:0..51:www$16 = void (rr) p phase->type(in(1))->dump() int:-16..-1$17 = void But could not get hint on issue root cause location. (could solve initial issues with placing watchpoint for _types values.) .e.g.: (rr) p (_types->_types[210])->dump() int:-16..-1$185 = void (rr) p &(_types->_types[210]) $186 = (const Type **) 0x7f1e580c3288 (rr) watch *0x7f1e580c3288 (rr) reverse-cont Thread hit Breakpoint, PhaseIterGVN::transform_old .. at ..open/src/hotspot/share/opto/phaseX.cpp:1221 1221 Node* k = n; (rr) where #0 PhaseIterGVN::transform_old (this=0x7f1e751bda00, n=0x7f1e580a0548) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/phaseX.cpp:1221 #1 0x00007f1e816a91d6 in PhaseIterGVN::optimize (this=0x7f1e751bda00) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/phaseX.cpp:1171 #2 0x00007f1e814c0805 in PhaseIdealLoop::build_and_optimize (this=0x7f1e751bccd0, mode=LoopOptsDefault) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/loopnode.cpp:3326 #3 0x00007f1e80e87e51 in PhaseIdealLoop::PhaseIdealLoop (this=0x7f1e751bccd0, igvn=..., mode=LoopOptsDefault) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/loopnode.hpp:952 #4 0x00007f1e80e87f4c in PhaseIdealLoop::optimize (igvn=..., mode=LoopOptsDefault) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/loopnode.hpp:1027 #5 0x00007f1e80e7b5a2 in Compile::optimize_loops (this=0x7f1e751bff60, igvn=..., mode=LoopOptsDefault) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/compile.cpp:1972 #6 0x00007f1e80e7c784 in Compile::Optimize (this=0x7f1e751bff60) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/compile.cpp:2259 #7 0x00007f1e80e7560f in Compile::Compile (this=0x7f1e751bff60, ci_env=0x7f1e751c0a90, target=0x7f1e7c42b6e0, osr_bci=-1, subsume_loads=true, do_escape_analysis=true, eliminate_boxing=true, install_code=true, directive=0x7f1e7c135e00) at /home/rvraghav/data/build/jdk8238812/jdk-jdk/open/src/hotspot/share/opto/compile.cpp:738 But could not find issue with types set for nodes with reverse debugging (the set types seems propagated correctly based on types of parent nodes) .e.g.: (rr) p n->dump(6) ......... 140 ConI === 0 [[ 141 561 707 ]] #int:2 526 AddI === _ 135 25 [[ 135 527 803 ]] !orig=[446] !jvms: Test::vMeth1 @ bci:130 827 CastII === 840 682 [[ 135 ]] #int:3..4 carry dependency 532 CountedLoop === 532 840 530 [[ 532 148 135 ]] inner stride: -1 main of N532 !orig=[518],[132] !jvms: Test::vMeth1 @ bci:23 141 LShiftI === _ 135 140 [[ 142 ]] !jvms: Test::vMeth1 @ bci:25 135 Phi === 532 827 526 [[ 820 819 142 818 817 141 816 815 526 814 813 ]] #int:1..4 #tripcount !jvms: Test::vMeth1 @ bci:23 211 ConI === 0 [[ 210 557 703 ]] #int:-21 142 AddI === _ 135 141 [[ 144 210 484 498 ]] !jvms: Test::vMeth1 @ bci:25 210 AddI === _ 142 211 [[ 212 ]] !jvms: Test::vMeth1 @ bci:29 --- Example type of 210-AddI becomes 'int:[-16..-1]' from its parent node types 142-AddI 'int:[5..20]' & 211-ConI 'int:[#-21]' (rr) p (_types->_types[210])->dump() int $205 = void (rr) p (_types->_types[211])->dump() int:-21 $206 = void (rr) p (_types->_types[142])->dump() int:5..20 $207 = void Also -- (rr) p (_types->_types[142])->dump() int:5..20 $207 = void (rr) p (_types->_types[135])->dump() int:1..4 $212 = void (rr) p (_types->_types[141])->dump() int:4..16 $213 = void (rr) p (_types->_types[141])->dump() int:4..16 $213 = void (rr) p (_types->_types[135])->dump() int:1..4 $212 = void 140 ConI === 0 [[ 141 561 707 ]] #int:2 (rr) p (_types->_types[135])->dump() int:1..4 $212 = void (rr) p (_types->_types[532])->dump() control $218 = void (rr) p (_types->_types[827])->dump() int:3..4 $219 = void (rr) p (_types->_types[526])->dump() int:0..3 $220 = void [2]. Tried checking if any issue with 211-ConI (#-21) node generation. 211 ConI === 0 [[ 210 557 703 ]] #int:-21 Similar to the 212-CastII node found this node also is generated in create_jump_tables and could not find any issues with -21 constant as it is correctly calculated based on the 'lo' , 'hi' input values [3]. Could not find clues with some trace options tried - TraceIterativeGVN, TraceLoopPredicate, TraceLoopOpts, TraceTypeProfile. Also checking any issues with LoopUnrollLimit did not help. [4]. Checked UseSwitchProfiling usage. Could not yet get a failing test with -XX:-UseSwitchProfiling. But when playing -UseSwitchProfiling, found a similar sub-graph shape as filing case, where in final though all range check dependent nodes deleted and a jump node remained. But the input to jump node was not direct TOP, but was through a ConI node from TOP. Though investigated, seems different unrelated case.
02-12-2020

## New test $ ...build/linux-x64-slowdebug/jdk/bin/javac Test.java $ ...build/linux-x64-slowdebug/jdk/bin/java -XX:CompileCommand=compileonly,Test::vMeth1 -XX:CompileCommand=dontinline,compiler.Test::vMeth1 -Xbatch -XX:-TieredCompilation -XX:+PrintIdeal -XX:-UseSwitchProfiling Test <NO FAILURE CRASH> $ ...build/linux-x64-slowdebug/jdk/bin/java -XX:CompileCommand=compileonly,Test::vMeth1 -XX:CompileCommand=dontinline,compiler.Test::vMeth1 -Xbatch -XX:-TieredCompilation -XX:+PrintIdeal Test <CRASH> # Internal Error (...open/src/hotspot/share/opto/matcher.cpp:1570), pid=6086, tid=6098 # assert(false) failed: bad AD file # JRE version: Java(TM) SE Runtime Environment (15.0) (slowdebug build 15-internal+0-2020-05-26-0710203.rvraghav...) # Java VM: Java HotSpot(TM) 64-Bit Server VM (slowdebug 15-internal+0-2020-05-26-0710203.rvraghav..., mixed mode, compressed oops, g1 gc, linux-amd64) # Problematic frame: # V [libjvm.so+0xd8eb69] Matcher::Label_Root(Node const*, State*, Node*, Node*&)+0x503 ............ From the Ideal graph printed, following node with TOP input causes the assert - .... 218 Jump === 182 1 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 ...... ## sample extracts/notes from debugging: .............. Thread 3 hit Breakpoint 1, Parse::create_jump_tables (this=0x7f80f77faea0, key_val=0x7f80ec098498, lo=0x7f810839be20, hi=0x7f810839bf80) at ...open/src/hotspot/share/opto/parse2.cpp:875 875 key_val = C->conv_I2X_index(&_gvn, key_val, ikeytype, control()); ////(hits only once for the test) (rr) c Continuing. Thread 3 hit Breakpoint 2, Parse::create_jump_tables (this=0x7f80f77faea0, key_val=0x7f80ec098858, lo=0x7f810839be20, hi=0x7f810839bf80) at ...open/src/hotspot/share/opto/parse2.cpp:926 926 return true; (rr) p lo->print() {32..34}=>130 (cnt=0.000002)$1 = void (rr) p hi->print() {83}=>2147483647 (cnt=0.000000)$2 = void (rr) p key_val->_in[1]->_in[1]->dump() 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p key_val->_in[1]->_in[1]->dump(3) 141 LShiftI === _ 135 140 [[ 142 ]] !jvms: Test::vMeth1 @ bci:25 135 Phi === 132 _ 131 [[ 81 137 142 138 139 141 150 160 166 175 400 192 202 221 224 227 231 238 241 244 247 250 254 261 265 272 275 278 281 284 287 290 293 296 299 302 305 308 311 314 317 320 324 331 334 337 340 343 346 349 352 355 359 366 369 372 375 378 381 384 387 390 393 396 ]] #int !jvms: Test::vMeth1 @ bci:23 187 Bool === _ 186 [[ 188 ]] [ge] !jvms: Test::vMeth1 @ bci:29 182 IfFalse === 180 [[ 188 ]] #0 !jvms: Test::vMeth1 @ bci:29 211 ConI === 0 [[ 210 ]] #int:-21 142 AddI === _ 135 141 [[ 144 210 ]] !jvms: Test::vMeth1 @ bci:25 188 If === 182 187 [[ 189 190 ]] P=0.833333, C=0.000156 !jvms: Test::vMeth1 @ bci:29 210 AddI === _ 142 211 [[ 212 ]] !jvms: Test::vMeth1 @ bci:29 190 IfFalse === 188 [[ 218 212 ]] #0 !jvms: Test::vMeth1 @ bci:29 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p key_val->_in[1]->_in[1]->dump(-3) 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 213 ConvI2L === _ 212 [[ 215 217 ]] #long:0..51:www !jvms: Test::vMeth1 @ bci:29 215 MulL === _ 213 214 [[]] !jvms: Test::vMeth1 @ bci:29 217 LShiftL === _ 213 216 [[ 218 ]] !jvms: Test::vMeth1 @ bci:29 218 Jump === 190 217 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 (rr) c Continuing. Thread 3 hit Breakpoint 3, Compile::Compile (this=0x7f80f77fbe00, ci_env=0x7f80f77fc910, target=0x7f810842a1f0, osr_bci=-1, subsume_loads=true, do_escape_analysis=true, eliminate_boxing=true, directive=0x7f8108135660) at ..../open/src/hotspot/share/opto/compile.cpp:736 warning: Source file is more recent than executable. 736 Optimize(); (rr) p find_node(C->root(),212)->dump(3) 141 LShiftI === _ 135 140 [[ 142 ]] !jvms: Test::vMeth1 @ bci:25 135 Phi === 132 446 131 [[ 436 441 142 359 324 141 265 254 446 231 400 202 ]] #int !jvms: Test::vMeth1 @ bci:23 187 Bool === _ 186 [[ 188 ]] [ge] !jvms: Test::vMeth1 @ bci:29 182 IfFalse === 180 [[ 188 ]] #0 !jvms: Test::vMeth1 @ bci:29 211 ConI === 0 [[ 210 ]] #int:-21 142 AddI === _ 135 141 [[ 144 210 ]] !jvms: Test::vMeth1 @ bci:25 188 If === 182 187 [[ 189 190 ]] P=0.833333, C=0.000156 !jvms: Test::vMeth1 @ bci:29 210 AddI === _ 142 211 [[ 212 ]] !jvms: Test::vMeth1 @ bci:29 190 IfFalse === 188 [[ 218 212 ]] #0 !jvms: Test::vMeth1 @ bci:29 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p find_node(C->root(),212)->dump(-3) 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 213 ConvI2L === _ 212 [[ 217 ]] #long:0..51:www !jvms: Test::vMeth1 @ bci:29 217 LShiftL === _ 213 216 [[ 218 ]] !jvms: Test::vMeth1 @ bci:29 218 Jump === 190 217 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 (rr) p find_node(C->root(),213)->_in[1]->dump() 212 CastII === 190 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p &find_node(C->root(),213)->_in[1] $11 = (Node **) 0x7f80ec0986b0 (rr) watch *0x7f80ec0986b0 (rr) c Continuing. Thread 3 hit Hardware watchpoint 5: *0x7f80ec0986b0 Old value = -334920272 New value = -335096024 Node::set_req (this=0x7f80ec098648, i=1, n=0x7f80ec06d728) at ..../open/src/hotspot/share/opto/node.hpp:418 418 if (n != NULL) n->add_out((Node *)this); (rr) where #0 Node::set_req (this=0x7f80ec098648, i=1, n=0x7f80ec06d728) at .../open/src/hotspot/share/opto/node.hpp:418 #1 0x00007f810fd38cbe in PhaseIterGVN::subsume_node (this=0x7f80f77f98b0, old=0x7f80ec0985b0, nn=0x7f80ec06d728) at .../open/src/hotspot/share/opto/phaseX.cpp:1459 #2 0x00007f810fd3807a in PhaseIterGVN::transform_old (this=0x7f80f77f98b0, n=0x7f80ec0985b0) at ..../open/src/hotspot/share/opto/phaseX.cpp:1289 #3 0x00007f810fd37a62 in PhaseIterGVN::optimize (this=0x7f80f77f98b0) at ...open/src/hotspot/share/opto/phaseX.cpp:1175 #4 0x00007f810fb56189 in PhaseIdealLoop::build_and_optimize (this=0x7f80f77f8b90, mode=LoopOptsDefault) at ...open/src/hotspot/share/opto/loopnode.cpp:3192 #5 0x00007f810f539de9 in PhaseIdealLoop::PhaseIdealLoop (this=0x7f80f77f8b90, igvn=..., mode=LoopOptsDefault) at ../open/src/hotspot/share/opto/loopnode.hpp:951 #6 0x00007f810f539ee4 in PhaseIdealLoop::optimize (igvn=..., mode=LoopOptsDefault) at .../open/src/hotspot/share/opto/loopnode.hpp:1026 #7 0x00007f810f52dceb in Compile::optimize_loops (this=0x7f80f77fbe00, igvn=..., mode=LoopOptsDefault) at .../open/src/hotspot/share/opto/compile.cpp:1970 #8 0x00007f810f52ea96 in Compile::Optimize (this=0x7f80f77fbe00) at .../open/src/hotspot/share/opto/compile.cpp:2182 .................... (rr) break phaseX.cpp:1266 (rr) reverse-continue ..... ////// @ [PhaseIterGVN::transform_old()] - const Type* t = k->Value(this); ////** Adding breakpint at PhaseIterGVN::transform_old() before the Value() call, and reverse continue debugging with rr, found that the range check dependent CastIINode 212, gets replaced by TOP afterwards and thus leads to the assert failure. Also following temporary change tried at PhaseIterGVN::transform_old(), helps to confirm this behavior for the test case. With this sample change got no crash for The test case. .... const Type* t = k->Value(this); assert(t != NULL, "value sanity"); + // Range check dependent CastIINodes should not be replaced by TOP + if (!(t == Type::TOP && k->is_CastII() && ((CastIINode *)k)->has_range_check())) { // Since I just called 'Value' to compute the set of run-time values .... subsume_node(k, con); // Everybody using k now uses con return con; } + } **//// ////*** Similar to following existing comments, checkings @ CastIINode::Ideal(), Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) { ........................ // Similar to ConvI2LNode::Ideal() for the same reasons // Do not narrow the type of range check dependent CastIINodes to // avoid corruption of the graph if a CastII is replaced by TOP but // the corresponding range check is not removed. if (can_reshape && !_range_check_dependency && !phase->C->major_progress()) { .................. } tried some sample changes with checking '_range_check_dependency' and TOP results @ CastIINode::Value(), but did not work. .e.g.: const Type* CastIINode::Value(PhaseGVN* phase) const { const Type *res = ConstraintCastNode::Value(phase); + if (res == Type::TOP && _range_check_dependency) { + res = phase->type(this); + assert (res != Type::TOP, "Range check dependent CastIINodes should not be replaced by TOP"); + } ............ ////*** ....... (rr) reverse-continue Continuing. Thread 3 hit Breakpoint 6, PhaseIterGVN::transform_old (this=0x7f80f77f98b0, n=0x7f80ec0985b0) at /home/rvraghav/data/build/jdk-jdk/open/src/hotspot/share/opto/phaseX.cpp:1266 1266 const Type* t = k->Value(this); (rr) p k->dump(3) 141 LShiftI === _ 135 140 [[ 142 ]] !jvms: Test::vMeth1 @ bci:25 135 Phi === 532 827 526 [[ 820 819 142 818 817 141 816 815 526 814 813 ]] #int:1..4 #tripcount !jvms: Test::vMeth1 @ bci:23 509 Bool === _ 25 [[ 510 ]] [lt] 182 IfFalse === 180 [[ 510 ]] #0 !jvms: Test::vMeth1 @ bci:29 211 ConI === 0 [[ 210 557 703 ]] #int:-21 142 AddI === _ 135 141 [[ 144 210 484 498 ]] !jvms: Test::vMeth1 @ bci:25 510 If === 182 509 [[ 511 512 ]] P=0.166667, C=0.000156 !orig=[188] !jvms: Test::vMeth1 @ bci:29 210 AddI === _ 142 211 [[ 212 ]] !jvms: Test::vMeth1 @ bci:29 512 IfTrue === 510 [[ 212 218 ]] #1 !orig=[190] !jvms: Test::vMeth1 @ bci:29 212 CastII === 512 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p k->dump(-3) 212 CastII === 512 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 213 ConvI2L === _ 212 [[ 217 ]] #long:0..51:www !jvms: Test::vMeth1 @ bci:29 217 LShiftL === _ 213 216 [[ 218 ]] !jvms: Test::vMeth1 @ bci:29 218 Jump === 512 217 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 (rr) s CastIINode::Value (this=0x7f80ec0985b0, phase=0x7f80f77f98b0) at /home/rvraghav/data/build/jdk-jdk/open/src/hotspot/share/opto/castnode.cpp:159 159 const Type *res = ConstraintCastNode::Value(phase); (rr) s ConstraintCastNode::Value (this=0x7f80ec0985b0, phase=0x7f80f77f98b0) at /home/rvraghav/data/build/jdk-jdk/open/src/hotspot/share/opto/castnode.cpp:51 51 if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP; (rr) n 52 const Type* ft = phase->type(in(1))->filter_speculative(_type); (rr) p this->dump(3) 141 LShiftI === _ 135 140 [[ 142 ]] !jvms: Test::vMeth1 @ bci:25 135 Phi === 532 827 526 [[ 820 819 142 818 817 141 816 815 526 814 813 ]] #int:1..4 #tripcount !jvms: Test::vMeth1 @ bci:23 509 Bool === _ 25 [[ 510 ]] [lt] 182 IfFalse === 180 [[ 510 ]] #0 !jvms: Test::vMeth1 @ bci:29 211 ConI === 0 [[ 210 557 703 ]] #int:-21 142 AddI === _ 135 141 [[ 144 210 484 498 ]] !jvms: Test::vMeth1 @ bci:25 510 If === 182 509 [[ 511 512 ]] P=0.166667, C=0.000156 !orig=[188] !jvms: Test::vMeth1 @ bci:29 210 AddI === _ 142 211 [[ 212 ]] !jvms: Test::vMeth1 @ bci:29 512 IfTrue === 510 [[ 212 218 ]] #1 !orig=[190] !jvms: Test::vMeth1 @ bci:29 212 CastII === 512 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 (rr) p this->dump(-3) 212 CastII === 512 210 [[ 213 ]] #int:0..51:www range check dependency !jvms: Test::vMeth1 @ bci:29 213 ConvI2L === _ 212 [[ 217 ]] #long:0..51:www !jvms: Test::vMeth1 @ bci:29 217 LShiftL === _ 213 216 [[ 218 ]] !jvms: Test::vMeth1 @ bci:29 218 Jump === 512 217 [[ 219 222 225 228 236 239 242 245 248 251 259 262 270 273 276 279 282 285 288 291 294 297 300 303 306 309 312 315 318 321 329 332 335 338 341 344 347 350 353 356 364 367 370 373 376 379 382 385 388 391 394 397 ]] !jvms: Test::vMeth1 @ bci:29 (rr) p phase->type(this)->dump() int:0..51:www$16 = void (rr) p phase->type(in(1))->dump() int:-16..-1$17 = void the type range of _in[1] node as [-16..-1], is not within or matching for the type range of the range check CastII node - [0..51]. This results in TOP getting returned for the above last Value() call, and subsequently the assert failure for The test. Work in progress to check why the range check node becomes known to be outside of the range it is casted to. Retriaging this issue = ILW = Crash (H); for now rare case/ only with javafuzzer test (L); -XX:-UseSwitchProfiling (M) = P3
03-07-2020

For now re-targeting to JDK 16. Need more time for correct fix; also not safe to push the fix near release milestone. (seems a rare / corner case issue, not new in JDK 15) Working to push the fix to mainline and then later backport to earlier versions.
25-06-2020

# [Test.java] // Reduced New Test public class Test { public static void vMeth1() { int i4, i5=99, i6, i9=89; for (i4 = 12; i4 < 365; i4++) { for (i6 = 5; i6 > 1; i6--) { switch ((i6 * 5) + 11) { case 13: case 19: case 26: case 31: case 35: case 41: case 43: case 61: case 71: case 83: case 314: i9 = i5; break; } } } } public static void main(String[] strArr) { for (int i = 0; i < 10; i++) { vMeth1(); } } }
28-05-2020

Regarding the sample temporary modifications tried in the comments above - https://bugs.openjdk.java.net/browse/JDK-8238812?focusedCommentId=14331847&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14331847 - if (needs_guard) { + if (needs_guard || (trim_ranges && trimmed_cnt == 0)) { (Thanks to Tobias for comment details, suggestion points.) One of the reasons for trying this modifications is - 'trim_ranges && trimmed_cnt == 0' already used with the 'jump_if_true_fork()' call in the if body, seems never be true with existing case, as 'trimmed_cnt' seems always non-zero when 'needs_guard' is set! (this observation may mean that we are actually never adding an uncommon trap. That should be fixed as well but is most likely unrelated to this current bug) Also understood with the temporary change mentioned, range check on key_val will be emitted in more cases. This helps because if the type of key_val is later known to be out of range, this check will be always false and subsequent code dies consistently. However, that guard is costly and should be avoided if possible. So working, debugging further to better understand why the assert is it and root cause location leading to the same.
28-05-2020

Sample new fix changes tried - - reverting the old 8229855 changes in Parse::jump_switch_ranges(); - and modifying a condition check in Parse::create_jump_tables(). ====================================== [src/hotspot/share/opto/parse2.cpp] ....... bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi) { ....... bool trim_ranges = !C->too_many_traps(method(), bci(), Deoptimization::Reason_unstable_if); ....... bool needs_guard = false; ....... // If a guard test will eliminate very sparse end ranges, then // it is worth the cost of an extra jump. float trimmed_cnt = 0; if (total_outlier_size > (MaxJumpTableSparseness * 4)) { needs_guard = true; if (default_dest == lo->dest()) { trimmed_cnt += lo->cnt(); lo++; } if (default_dest == hi->dest()) { trimmed_cnt += hi->cnt(); hi--; } } ....... // Generate a guard to protect against input keyvals that aren't // in the switch domain. - if (needs_guard) { + if (needs_guard || (trim_ranges && trimmed_cnt == 0)) { Node* size = _gvn.intcon(num_cases); Node* cmp = _gvn.transform(new CmpUNode(key_val, size)); Node* tst = _gvn.transform(new BoolNode(cmp, BoolTest::ge)); IfNode* iff = create_and_map_if(control(), tst, if_prob(trimmed_cnt, total), if_cnt(trimmed_cnt)); jump_if_true_fork(iff, default_dest, NullTableIndex, trim_ranges && trimmed_cnt == 0); total -= trimmed_cnt; } .............. .............. void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi, int switch_depth) { ........ // if there is a higher range, test for it and process it: if (mid < hi && !eq_test_only) { // two comparisons of same values--should enable 1 test for 2 branches - // Use BoolTest::lt instead of BoolTest::gt + // Use BoolTest::le instead of BoolTest::gt float cnt = sum_of_cnts(lo, mid-1); - IfNode *iff_lt = jump_if_fork_int(key_val, test_val, BoolTest::lt, if_prob(cnt, total_cnt), if_cnt(cnt)); - Node *iftrue = _gvn.transform( new IfTrueNode(iff_lt) ); - Node *iffalse = _gvn.transform( new IfFalseNode(iff_lt) ); + IfNode *iff_le = jump_if_fork_int(key_val, test_val, BoolTest::le, if_prob(cnt, total_cnt), if_cnt(cnt)); + Node *iftrue = _gvn.transform( new IfTrueNode(iff_le) ); + Node *iffalse = _gvn.transform( new IfFalseNode(iff_le) ); { PreserveJVMState pjvms(this); set_control(iffalse); jump_switch_ranges(key_val, mid+1, hi, switch_depth+1); ======================================
20-04-2020

This reported assert failure 8238812 started in JDK14b32 build with old 8229855 fix changeset. Attached reduced test. $ java -XX:CompileCommand=compileonly,Test::vMeth1 -XX:-TieredCompilation Test
02-04-2020

Could be reproduced with 'java Test'.
10-02-2020