diff src/share/vm/opto/type.cpp @ 223:1dd146f17531

6716441: error in meet with +DoEscapeAnalysis Summary: Set instance_id to InstanceBot for InstPtr->meet(AryPtr) when types are not related. Reviewed-by: jrose, never
author kvn
date Thu, 26 Jun 2008 13:34:00 -0700
parents 1e026f8da827
children 9c2ecc2ffb12
line wrap: on
line diff
--- a/src/share/vm/opto/type.cpp	Tue Jun 24 16:00:14 2008 -0700
+++ b/src/share/vm/opto/type.cpp	Thu Jun 26 13:34:00 2008 -0700
@@ -168,20 +168,7 @@
 const Type *Type::make( enum TYPES t ) {
   return (new Type(t))->hashcons();
 }
-/*
-//------------------------------make_ptr---------------------------------------
-// Returns this ptr type or the equivalent ptr type for this compressed pointer.
-const TypePtr* Type::make_ptr() const {
-  return (_base == NarrowOop) ? is_narrowoop()->make_oopptr() : is_ptr();
-}
-
-//------------------------------make_narrowoop---------------------------------
-// Returns this compressed pointer or the equivalent compressed version
-// of this pointer type.
-const TypeNarrowOop* Type::make_narrowoop() const {
-  return (_base == NarrowOop) ? is_narrowoop() : TypeNarrowOop::make(is_ptr());
-}
-*/
+
 //------------------------------cmp--------------------------------------------
 int Type::cmp( const Type *const t1, const Type *const t2 ) {
   if( t1->_base != t2->_base )
@@ -527,23 +514,8 @@
     bool    t_interface =    t_inst->klass()->is_interface();
     interface_vs_oop = this_interface ^ t_interface;
   }
-  const Type *tdual = t->_dual;
-  const Type *thisdual = _dual;
-  // strip out instances
-  if (t2t->isa_oopptr() != NULL) {
-    t2t = t2t->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (t2this->isa_oopptr() != NULL) {
-    t2this = t2this->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (tdual->isa_oopptr() != NULL) {
-    tdual = tdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (thisdual->isa_oopptr() != NULL) {
-    thisdual = thisdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-
-  if( !interface_vs_oop && (t2t != tdual || t2this != thisdual) ) {
+
+  if( !interface_vs_oop && (t2t != t->_dual || t2this != _dual) ) {
     tty->print_cr("=== Meet Not Symmetric ===");
     tty->print("t   =                   ");         t->dump(); tty->cr();
     tty->print("this=                   ");            dump(); tty->cr();
@@ -2235,7 +2207,7 @@
   ciKlass*  k = ciKlassKlass::make();
   bool      xk = false;
   ciObject* o = NULL;
-  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, UNKNOWN_INSTANCE))->hashcons();
+  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons();
 }
 
 
@@ -2247,7 +2219,7 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeOopPtr::cast_to_instance(int instance_id) const {
+const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
   // There are no instances of a general oop.
   // Return self unchanged.
   return this;
@@ -2341,7 +2313,7 @@
 const Type *TypeOopPtr::xdual() const {
   assert(klass() == ciKlassKlass::make(), "no klasses here");
   assert(const_oop() == NULL,             "no constants here");
-  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance()  );
+  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id()  );
 }
 
 //--------------------------make_from_klass_common-----------------------------
@@ -2555,7 +2527,9 @@
   case         0: break;
   default:        st->print("+%d",_offset); break;
   }
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif
@@ -2587,16 +2561,24 @@
   return make( _ptr, xadd_offset(offset) );
 }
 
-int TypeOopPtr::meet_instance(int iid) const {
-  if (iid == 0) {
-    return (_instance_id < 0)  ? _instance_id : UNKNOWN_INSTANCE;
-  } else if (_instance_id == UNKNOWN_INSTANCE) {
-    return (iid < 0)  ? iid : UNKNOWN_INSTANCE;
-  } else {
-    return (_instance_id == iid) ? iid : UNKNOWN_INSTANCE;
-  }
+//------------------------------meet_instance_id--------------------------------
+int TypeOopPtr::meet_instance_id( int instance_id ) const {
+  // Either is 'TOP' instance?  Return the other instance!
+  if( _instance_id == InstanceTop ) return  instance_id;
+  if(  instance_id == InstanceTop ) return _instance_id;
+  // If either is different, return 'BOTTOM' instance
+  if( _instance_id != instance_id ) return InstanceBot;
+  return _instance_id;
 }
 
+//------------------------------dual_instance_id--------------------------------
+int TypeOopPtr::dual_instance_id( ) const {
+  if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM
+  if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP
+  return _instance_id;              // Map everything else into self
+}
+
+
 //=============================================================================
 // Convenience common pre-built types.
 const TypeInstPtr *TypeInstPtr::NOTNULL;
@@ -2628,7 +2610,7 @@
   // Ptr is never Null
   assert( ptr != Null, "NULL pointers are not typed" );
 
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = false;
   if (ptr == Constant) {
@@ -2653,7 +2635,7 @@
   if( ptr == _ptr ) return this;
   // Reconstruct _sig info here since not a problem with later lazy
   // construction, _sig will show up on demand.
-  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset);
+  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id);
 }
 
 
@@ -2669,13 +2651,13 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const {
-  if( instance_id == _instance_id) return this;
-  bool exact = true;
-  PTR  ptr_t = NotNull;
-  if (instance_id == UNKNOWN_INSTANCE) {
-    exact = _klass_is_exact;
-    ptr_t = _ptr;
+const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
+  if( instance_id == _instance_id ) return this;
+  bool exact = _klass_is_exact;
+  PTR  ptr_t = _ptr;
+  if ( instance_id > 0 ) { // instances are always exactly typed
+    if (UseExactTypes) exact = true;
+    ptr_t = NotNull;
   }
   return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
 }
@@ -2758,16 +2740,17 @@
     const TypeAryPtr *tp = t->is_aryptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
-    int iid = meet_instance(tp->instance_id());
+    int instance_id = meet_instance_id(tp->instance_id());
     switch (ptr) {
     case TopPTR:
     case AnyNull:                // Fall 'down' to dual of object klass
       if (klass()->equals(ciEnv::current()->Object_klass())) {
-        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
       } else {
         // cannot subclass, so the meet has to fall badly below the centerline
         ptr = NotNull;
-        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid);
+        instance_id = InstanceBot;
+        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id);
       }
     case Constant:
     case NotNull:
@@ -2778,14 +2761,15 @@
         // then we can subclass in the Java class heirarchy.
         if (klass()->equals(ciEnv::current()->Object_klass())) {
           // that is, tp's array type is a subtype of my klass
-          return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+          return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
         }
       }
       // The other case cannot happen, since I cannot be a subtype of an array.
       // The meet falls down to Object class below centerline.
       if( ptr == Constant )
          ptr = NotNull;
-      return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid );
+      instance_id = InstanceBot;
+      return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id );
     default: typerr(t);
     }
   }
@@ -2797,9 +2781,11 @@
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
     case TopPTR:
-    case AnyNull:
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
       return make(ptr, klass(), klass_is_exact(),
-                  (ptr == Constant ? const_oop() : NULL), offset);
+                  (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+    }
     case NotNull:
     case BotPTR:
       return TypeOopPtr::make(ptr, offset);
@@ -2815,10 +2801,13 @@
     switch (tp->ptr()) {
     case Null:
       if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset );
+      // else fall through to AnyNull
     case TopPTR:
-    case AnyNull:
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
       return make( ptr, klass(), klass_is_exact(),
-                   (ptr == Constant ? const_oop() : NULL), offset );
+                   (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+    }
     case NotNull:
     case BotPTR:
       return TypePtr::make( AnyPtr, ptr, offset );
@@ -2847,7 +2836,7 @@
     const TypeInstPtr *tinst = t->is_instptr();
     int off = meet_offset( tinst->offset() );
     PTR ptr = meet_ptr( tinst->ptr() );
-    int instance_id = meet_instance(tinst->instance_id());
+    int instance_id = meet_instance_id(tinst->instance_id());
 
     // Check for easy case; klasses are equal (and perhaps not loaded!)
     // If we have constants, then we created oops so classes are loaded
@@ -2916,7 +2905,7 @@
         // Find out which constant.
         o = (this_klass == klass()) ? const_oop() : tinst->const_oop();
       }
-      return make( ptr, k, xk, o, off );
+      return make( ptr, k, xk, o, off, instance_id );
     }
 
     // Either oop vs oop or interface vs interface or interface vs Object
@@ -3003,7 +2992,7 @@
 
     // Now we find the LCA of Java classes
     ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
-    return make( ptr, k, false, NULL, off );
+    return make( ptr, k, false, NULL, off, instance_id );
   } // End of case InstPtr
 
   case KlassPtr:
@@ -3030,7 +3019,7 @@
 // Dual: do NOT dual on klasses.  This means I do NOT understand the Java
 // inheritence mechanism.
 const Type *TypeInstPtr::xdual() const {
-  return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance()  );
+  return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id()  );
 }
 
 //------------------------------eq---------------------------------------------
@@ -3082,7 +3071,9 @@
   }
 
   st->print(" *");
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif
@@ -3110,7 +3101,7 @@
   assert(!(k == NULL && ary->_elem->isa_int()),
          "integral arrays must be pre-equipped with a class");
   if (!xk)  xk = ary->ary_must_be_exact();
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = (ptr == Constant);
   return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
@@ -3122,7 +3113,7 @@
          "integral arrays must be pre-equipped with a class");
   assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
   if (!xk)  xk = (o != NULL) || ary->ary_must_be_exact();
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = (ptr == Constant);
   return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
@@ -3131,7 +3122,7 @@
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
   if( ptr == _ptr ) return this;
-  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset);
+  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id);
 }
 
 
@@ -3144,13 +3135,13 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const {
-  if( instance_id == _instance_id) return this;
-  bool exact = true;
-  PTR  ptr_t = NotNull;
-  if (instance_id == UNKNOWN_INSTANCE) {
-    exact = _klass_is_exact;
-    ptr_t = _ptr;
+const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
+  if( instance_id == _instance_id ) return this;
+  bool exact = _klass_is_exact;
+  PTR  ptr_t = _ptr;
+  if ( instance_id > 0 ) { // instances are always exactly typed
+    if (UseExactTypes) exact = true;
+    ptr_t = NotNull;
   }
   return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
 }
@@ -3203,7 +3194,7 @@
     new_size = TypeInt::ZERO; // intermediate dead fast-path goo
   if (new_size == size())  return this;
   const TypeAry* new_ary = TypeAry::make(elem(), new_size);
-  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset);
+  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
 }
 
 
@@ -3255,8 +3246,11 @@
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
     case TopPTR:
-    case AnyNull:
-      return make(ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset);
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
+      return make(ptr, (ptr == Constant ? const_oop() : NULL),
+                  _ary, _klass, _klass_is_exact, offset, instance_id);
+    }
     case BotPTR:
     case NotNull:
       return TypeOopPtr::make(ptr, offset);
@@ -3277,8 +3271,12 @@
       return TypePtr::make(AnyPtr, ptr, offset);
     case Null:
       if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset);
-    case AnyNull:
-      return make( ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset );
+      // else fall through to AnyNull
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
+      return make( ptr, (ptr == Constant ? const_oop() : NULL),
+                  _ary, _klass, _klass_is_exact, offset, instance_id);
+    }
     default: ShouldNotReachHere();
     }
   }
@@ -3290,7 +3288,7 @@
     int off = meet_offset(tap->offset());
     const TypeAry *tary = _ary->meet(tap->_ary)->is_ary();
     PTR ptr = meet_ptr(tap->ptr());
-    int iid = meet_instance(tap->instance_id());
+    int instance_id = meet_instance_id(tap->instance_id());
     ciKlass* lazy_klass = NULL;
     if (tary->_elem->isa_int()) {
       // Integral array element types have irrelevant lattice relations.
@@ -3311,7 +3309,7 @@
     case TopPTR:
       // Compute new klass on demand, do not use tap->_klass
       xk = (tap->_klass_is_exact | this->_klass_is_exact);
-      return make( ptr, const_oop(), tary, lazy_klass, xk, off, iid );
+      return make( ptr, const_oop(), tary, lazy_klass, xk, off, instance_id );
     case Constant: {
       ciObject* o = const_oop();
       if( _ptr == Constant ) {
@@ -3323,7 +3321,7 @@
         o = tap->const_oop();
       }
       xk = true;
-      return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, iid );
+      return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, instance_id );
     }
     case NotNull:
     case BotPTR:
@@ -3334,7 +3332,7 @@
             xk = this->_klass_is_exact;
       else  xk = (tap->_klass_is_exact & this->_klass_is_exact) &&
               (klass() == tap->klass()); // Only precise for identical arrays
-      return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, iid );
+      return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, instance_id );
     default: ShouldNotReachHere();
     }
   }
@@ -3344,16 +3342,17 @@
     const TypeInstPtr *tp = t->is_instptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
-    int iid = meet_instance(tp->instance_id());
+    int instance_id = meet_instance_id(tp->instance_id());
     switch (ptr) {
     case TopPTR:
     case AnyNull:                // Fall 'down' to dual of object klass
       if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
-        return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+        return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
       } else {
         // cannot subclass, so the meet has to fall badly below the centerline
         ptr = NotNull;
-        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+        instance_id = InstanceBot;
+        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
       }
     case Constant:
     case NotNull:
@@ -3364,14 +3363,15 @@
         // then we can subclass in the Java class heirarchy.
         if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
           // that is, my array type is a subtype of 'tp' klass
-          return make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+          return make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
         }
       }
       // The other case cannot happen, since t cannot be a subtype of an array.
       // The meet falls down to Object class below centerline.
       if( ptr == Constant )
          ptr = NotNull;
-      return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+      instance_id = InstanceBot;
+      return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
     default: typerr(t);
     }
   }
@@ -3386,7 +3386,7 @@
 //------------------------------xdual------------------------------------------
 // Dual: compute field-by-field dual
 const Type *TypeAryPtr::xdual() const {
-  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance() );
+  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
 }
 
 //------------------------------dump2------------------------------------------
@@ -3423,7 +3423,9 @@
     }
   }
   st->print(" *");
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif