src/share/vm/opto/type.cpp

Print this page

        

@@ -55,10 +55,11 @@
   { Bottom,          T_VOID,       "top",           false, 0,                    relocInfo::none          },  // Top
   { Bad,             T_INT,        "int:",          false, Op_RegI,              relocInfo::none          },  // Int
   { Bad,             T_LONG,       "long:",         false, Op_RegL,              relocInfo::none          },  // Long
   { Half,            T_VOID,       "half",          false, 0,                    relocInfo::none          },  // Half
   { Bad,             T_NARROWOOP,  "narrowoop:",    false, Op_RegN,              relocInfo::none          },  // NarrowOop
+  { Bad,             T_NARROWKLASS,"narrowklass:",  false, Op_RegN,              relocInfo::none          },  // NarrowKlass
   { Bad,             T_ILLEGAL,    "tuple:",        false, Node::NotAMachineReg, relocInfo::none          },  // Tuple
   { Bad,             T_ARRAY,      "array:",        false, Node::NotAMachineReg, relocInfo::none          },  // Array
 
 #if defined(IA32) || defined(AMD64)
   { Bad,             T_ILLEGAL,    "vectors:",      false, Op_VecS,              relocInfo::none          },  // VectorS

@@ -330,10 +331,12 @@
   TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot);
 
   TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR );
   TypeNarrowOop::BOTTOM   = TypeNarrowOop::make( TypeInstPtr::BOTTOM );
 
+  TypeNarrowKlass::NULL_PTR = TypeNarrowKlass::make( TypePtr::NULL_PTR );
+
   mreg2type[Op_Node] = Type::BOTTOM;
   mreg2type[Op_Set ] = 0;
   mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM;
   mreg2type[Op_RegI] = TypeInt::INT;
   mreg2type[Op_RegP] = TypePtr::BOTTOM;

@@ -394,10 +397,11 @@
   longpair[0] = TypeLong::LONG;
   longpair[1] = TypeLong::LONG;
   TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair);
 
   _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM;
+  _const_basic_type[T_NARROWKLASS] = Type::BOTTOM;
   _const_basic_type[T_BOOLEAN] = TypeInt::BOOL;
   _const_basic_type[T_CHAR]    = TypeInt::CHAR;
   _const_basic_type[T_BYTE]    = TypeInt::BYTE;
   _const_basic_type[T_SHORT]   = TypeInt::SHORT;
   _const_basic_type[T_INT]     = TypeInt::INT;

@@ -406,13 +410,14 @@
   _const_basic_type[T_DOUBLE]  = Type::DOUBLE;
   _const_basic_type[T_OBJECT]  = TypeInstPtr::BOTTOM;
   _const_basic_type[T_ARRAY]   = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays
   _const_basic_type[T_VOID]    = TypePtr::NULL_PTR;   // reflection represents void this way
   _const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM;  // both interpreter return addresses & random raw ptrs
-  _const_basic_type[T_CONFLICT]= Type::BOTTOM;        // why not?
+  _const_basic_type[T_CONFLICT]    = Type::BOTTOM;        // why not?
 
   _zero_type[T_NARROWOOP] = TypeNarrowOop::NULL_PTR;
+  _zero_type[T_NARROWKLASS] = TypeNarrowKlass::NULL_PTR;
   _zero_type[T_BOOLEAN] = TypeInt::ZERO;     // false == 0
   _zero_type[T_CHAR]    = TypeInt::ZERO;     // '\0' == 0
   _zero_type[T_BYTE]    = TypeInt::ZERO;     // 0x00 == 0
   _zero_type[T_SHORT]   = TypeInt::ZERO;     // 0x0000 == 0
   _zero_type[T_INT]     = TypeInt::ZERO;

@@ -561,13 +566,18 @@
 const Type *Type::meet( const Type *t ) const {
   if (isa_narrowoop() && t->isa_narrowoop()) {
     const Type* result = make_ptr()->meet(t->make_ptr());
     return result->make_narrowoop();
   }
+  if (isa_narrowklass() && t->isa_narrowklass()) {
+    const Type* result = make_ptr()->meet(t->make_ptr());
+    return result->make_narrowklass();
+  }
 
   const Type *mt = xmeet(t);
   if (isa_narrowoop() || t->isa_narrowoop()) return mt;
+  if (isa_narrowklass() || t->isa_narrowklass()) return mt;
 #ifdef ASSERT
   assert( mt == t->xmeet(this), "meet not commutative" );
   const Type* dual_join = mt->_dual;
   const Type *t2t    = dual_join->xmeet(t->_dual);
   const Type *t2this = dual_join->xmeet(   _dual);

@@ -633,10 +643,13 @@
     return t->xmeet(this);
 
   case NarrowOop:
     return t->xmeet(this);
 
+  case NarrowKlass:
+    return t->xmeet(this);
+
   case Bad:                     // Type check
   default:                      // Bogus type not in lattice
     typerr(t);
     return Type::BOTTOM;
 

@@ -691,10 +704,11 @@
   Bottom,       // Top
   Bad,          // Int - handled in v-call
   Bad,          // Long - handled in v-call
   Half,         // Half
   Bad,          // NarrowOop - handled in v-call
+  Bad,          // NarrowKlass - handled in v-call
 
   Bad,          // Tuple - handled in v-call
   Bad,          // Array - handled in v-call
   Bad,          // VectorS - handled in v-call
   Bad,          // VectorD - handled in v-call

@@ -754,10 +768,12 @@
   ResourceMark rm;
   Dict d(cmpkey,hashkey);       // Stop recursive type dumping
   dump2(d,1, st);
   if (is_ptr_to_narrowoop()) {
     st->print(" [narrow]");
+  } else if (is_ptr_to_narrowklass()) {
+    st->print(" [narrowklass]");
   }
 }
 #endif
 
 //------------------------------singleton--------------------------------------

@@ -836,10 +852,11 @@
   case InstPtr:
   case AryPtr:
   case MetadataPtr:
   case KlassPtr:
   case NarrowOop:
+  case NarrowKlass:
   case Int:
   case Long:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:

@@ -953,10 +970,11 @@
   case InstPtr:
   case AryPtr:
   case MetadataPtr:
   case KlassPtr:
   case NarrowOop:
+  case NarrowKlass:
   case Int:
   case Long:
   case FloatTop:
   case FloatCon:
   case FloatBot:

@@ -1107,10 +1125,11 @@
   case InstPtr:
   case AryPtr:
   case MetadataPtr:
   case KlassPtr:
   case NarrowOop:
+  case NarrowKlass:
   case Long:
   case FloatTop:
   case FloatCon:
   case FloatBot:
   case DoubleTop:

@@ -1364,10 +1383,11 @@
   case InstPtr:
   case AryPtr:
   case MetadataPtr:
   case KlassPtr:
   case NarrowOop:
+  case NarrowKlass:
   case Int:
   case FloatTop:
   case FloatCon:
   case FloatBot:
   case DoubleTop:

@@ -2094,10 +2114,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 

@@ -2348,30 +2369,31 @@
 TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id )
   : TypePtr(t, ptr, offset),
     _const_oop(o), _klass(k),
     _klass_is_exact(xk),
     _is_ptr_to_narrowoop(false),
+    _is_ptr_to_narrowklass(false),
     _instance_id(instance_id) {
 #ifdef _LP64
-  if (UseCompressedOops && _offset != 0) {
+  if (_offset != 0) {
     if (_offset == oopDesc::klass_offset_in_bytes()) {
-      _is_ptr_to_narrowoop = UseCompressedKlassPointers;
+      _is_ptr_to_narrowklass = UseCompressedKlassPointers;
     } else if (klass() == NULL) {
       // Array with unknown body type
       assert(this->isa_aryptr(), "only arrays without klass");
-      _is_ptr_to_narrowoop = true;
+      _is_ptr_to_narrowoop = UseCompressedOops;
     } else if (this->isa_aryptr()) {
-      _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
+      _is_ptr_to_narrowoop = (UseCompressedOops && klass()->is_obj_array_klass() &&
                              _offset != arrayOopDesc::length_offset_in_bytes());
     } else if (klass()->is_instance_klass()) {
       ciInstanceKlass* ik = klass()->as_instance_klass();
       ciField* field = NULL;
       if (this->isa_klassptr()) {
         // Perm objects don't use compressed references
       } else if (_offset == OffsetBot || _offset == OffsetTop) {
         // unsafe access
-        _is_ptr_to_narrowoop = true;
+        _is_ptr_to_narrowoop = UseCompressedOops;
       } else { // exclude unsafe ops
         assert(this->isa_instptr(), "must be an instance ptr.");
 
         if (klass() == ciEnv::current()->Class_klass() &&
             (_offset == java_lang_Class::klass_offset_in_bytes() ||

@@ -2385,26 +2407,26 @@
           assert(o != NULL, "must be constant");
           ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass();
           ciField* field = k->get_field_by_offset(_offset, true);
           assert(field != NULL, "missing field");
           BasicType basic_elem_type = field->layout_type();
-          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+          _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
                                   basic_elem_type == T_ARRAY);
         } else {
           // Instance fields which contains a compressed oop references.
           field = ik->get_field_by_offset(_offset, false);
           if (field != NULL) {
             BasicType basic_elem_type = field->layout_type();
-            _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+            _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT ||
                                     basic_elem_type == T_ARRAY);
           } else if (klass()->equals(ciEnv::current()->Object_klass())) {
             // Compile::find_alias_type() cast exactness on all types to verify
             // that it does not affect alias type.
-            _is_ptr_to_narrowoop = true;
+            _is_ptr_to_narrowoop = UseCompressedOops;
           } else {
             // Type for the copy start in LibraryCallKit::inline_native_clone().
-            _is_ptr_to_narrowoop = true;
+            _is_ptr_to_narrowoop = UseCompressedOops;
           }
         }
       }
     }
   }

@@ -2473,10 +2495,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 

@@ -2923,10 +2946,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 

@@ -3351,10 +3375,11 @@
   if (res == 0) {
     switch (etype) {
     case T_NARROWOOP:
       etype = T_OBJECT;
       break;
+    case T_NARROWKLASS:
     case T_CONFLICT:
     case T_ILLEGAL:
     case T_VOID:
       etype = T_BYTE;           // will produce conservatively high value
     }

@@ -3423,10 +3448,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 

@@ -3669,52 +3695,80 @@
   return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id );
 }
 
 
 //=============================================================================
-const TypeNarrowOop *TypeNarrowOop::BOTTOM;
-const TypeNarrowOop *TypeNarrowOop::NULL_PTR;
-
-
-const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) {
-  return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
-}
 
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
-int TypeNarrowOop::hash(void) const {
+int TypeNarrowPtr::hash(void) const {
   return _ptrtype->hash() + 7;
 }
 
+bool TypeNarrowPtr::singleton(void) const {    // TRUE if type is a singleton
+  return _ptrtype->singleton();
+}
+
+bool TypeNarrowPtr::empty(void) const {
+  return _ptrtype->empty();
+}
+
+intptr_t TypeNarrowPtr::get_con() const {
+  return _ptrtype->get_con();
+}
 
-bool TypeNarrowOop::eq( const Type *t ) const {
-  const TypeNarrowOop* tc = t->isa_narrowoop();
+bool TypeNarrowPtr::eq( const Type *t ) const {
+  const TypeNarrowPtr* tc = isa_same_narrowptr(t);
   if (tc != NULL) {
     if (_ptrtype->base() != tc->_ptrtype->base()) {
       return false;
     }
     return tc->_ptrtype->eq(_ptrtype);
   }
   return false;
 }
 
-bool TypeNarrowOop::singleton(void) const {    // TRUE if type is a singleton
-  return _ptrtype->singleton();
+const Type *TypeNarrowPtr::xdual() const {    // Compute dual right now.
+  const TypePtr* odual = _ptrtype->dual()->is_ptr();
+  return make_same_narrowptr(odual);
 }
 
-bool TypeNarrowOop::empty(void) const {
-  return _ptrtype->empty();
+
+const Type *TypeNarrowPtr::filter( const Type *kills ) const {
+  if (isa_same_narrowptr(kills)) {
+    const Type* ft =_ptrtype->filter(is_same_narrowptr(kills)->_ptrtype);
+    if (ft->empty())
+      return Type::TOP;           // Canonical empty value
+    if (ft->isa_ptr()) {
+      return make_hash_same_narrowptr(ft->isa_ptr());
+    }
+    return ft;
+  } else if (kills->isa_ptr()) {
+    const Type* ft = _ptrtype->join(kills);
+    if (ft->empty())
+      return Type::TOP;           // Canonical empty value
+    return ft;
+  } else {
+    return Type::TOP;
+  }
 }
 
 //------------------------------xmeet------------------------------------------
 // Compute the MEET of two types.  It returns a new Type object.
-const Type *TypeNarrowOop::xmeet( const Type *t ) const {
+const Type *TypeNarrowPtr::xmeet( const Type *t ) const {
   // Perform a fast test for common case; meeting the same types together.
   if( this == t ) return this;  // Meeting same type-rep?
 
+  if (t->base() == base()) {
+    const Type* result = _ptrtype->xmeet(t->make_ptr());
+    if (result->isa_ptr()) {
+      return make_hash_same_narrowptr(result->is_ptr());
+    }
+    return result;
+  }
 
-  // Current "this->_base" is OopPtr
+  // Current "this->_base" is NarrowKlass or NarrowOop
   switch (t->base()) {          // switch on original type
 
   case Int:                     // Mixing ints & oops happens when javac
   case Long:                    // reuses local variables
   case FloatTop:

@@ -3728,68 +3782,60 @@
   case OopPtr:
   case InstPtr:
   case AryPtr:
   case MetadataPtr:
   case KlassPtr:
+  case NarrowOop:
+  case NarrowKlass:
 
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 
-  case NarrowOop: {
-    const Type* result = _ptrtype->xmeet(t->make_ptr());
-    if (result->isa_ptr()) {
-      return TypeNarrowOop::make(result->is_ptr());
-    }
-    return result;
-  }
-
   default:                      // All else is a mistake
     typerr(t);
 
   } // End of switch
 
   return this;
 }
 
-const Type *TypeNarrowOop::xdual() const {    // Compute dual right now.
-  const TypePtr* odual = _ptrtype->dual()->is_ptr();
-  return new TypeNarrowOop(odual);
+#ifndef PRODUCT
+void TypeNarrowPtr::dump2( Dict & d, uint depth, outputStream *st ) const {
+  _ptrtype->dump2(d, depth, st);
 }
+#endif
 
-const Type *TypeNarrowOop::filter( const Type *kills ) const {
-  if (kills->isa_narrowoop()) {
-    const Type* ft =_ptrtype->filter(kills->is_narrowoop()->_ptrtype);
-    if (ft->empty())
-      return Type::TOP;           // Canonical empty value
-    if (ft->isa_ptr()) {
-      return make(ft->isa_ptr());
-    }
-    return ft;
-  } else if (kills->isa_ptr()) {
-    const Type* ft = _ptrtype->join(kills);
-    if (ft->empty())
-      return Type::TOP;           // Canonical empty value
-    return ft;
-  } else {
-    return Type::TOP;
-  }
-}
+const TypeNarrowOop *TypeNarrowOop::BOTTOM;
+const TypeNarrowOop *TypeNarrowOop::NULL_PTR;
 
 
-intptr_t TypeNarrowOop::get_con() const {
-  return _ptrtype->get_con();
+const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) {
+  return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons();
 }
 
+
 #ifndef PRODUCT
 void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const {
   st->print("narrowoop: ");
-  _ptrtype->dump2(d, depth, st);
+  TypeNarrowPtr::dump2(d, depth, st);
 }
 #endif
 
+const TypeNarrowKlass *TypeNarrowKlass::NULL_PTR;
+
+const TypeNarrowKlass* TypeNarrowKlass::make(const TypePtr* type) {
+  return (const TypeNarrowKlass*)(new TypeNarrowKlass(type))->hashcons();
+}
+
+#ifndef PRODUCT
+void TypeNarrowKlass::dump2( Dict & d, uint depth, outputStream *st ) const {
+  st->print("narrowklass: ");
+  TypeNarrowPtr::dump2(d, depth, st);
+}
+#endif
 
 
 //------------------------------eq---------------------------------------------
 // Structural equality check for Type representations
 bool TypeMetadataPtr::eq( const Type *t ) const {

@@ -3876,10 +3922,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;
 

@@ -4167,10 +4214,11 @@
   case FloatBot:
   case DoubleTop:
   case DoubleCon:
   case DoubleBot:
   case NarrowOop:
+  case NarrowKlass:
   case Bottom:                  // Ye Olde Default
     return Type::BOTTOM;
   case Top:
     return this;