JDK-8039050 : Crash in C2 compiler at Node::rematerialize
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 7u40,7u80,8u20,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86_64
  • Submitted: 2014-04-02
  • Updated: 2021-03-08
  • Resolved: 2014-04-15
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 6 JDK 7 JDK 8 JDK 9
6u85Fixed 7u75Fixed 8u25Fixed 9 b11Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The crash is reproducible in JDK6 and JDK7. In JDK8 and JDK9 the crash is not reproducible if TieredCompilation flag is set (src/cpu/x86/vm/c2_globals_x86.hpp).

Crash reproducer attached.
java -d64  -XX:-TieredCompilation -cp lib/runtime/*:build/classes/ org.openbravo.JasperC2CompilerCrash

Comment from Vladimir Kozlov:
==================================================================================
Looks like we will not convert a loop into Counted (canonical) loop if predicate is not present so 5091921 problem will not be created:

    // Loop limit check predicate should be near the loop.
    ProjNode *limit_check_proj = find_predicate_insertion_point(init_control, Deoptimization::Reason_loop_limit_check);
    if (!limit_check_proj) {
      // The limit check predicate is not generated if this method trapped here before.
#ifdef ASSERT
      if (TraceLoopLimitCheck) {
        tty->print("missing loop limit check:");
        loop->dump_head();
        x->dump(1);
      }
#endif
      return false;
    }

The same is for a loop predication.
==================================================================================
Comments
If this is regression please add rergession label and provide information on what build it was introduced in. Please add appropriate mapping to explain absence of regression test.
29-05-2014

I tested 2014-04-15-062318.sgabdura.jdk7u51 on linux-x64. - the bug test passed. - 8039247 tests compiler/7119644 passed - 8039296 test closed/compiler/6536652/VTest.java passed I am not sure 8039298 is related to 8038785 since we see similar problem in 9. I will work on it separately.
15-04-2014

Sergey, can you also check if 3 bugs filed after your change are not reproduced now? I mean 8039247, 8039296, 8039298. Thanks!
15-04-2014

http://cr.openjdk.java.net/~kvn/8039050/webrev/
15-04-2014

I tested the patch for src/share/vm/opto/loopTransform.cpp on hsx/jdk7u/hotspot. It works. Is it a final version of the fix?
14-04-2014

Agreed -XX:-RangeCheckElimination is fully functional workaround with a performance hit. Recaculating ILW: ILW=Crash or assert, reproducible but not common, -XX:-RangeCheckElimination=HMM=P2
10-04-2014

I should trust C2 more :) Putting all nodes from original loop on IGVN worklist (as we do in other loop opts after cloning) eliminated part of graph and make resulting graph correct: src/share/vm/opto/loopTransform.cpp @@ -1150,6 +1150,7 @@ // Now force out all loop-invariant dominating tests. The optimizer // finds some, but we _know_ they are all useless. peeled_dom_test_elim(loop,old_new); + loop->record_for_igvn(); } //------------------------------is_invariant----------------------------- RangeCheck Loop: N713/N650 counted [int,int),+1 (1 iters) main Loop: N0/N0 Loop: N700/N491 limit_check predicated Loop: N998/N1005 counted [int,int),+1 (4 iters) pre Loop: N713/N650 counted [int,int),+1 (1 iters) main Loop: N808/N815 counted [int,int),+1 (4 iters) post Peel Loop: N713/N650 counted [int,int),+1 (1 iters) main Loop: N0/N0 Loop: N700/N491 limit_check predicated Loop: N998/N1005 counted [int,int),+1 (4 iters) pre Loop: N713/N650 counted [int,int),+1 (1 iters) Loop: N808/N815 counted [int,int),+1 (4 iters) post Empty with zero trip guard Loop: N713/N650 counted [int,int),+1 (1 iters) Loop: N0/N0 Loop: N700/N491 limit_check predicated Loop: N998/N1005 counted [int,int),+1 (4 iters) pre Loop: N808/N815 counted [int,int),+1 (4 iters) post PredicatesOff Loop: N0/N0 Loop: N700/N491 Loop: N998/N1005 counted [int,int),+1 (4 iters) pre Loop: N808/N815 counted [int,int),+1 (4 iters) post execution completed, exit code is 0
10-04-2014

May be we should avoid converting such loops into counted when we do OSR compilation. Some small benchmarks which rely only on OSR could be affected.
10-04-2014

So far I don't see anything wrong with compiler code. It is a problem how we define nested loops during OSR compilation when entry bci is inner loop. Again, the program works if Loop: N713/N650 is not split.
10-04-2014

One of the phi (used by array addressing) has -1 as value on loop's back branch. When post-loop is created it take that backedge value as input as result in post loop the corresponding Phi collapse to -1. And whole address expression in post-loop becomes top because it expects only positive values. That is why we don't have value from post loop and it creates the bypass.
10-04-2014

So why P1? It is also goes away if range check elimination is off: -XX:-RangeCheckElimination which switches off iteration splitting. But it is very heavy performance hammer!
10-04-2014

ILW=Crash or assert, reproducible but not common, tiered seems to make it go away - but it is a loopopt issue - so probably by chance.=HMH=P1
09-04-2014

Looks like loopopts is responsible during PreMainPost loop splitting it creates a use outside the loop: Loop: N0/N0 Loop: N700/N491 limit_check predicated Loop: N713/N650 counted [int,int),+1 (1 iters) PreMainPost Loop: N713/N650 counted [int,int),+1 (1 iters) RangeCheck Loop: N713/N650 counted [int,int),+1 (1 iters) main Loop: N0/N0 Loop: N700/N491 limit_check predicated Loop: N998/N1005 counted [int,int),+1 (4 iters) pre Loop: N713/N650 counted [int,int),+1 (1 iters) main Loop: N808/N815 counted [int,int),+1 (4 iters) post
09-04-2014

There is a path to B39 (which consumes L78) which bypass blocks where L78 is defined (B74, B87, B73): B39: # B41 B40 <- B37 Freq: 0.00116631 L0/N453 Region === L0/N453 L0/N137 L147[R10,R11,R8,R9,RCX,RBX,RDI,RDX,RSI,RAX,RBP,R13,R14]/N138 loadN === L0/N453 L0/N18 L127[R10-RSP_H]/N139 L78[R10-R9_H,RCX-R14_H]/N208 narrowoop: net/sf/jasperreports/engine/export/JRExporterGridCell * B74: # B26 <- B87 B73 Freq: 205422 L0/N154 Region === L0/N154 L0/N485 L0/N484 L78/N208 Phi === L0/N154 L78/N562 L78/N563 #long:0..8589934584:www
09-04-2014

I see that this L78 live range is in liveout lists in all exit blocks, including uncommon trap blocks: L0/N34 ShouldNotReachHere === L0/N35 L0/N0 L0/N0 L1[RSP,RSP_H]/N19 L0/N0 Liveout: {L78 }
09-04-2014

Somehow root block got live range: B1: # B2 <- B6 B4 B38 B79 B40 B27 B29 B31 B33 B47 B49 B19 B71 B68 B65 Freq: 1 L0/N1 Root === L0/N1 L0/N2 L0/N34 L0/N51 L0/N297 L0/N304 L0/N312 L0/N319 L0/N327 L0/N334 L0/N342 L0/N349 L0/N356 L0/N361 L0/N374 L0/N390 Liveout: {L78 } But there are no any defining nodes at this point since no nodes were processed yet. B1 is the first block we process. That is what Reachblock[slidx] == NULL means. I added Niclas to watch list.
09-04-2014

With latest jdk9 debug VM I hit assert in RA for the same compilation: # Internal Error (src/share/vm/opto/reg_split.cpp:1262), pid=9697, tid=140402399704832 # assert(Reachblock[slidx] != NULL) failed: No reaching definition for liveout value V [libjvm.so+0x694866] report_vm_error(char const*, int, char const*, char const*)+0xa9 V [libjvm.so+0xc28dfa] PhaseChaitin::Split(unsigned int, ResourceArea*)+0x3514 V [libjvm.so+0x5761ee] PhaseChaitin::Register_Allocate()+0x548 V [libjvm.so+0x623943] Compile::Code_Gen()+0x283 V [libjvm.so+0x61d657] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool)+0x13f7 V [libjvm.so+0x54eb37] C2Compiler::compile_method(ciEnv*, ciMethod*, int)+0xf5 V [libjvm.so+0x63496b] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x461 V [libjvm.so+0x634023] CompileBroker::compiler_thread_loop()+0x349 V [libjvm.so+0xd0381a] compiler_thread_entry(JavaThread*, Thread*)+0x57 V [libjvm.so+0xcfedb7] JavaThread::thread_main_inner()+0x14f V [libjvm.so+0xcfec59] JavaThread::run()+0x163 V [libjvm.so+0xb84fe6] java_start(Thread*)+0x1ad C [libpthread.so.0+0x79d1] Current CompileTask: C2: 9343 103 % b net.sf.jasperreports.engine.export.JRGridLayout::horizontallyMergeEmptyCells @ 18 (175 bytes)
08-04-2014