aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkvn <none@none>2009-01-07 11:04:45 -0800
committerkvn <none@none>2009-01-07 11:04:45 -0800
commit91b63c49f23d5cd7917ad7f7bc91c21d3bf7b564 (patch)
treee2ff36c6bbd6cf7c4e501bb5145b3fa79973853d /src
parent34ab81c1d1b1fc661a103af3dc2c129b754a9486 (diff)
6782232: assert("CreateEx must be first instruction in block" )
Summary: Add the missing check for CreateEx. Add new notproduct flag VerifyRegisterAllocator. Reviewed-by: never
Diffstat (limited to 'src')
-rw-r--r--src/share/vm/opto/c2_globals.hpp3
-rw-r--r--src/share/vm/opto/chaitin.cpp10
-rw-r--r--src/share/vm/opto/live.cpp67
-rw-r--r--src/share/vm/opto/reg_split.cpp4
4 files changed, 62 insertions, 22 deletions
diff --git a/src/share/vm/opto/c2_globals.hpp b/src/share/vm/opto/c2_globals.hpp
index 844d637e5..3a516ab98 100644
--- a/src/share/vm/opto/c2_globals.hpp
+++ b/src/share/vm/opto/c2_globals.hpp
@@ -191,6 +191,9 @@
notproduct(bool, VerifyHashTableKeys, true, \
"Verify the immutability of keys in the VN hash tables") \
\
+ notproduct(bool, VerifyRegisterAllocator , false, \
+ "Verify Register Allocator") \
+ \
develop_pd(intx, FLOATPRESSURE, \
"Number of float LRG's that constitute high register pressure") \
\
diff --git a/src/share/vm/opto/chaitin.cpp b/src/share/vm/opto/chaitin.cpp
index 0456db5dc..3d98f65d6 100644
--- a/src/share/vm/opto/chaitin.cpp
+++ b/src/share/vm/opto/chaitin.cpp
@@ -307,7 +307,7 @@ void PhaseChaitin::Register_Allocate() {
if (C->failing()) return;
#ifdef ASSERT
- if( VerifyOpto ) {
+ if( VerifyOpto || VerifyRegisterAllocator ) {
_cfg.verify();
verify_base_ptrs(&live_arena);
}
@@ -340,7 +340,7 @@ void PhaseChaitin::Register_Allocate() {
compress_uf_map_for_nodes();
#ifdef ASSERT
- if( VerifyOpto ) _ifg->verify(this);
+ if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this);
#endif
} else {
ifg.SquareUp();
@@ -377,7 +377,7 @@ void PhaseChaitin::Register_Allocate() {
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
if (C->failing()) return;
#ifdef ASSERT
- if( VerifyOpto ) {
+ if( VerifyOpto || VerifyRegisterAllocator ) {
_cfg.verify();
verify_base_ptrs(&live_arena);
}
@@ -412,7 +412,7 @@ void PhaseChaitin::Register_Allocate() {
}
compress_uf_map_for_nodes();
#ifdef ASSERT
- if( VerifyOpto ) _ifg->verify(this);
+ if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this);
#endif
cache_lrg_info(); // Count degree of LRGs
@@ -956,7 +956,7 @@ void PhaseChaitin::Simplify( ) {
while ((neighbor = elements.next()) != 0) {
LRG *n = &lrgs(neighbor);
#ifdef ASSERT
- if( VerifyOpto ) {
+ if( VerifyOpto || VerifyRegisterAllocator ) {
assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
}
#endif
diff --git a/src/share/vm/opto/live.cpp b/src/share/vm/opto/live.cpp
index 4127f67e1..48717fc66 100644
--- a/src/share/vm/opto/live.cpp
+++ b/src/share/vm/opto/live.cpp
@@ -271,9 +271,9 @@ void PhaseLive::dump( const Block *b ) const {
//------------------------------verify_base_ptrs-------------------------------
// Verify that base pointers and derived pointers are still sane.
-// Basically, if a derived pointer is live at a safepoint, then its
-// base pointer must be live also.
void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
+#ifdef ASSERT
+ Unique_Node_List worklist(a);
for( uint i = 0; i < _cfg._num_blocks; i++ ) {
Block *b = _cfg._blocks[i];
for( uint j = b->end_idx() + 1; j > 1; j-- ) {
@@ -287,28 +287,63 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
// Now scan for a live derived pointer
if (jvms->oopoff() < sfpt->req()) {
// Check each derived/base pair
- for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx += 2) {
+ for (uint idx = jvms->oopoff(); idx < sfpt->req(); idx++) {
Node *check = sfpt->in(idx);
- uint j = 0;
+ bool is_derived = ((idx - jvms->oopoff()) & 1) == 0;
// search upwards through spills and spill phis for AddP
- while(true) {
- if( !check ) break;
- int idx = check->is_Copy();
- if( idx ) {
- check = check->in(idx);
- } else if( check->is_Phi() && check->_idx >= _oldphi ) {
- check = check->in(1);
- } else
- break;
- j++;
- assert(j < 100000,"Derived pointer checking in infinite loop");
+ worklist.clear();
+ worklist.push(check);
+ uint k = 0;
+ while( k < worklist.size() ) {
+ check = worklist.at(k);
+ assert(check,"Bad base or derived pointer");
+ // See PhaseChaitin::find_base_for_derived() for all cases.
+ int isc = check->is_Copy();
+ if( isc ) {
+ worklist.push(check->in(isc));
+ } else if( check->is_Phi() ) {
+ for (uint m = 1; m < check->req(); m++)
+ worklist.push(check->in(m));
+ } else if( check->is_Con() ) {
+ if (is_derived) {
+ // Derived is NULL+offset
+ assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
+ } else {
+ assert(check->bottom_type()->is_ptr()->_offset == 0,"Bad base pointer");
+ // Base either ConP(NULL) or loadConP
+ if (check->is_Mach()) {
+ assert(check->as_Mach()->ideal_Opcode() == Op_ConP,"Bad base pointer");
+ } else {
+ assert(check->Opcode() == Op_ConP &&
+ check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
+ }
+ }
+ } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
+ 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 ||
+ check->as_Mach()->ideal_Opcode() == Op_CheckCastPP ||
+#ifdef _LP64
+ UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_CastPP ||
+ UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
+#endif
+ check->as_Mach()->ideal_Opcode() == Op_LoadP ||
+ check->as_Mach()->ideal_Opcode() == Op_LoadKlass))
+ assert(false,"Bad base or derived pointer");
+ } else {
+ assert(is_derived,"Bad base pointer");
+ assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
+ }
+ k++;
+ assert(k < 100000,"Derived pointer checking in infinite loop");
} // End while
- assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer")
}
} // End of check for derived pointers
} // End of Kcheck for debug info
} // End of if found a safepoint
} // End of forall instructions in block
} // End of forall blocks
+#endif
}
#endif
diff --git a/src/share/vm/opto/reg_split.cpp b/src/share/vm/opto/reg_split.cpp
index 003df4c48..709db17d9 100644
--- a/src/share/vm/opto/reg_split.cpp
+++ b/src/share/vm/opto/reg_split.cpp
@@ -96,7 +96,9 @@ void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) {
// its definer.
while( i < b->_nodes.size() &&
(b->_nodes[i]->is_Proj() ||
- b->_nodes[i]->is_Phi() ) )
+ b->_nodes[i]->is_Phi() ||
+ (b->_nodes[i]->is_Mach() &&
+ b->_nodes[i]->as_Mach()->ideal_Opcode() == Op_CreateEx)) )
i++;
// Do not insert between a call and his Catch