changeset 582:96964ebdb154

6782232: assert("CreateEx must be first instruction in block" ) Summary: Add the missing check for CreateEx. Add new notproduct flag VerifyRegisterAllocator. Reviewed-by: never
author kvn
date Wed, 07 Jan 2009 11:04:45 -0800
parents 1a767c61ad01
children 6c4cda924d2e
files src/share/vm/opto/c2_globals.hpp src/share/vm/opto/chaitin.cpp src/share/vm/opto/live.cpp src/share/vm/opto/reg_split.cpp
diffstat 4 files changed, 62 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/c2_globals.hpp	Tue Jan 06 16:10:11 2009 -0800
+++ b/src/share/vm/opto/c2_globals.hpp	Wed Jan 07 11:04:45 2009 -0800
@@ -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")   \
                                                                             \
--- a/src/share/vm/opto/chaitin.cpp	Tue Jan 06 16:10:11 2009 -0800
+++ b/src/share/vm/opto/chaitin.cpp	Wed Jan 07 11:04:45 2009 -0800
@@ -307,7 +307,7 @@
     if (C->failing())  return;
 
 #ifdef ASSERT
-    if( VerifyOpto ) {
+    if( VerifyOpto || VerifyRegisterAllocator ) {
       _cfg.verify();
       verify_base_ptrs(&live_arena);
     }
@@ -340,7 +340,7 @@
     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 @@
     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 @@
     }
     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 @@
       while ((neighbor = elements.next()) != 0) {
         LRG *n = &lrgs(neighbor);
 #ifdef ASSERT
-        if( VerifyOpto ) {
+        if( VerifyOpto || VerifyRegisterAllocator ) {
           assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
         }
 #endif
--- a/src/share/vm/opto/live.cpp	Tue Jan 06 16:10:11 2009 -0800
+++ b/src/share/vm/opto/live.cpp	Wed Jan 07 11:04:45 2009 -0800
@@ -271,9 +271,9 @@
 
 //------------------------------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 @@
           // 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
--- a/src/share/vm/opto/reg_split.cpp	Tue Jan 06 16:10:11 2009 -0800
+++ b/src/share/vm/opto/reg_split.cpp	Wed Jan 07 11:04:45 2009 -0800
@@ -96,7 +96,9 @@
   // 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