--- old/src/share/vm/opto/block.cpp Mon Jan 12 16:05:13 2009 +++ new/src/share/vm/opto/block.cpp Mon Jan 12 16:05:13 2009 @@ -894,10 +894,16 @@ "CreateEx must be first instruction in block" ); } for( uint k = 0; k < n->req(); k++ ) { - Node *use = n->in(k); - if( use && use != n ) { - assert( _bbs[use->_idx] || use->is_Con(), + Node *def = n->in(k); + if( def && def != n ) { + assert( _bbs[def->_idx] || def->is_Con(), "must have block; constants for debug info ok" ); + if( _bbs[def->_idx] == b && + !(b->head()->is_Loop() && n->is_Phi()) && + // See (+++) comment in reg_split.cpp + !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) { + assert( b->find_node(def) < j, "uses must follow definitions" ); + } } } } --- 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 --- old/src/share/vm/opto/chaitin.hpp Mon Jan 12 16:05:14 2009 +++ new/src/share/vm/opto/chaitin.hpp Mon Jan 12 16:05:14 2009 @@ -451,6 +451,12 @@ // Set C->failing when fixup spills could not complete, node limit exceeded. void fixup_spills(); + // Collect blocks with CreateEx node. + void PhaseChaitin::collect_ex_blocks(Block_List& ex_blocks); + + // Move CreateEx node to the beginning of its block after phis. + void PhaseChaitin::fixup_ex_blocks(Block_List& ex_blocks); + // Post-Allocation peephole copy removal void post_allocate_copy_removal(); Node *skip_copies( Node *c ); --- old/src/share/vm/opto/live.cpp Mon Jan 12 16:05:15 2009 +++ new/src/share/vm/opto/live.cpp Mon Jan 12 16:05:14 2009 @@ -319,7 +319,7 @@ } } } else if( check->bottom_type()->is_ptr()->_offset == 0 ) { - if(check->is_Proj() || check->is_Mach() && + if(!check->is_Proj() && !(check->is_Mach() && (check->as_Mach()->ideal_Opcode() == Op_CreateEx || check->as_Mach()->ideal_Opcode() == Op_ThreadLocal || check->as_Mach()->ideal_Opcode() == Op_CMoveP || @@ -329,7 +329,7 @@ UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN || #endif check->as_Mach()->ideal_Opcode() == Op_LoadP || - check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) + check->as_Mach()->ideal_Opcode() == Op_LoadKlass))) assert(false,"Bad base or derived pointer"); } else { assert(is_derived,"Bad base pointer"); --- old/src/share/vm/opto/reg_split.cpp Mon Jan 12 16:05:15 2009 +++ new/src/share/vm/opto/reg_split.cpp Mon Jan 12 16:05:15 2009 @@ -96,9 +96,7 @@ // its definer. while( i < b->_nodes.size() && (b->_nodes[i]->is_Proj() || - b->_nodes[i]->is_Phi() || - (b->_nodes[i]->is_Mach() && - b->_nodes[i]->as_Mach()->ideal_Opcode() == Op_CreateEx)) ) + b->_nodes[i]->is_Phi() ) ) i++; // Do not insert between a call and his Catch