SUGGESTED FIX
==== //java/main-dev/java/hotspot5/src/share/vm/opto/split_if.cpp#7 - /home/cliffc/HotSpot/cliffc-bugs/hotspot5/src/share/vm/opto/split_if.cpp ====
@@ -534,19 +534,14 @@
region_cache.lru_insert( new_false, new_false );
region_cache.lru_insert( new_true , new_true );
// Now handle all uses of the splitting block
- for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) {
- Node* phi = region->last_out(k);
+ for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
+ Node* phi = region->fast_out(k);
if( !phi->in(0) ) { // Dead phi? Remove it
_igvn.remove_dead_node(phi);
- continue;
- }
- assert( phi->in(0) == region, "" );
- if( phi == region ) { // Found the self-reference
- phi->set_req(0, NULL);
- continue; // Break the self-cycle
- }
- // Expected common case: Phi hanging off of Region
- if( phi->is_Phi() ) {
+ } else if( phi == region ) { // Found the self-reference
+ continue; // No roll-back of DUIterator
+ } else if( phi->is_Phi() ) { // Expected common case: Phi hanging off of Region
+ assert0( phi->in(0) == region );
assert0( phi->in(LoopNode::LoopBackControl) != phi );
// Need a per-def cache. Phi represents a def, so make a cache
small_cache phi_cache;
@@ -561,20 +556,25 @@
// 2-element cache to handle multiple uses from the same block.
handle_use( use, phi, &phi_cache, iff_replacement, new_false, new_true, old_false, old_true );
} // End of while phi has uses
-
- // Because handle_use might relocate region->_out,
- // we must refresh the iterator.
- k = region->last_outs(kmin);
// Remove the dead Phi
_igvn.remove_dead_node( phi );
} else {
+ assert0( phi->in(0) == region );
// Random memory op guarded by Region. Compute new DEF for USE.
handle_use( phi, region, ®ion_cache, iff_replacement, new_false, new_true, old_false, old_true );
}
+ // Every path above deletes a use of the region, except for the region
+ // self-cycle (which is needed by handle_use calling get_early_ctrl
+ // calling get_ctrl_no_assert calling get_ctrl_no_update looking for dead
+ // regions). So roll back the DUIterator innards.
+ --k;
+ --kmax;
+ } // End of while merge point has phis
- } // End of while merge point has phis
+ assert0( region->outcnt() == 1 ); // Just Self on the Region
+ region->set_req(0, NULL); // Break the self-cycle
// Any leftover bits in the splitting block must not have depended on local
// Phi inputs (these have already been split-up). Hence it's safe to hoist
|