United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6758445 loop heads that are exception entry points can crash during count_edges/mark_loops
JDK-6758445 : loop heads that are exception entry points can crash during count_edges/mark_loops

Details
Type:
Bug
Submit Date:
2008-10-10
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
hotspot
OS:
solaris_9
Sub-Component:
compiler
CPU:
sparc
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs10
Fixed Versions:
hs14 (b08)

Related Reports
Backport:
Backport:
Backport:

Sub Tasks

Description
Ok, I've just attached the files...too complicated to find somewhere to put them..

test.class is the class "ruby.test". jruby.jar is JRuby's jar. Run with:

java -client -cp jruby.jar:. ruby.test

(assuming you put the test.class in ./ruby)

It should crash under any version of JDK 6 client compiler.

I've also attached the Ruby source. If you want to just run it directly, and JRuby will compile it before run, do it like this:

java -jar jruby.jar org.jruby.Main test.rb

- Charlie
$ok = true

def getc
 if $ok
   $ok = false
   nil
 else
   $ok = true
   50
 end
end

def gets
 c = getc or return
 l = ""
 begin
   l.concat c unless c == "\r"
   break if c == "\n"
 end while c = getc
 l
end

loop { gets }

                                    

Comments
SUGGESTED FIX

diff --git a/src/share/vm/c1/c1_IR.cpp b/src/share/vm/c1/c1_IR.cpp                                                                   
--- a/src/share/vm/c1/c1_IR.cpp                                                                                                      
+++ b/src/share/vm/c1/c1_IR.cpp                                                                                                      
@@ -574,12 +574,23 @@ void ComputeLinearScanOrder::count_edges
     TRACE_LINEAR_SCAN(3, tty->print_cr("backward branch"));                                                                         
     assert(is_visited(cur), "block must be visisted when block is active");                                                         
     assert(parent != NULL, "must have parent");                                                                                     
-    assert(parent->number_of_sux() == 1, "loop end blocks must have one successor (critical edges are split)");                     
                                                                                                                                     
     cur->set(BlockBegin::linear_scan_loop_header_flag);                                                                             
     cur->set(BlockBegin::backward_branch_target_flag);                                                                              
                                                                                                                                     
     parent->set(BlockBegin::linear_scan_loop_end_flag);                                                                             
+                                                                                                                                    
+    // When a loop header is also the start of an exception handler, then the backward branch is                                    
+    // an exception edge. Because such edges are usually critical edges which cannot be split, the                                  
+    // loop must be excluded here from processing.                                                                                  
+    if (cur->is_set(BlockBegin::exception_entry_flag)) {                                                                            
+      // Make sure that dominators are correct in this weird situation                                                              
+      _iterative_dominators = true;                                                                                                 
+      return;                                                                                                                       
+    }                                                                                                                               
+    assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,                                                                
+           "loop end blocks must have one successor (critical edges are split)");                                                   
+                                                                                                                                    
     _loop_end_blocks.append(parent);                                                                                                
     return;                                                                                                                         
   }
                                     
2008-10-10
EVALUATION

So I'm looking at this crash and I'm seeing asserts that are unhappy about some loop structures that are being formed with exception handlers.  I think it's a throw of a BreakJump that goes to a handler which jumps into a loop.  I'm guessing that the problem is that it's producing a control structure you couldn't make from normal Java source.  In Java it would/might require multiple separate exception ranges.

I think it's something like this:

try
 if (something) throw BreakJump

 loop:
   .....

catch (BreakJump bj)
 goto loop

You'd have to build a structure like that in java source very differently and I think we'd handle that correctly but I don't think we've seen anything structured like this before.  We can probably fix this but you might want to think about a workaround given how long it takes for releases to make it into users hands.  I'll look into a fix for it.  How do I get a version of the class file that was generated? The test.class you sent me appeared to be corrupted in some way.

*** (#1 of 1): [ UNSAVED ] ###@###.###
                                     
2008-10-10
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/334969144810
                                     
2008-11-12



Hardware and Software, Engineered to Work Together