--- old/src/share/vm/opto/chaitin.cpp	Mon Jan 12 16:05:14 2009
+++ new/src/share/vm/opto/chaitin.cpp	Mon Jan 12 16:05:14 2009
@@ -228,6 +228,16 @@
   // them for real.
   de_ssa();
 
+#ifdef ASSERT
+  // Veify the graph before RA.
+  if( VerifyOpto || VerifyRegisterAllocator ) {
+    _cfg.verify();
+  }
+#endif
+  // Collect exception blocks.
+  Block_List ex_blocks;
+  collect_ex_blocks(ex_blocks);
+
   {
     NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
     _live = NULL;                 // Mark live as being not available
@@ -256,6 +266,10 @@
     live.compute( _maxlrg );
     _live = &live;
   }
+
+  // Fixup exception blocks before ifg.
+  fixup_ex_blocks(ex_blocks);
+
   // Create the interference graph using virtual copies
   build_ifg_virtual( );  // Include stack slots this time
 
@@ -306,6 +320,9 @@
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
     if (C->failing())  return;
 
+    // Fixup exception blocks after Split.
+    fixup_ex_blocks(ex_blocks);
+
 #ifdef ASSERT
     if( VerifyOpto || VerifyRegisterAllocator ) {
       _cfg.verify();
@@ -376,6 +393,10 @@
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
     if (C->failing())  return;
+
+    // Fixup exception blocks after Split.
+    fixup_ex_blocks(ex_blocks);
+
 #ifdef ASSERT
     if( VerifyOpto || VerifyRegisterAllocator ) {
       _cfg.verify();
@@ -432,6 +453,16 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+  // Fixup exception blocks at the end of RA.
+  fixup_ex_blocks(ex_blocks);
+
+#ifdef ASSERT
+  if( VerifyOpto || VerifyRegisterAllocator ) {
+    _cfg.verify();
+    verify_base_ptrs(&live_arena);
+  }
+#endif
+
   // max_reg is past the largest *register* used.
   // Convert that to a frame_slot number.
   if( _max_reg <= _matcher._new_SP )
@@ -1408,6 +1439,49 @@
   } // End of for all blocks
 }
 
+
+//------------------------------collect_ex_blocks-----------------------------
+// Collect blocks with CreateEx.
+void PhaseChaitin::collect_ex_blocks(Block_List& ex_blocks) {
+  // For all blocks
+  for( uint i = 0; i < _cfg._num_blocks; i++ ) {
+    Block* b = _cfg._blocks[i];
+    uint last_inst = b->end_idx();
+    for( uint insidx = 1; insidx < last_inst; insidx++ ) {
+      Node* n = b->_nodes[insidx];
+      if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+        ex_blocks.push(b);
+        break;
+      }
+    }
+  }
+}
+
+//------------------------------fixup_ex_blocks-------------------------------
+// Spills could be inserted before CreateEx node which should be first
+// instruction in an exception block after Phis. Move CreateEx node up.
+void PhaseChaitin::fixup_ex_blocks(Block_List& ex_blocks) {
+  // For all exception blocks.
+  for( uint i = 0; i < ex_blocks.size(); i++ ) {
+    Block* b = ex_blocks[i];
+    uint last_inst = b->end_idx();
+    uint last_phi = 1;
+    for( ; last_phi < last_inst; last_phi++ )
+      if( !b->_nodes[last_phi]->is_Phi() )
+        break;
+
+    for( uint insidx = (last_phi+1); insidx < last_inst; insidx++ ) {
+      Node* n = b->_nodes[insidx];
+      if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+        b->_nodes.remove(insidx);
+        b->_nodes.insert(last_phi, n);
+        break;
+      }
+    }
+  }
+}
+
+
 //------------------------------find_base_for_derived--------------------------
 // Helper to stretch above; recursively discover the base Node for a
 // given derived Node.  Easy for AddP-related machine nodes, but needs
