< prev index next >

src/hotspot/share/opto/type.cpp

Print this page

        

@@ -1932,13 +1932,10 @@
 static void collect_value_fields(ciValueKlass* vk, const Type** field_array, uint& pos) {
   for (int j = 0; j < vk->nof_nonstatic_fields(); j++) {
     ciField* field = vk->nonstatic_field_at(j);
     BasicType bt = field->type()->basic_type();
     const Type* ft = Type::get_const_type(field->type());
-    if (bt == T_VALUETYPE) {
-      ft = ft->isa_valuetypeptr()->cast_to_ptr_type(TypePtr::BotPTR);
-    }
     field_array[pos++] = ft;
     if (bt == T_LONG || bt == T_DOUBLE) {
       field_array[pos++] = Type::HALF;
     }
   }

@@ -1989,11 +1986,12 @@
       uint pos = TypeFunc::Parms;
       field_array[pos] = TypePtr::BOTTOM;
       pos++;
       collect_value_fields(vk, field_array, pos);
     } else {
-      field_array[TypeFunc::Parms] = get_const_type(return_type);
+      // Value type returns cannot be NULL
+      field_array[TypeFunc::Parms] = get_const_type(return_type)->join_speculative(TypePtr::NOTNULL);
     }
     break;
   case T_VOID:
     break;
   default:

@@ -2069,11 +2067,12 @@
       assert(type->is_valuetype(), "inconsistent type");
       if (vt_fields_as_args && !type->is__Value()) {
         ciValueKlass* vk = (ciValueKlass*)type;
         collect_value_fields(vk, field_array, pos);
       } else {
-        field_array[pos++] = get_const_type(type);
+        // Value types arguments cannot be NULL
+        field_array[pos++] = get_const_type(type)->join_speculative(TypePtr::NOTNULL);
       }
       break;
     }
     default:
       ShouldNotReachHere();

@@ -2214,10 +2213,14 @@
     return size;
 }
 
 //------------------------------make-------------------------------------------
 const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) {
+  if (elem->isa_valuetypeptr()) {
+    // Value type array elements cannot be NULL
+    elem = elem->join_speculative(TypePtr::NOTNULL)->is_oopptr();
+  }
   if (UseCompressedOops && elem->isa_oopptr()) {
     elem = elem->make_narrowoop();
   }
   size = normalize_array_size(size);
   return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons();

@@ -3365,11 +3368,11 @@
 
 //--------------------------make_from_klass_common-----------------------------
 // Computes the element-type given a klass.
 const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_change, bool try_for_exact) {
   if (klass->is_valuetype()) {
-    return TypeValueTypePtr::make(TypePtr::NotNull, klass->as_value_klass());
+    return TypeValueTypePtr::make(TypePtr::BotPTR, klass->as_value_klass());
   } else if (klass->is_instance_klass()) {
     Compile* C = Compile::current();
     Dependencies* deps = C->dependencies();
     assert((deps != NULL) == (C->method() != NULL && C->method()->code_size() > 0), "sanity");
     // Element is an instance

@@ -3415,22 +3418,12 @@
     // is not-null. That was not true in general.
     const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::BotPTR, arr0, klass, true, Offset(0));
     return arr;
   } else if (klass->is_value_array_klass()) {
     ciValueKlass* vk = klass->as_array_klass()->element_klass()->as_value_klass();
-    const Type* etype = NULL;
-    bool xk = false;
-    if (vk->flatten_array()) {
-      etype = TypeValueType::make(vk);
-      xk = true;
-    } else {
-      const TypeOopPtr* etype_oop = TypeOopPtr::make_from_klass_common(vk, false, try_for_exact);
-      xk = etype_oop->klass_is_exact();
-      etype = etype_oop;
-    }
-    const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS);
-    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::BotPTR, arr0, klass, xk, Offset(0));
+    const TypeAry* arr0 = TypeAry::make(TypeValueType::make(vk), TypeInt::POS);
+    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::BotPTR, arr0, klass, true, Offset(0));
     return arr;
   } else {
     ShouldNotReachHere();
     return NULL;
   }

@@ -4782,28 +4775,28 @@
 
 //=============================================================================
 
 const TypeValueTypePtr* TypeValueTypePtr::NOTNULL;
 //------------------------------make-------------------------------------------
-const TypeValueTypePtr* TypeValueTypePtr::make(const TypeValueType* vt, PTR ptr, ciObject* o, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth, bool narrow) {
-  return (TypeValueTypePtr*)(new TypeValueTypePtr(vt, ptr, o, offset, instance_id, speculative, inline_depth))->hashcons();
+const TypeValueTypePtr* TypeValueTypePtr::make(PTR ptr, ciValueKlass* vk, ciObject* o, Offset offset, int instance_id, const TypePtr* speculative, int inline_depth, bool narrow) {
+  return (TypeValueTypePtr*)(new TypeValueTypePtr(ptr, vk, o, offset, instance_id, speculative, inline_depth))->hashcons();
 }
 
 const TypePtr* TypeValueTypePtr::add_offset(intptr_t offset) const {
-  return make(_vt, _ptr, _const_oop, Offset(offset), _instance_id, _speculative, _inline_depth);
+  return make(_ptr, value_klass(), _const_oop, Offset(offset), _instance_id, _speculative, _inline_depth);
 }
 
 //------------------------------cast_to_ptr_type-------------------------------
 const Type* TypeValueTypePtr::cast_to_ptr_type(PTR ptr) const {
   if (ptr == _ptr) return this;
-  return make(_vt, ptr, _const_oop, _offset, _instance_id, _speculative, _inline_depth);
+  return make(ptr, value_klass(), _const_oop, _offset, _instance_id, _speculative, _inline_depth);
 }
 
 //-----------------------------cast_to_instance_id----------------------------
 const TypeOopPtr* TypeValueTypePtr::cast_to_instance_id(int instance_id) const {
   if (instance_id == _instance_id) return this;
-  return make(_vt, _ptr, _const_oop, _offset, instance_id, _speculative, _inline_depth);
+  return make(_ptr, value_klass(), _const_oop, _offset, instance_id, _speculative, _inline_depth);
 }
 
 //------------------------------meet-------------------------------------------
 // Compute the MEET of two types.  It returns a new Type object.
 const Type* TypeValueTypePtr::xmeet_helper(const Type* t) const {

@@ -4846,11 +4839,11 @@
       const TypePtr* speculative = xmeet_speculative(tp);
       int depth = meet_inline_depth(tp->inline_depth());
       switch (tp->ptr()) {
       case TopPTR:
       case AnyNull: {
-        return make(_vt, ptr, NULL, offset, instance_id, speculative, depth);
+        return make(ptr, value_klass(), NULL, offset, instance_id, speculative, depth);
       }
       case NotNull:
       case BotPTR: {
         return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth);
       }

@@ -4870,11 +4863,11 @@
       case Null:
         if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
         // else fall through to AnyNull
       case TopPTR:
       case AnyNull: {
-        return make(_vt, ptr, NULL, offset, instance_id, speculative, depth);
+        return make(ptr, value_klass(), NULL, offset, instance_id, speculative, depth);
       }
       case NotNull:
       case BotPTR:
         return TypePtr::make(AnyPtr, ptr, offset, speculative, depth);
       default: typerr(t);

@@ -4891,24 +4884,24 @@
       int depth = meet_inline_depth(tp->inline_depth());
       // Compute constant oop
       ciObject* o = NULL;
       ciObject* this_oop  = const_oop();
       ciObject* tp_oop = tp->const_oop();
-      const TypeValueType* vt = NULL;
-      if (_vt != tp->_vt) {
+      ciKlass* klass = NULL;
+      if (_klass != tp->_klass) {
         assert(is__Value() || tp->is__Value(), "impossible meet");
         if (above_centerline(ptr)) {
-          vt = is__Value() ? tp->_vt : _vt;
+          klass = is__Value() ? tp->_klass : _klass;
         } else if (above_centerline(this->_ptr) && !above_centerline(tp->_ptr)) {
-          vt = tp->_vt;
+          klass = tp->_klass;
         } else if (above_centerline(tp->_ptr) && !above_centerline(this->_ptr)) {
-          vt = _vt;
+          klass = _klass;
         } else {
-          vt = is__Value() ? _vt : tp->_vt;
+          klass = is__Value() ? _klass : tp->_klass;
         }
       } else {
-        vt = _vt;
+        klass = _klass;
       }
       if (ptr == Constant) {
         if (this_oop != NULL && tp_oop != NULL &&
             this_oop->equals(tp_oop) ) {
           o = this_oop;

@@ -4918,31 +4911,31 @@
           o = this_oop;
         } else {
           ptr = NotNull;
         }
       }
-      return make(vt, ptr, o, offset, instance_id, speculative, depth);
+      return make(ptr, klass->as_value_klass(), o, offset, instance_id, speculative, depth);
     }
     }
 }
 
 // Dual: compute field-by-field dual
 const Type* TypeValueTypePtr::xdual() const {
-  return new TypeValueTypePtr(_vt, dual_ptr(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
+  return new TypeValueTypePtr(dual_ptr(), value_klass(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth());
 }
 
 //------------------------------eq---------------------------------------------
 // Structural equality check for Type representations
 bool TypeValueTypePtr::eq(const Type* t) const {
   const TypeValueTypePtr* p = t->is_valuetypeptr();
-  return _vt->eq(p->value_type()) && TypeOopPtr::eq(p);
+  return klass()->equals(p->klass()) && TypeOopPtr::eq(p);
 }
 
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypeValueTypePtr::hash(void) const {
-  return java_add(_vt->hash(), TypeOopPtr::hash());
+  return java_add(klass()->hash(), TypeOopPtr::hash());
 }
 
 //------------------------------is__Value--------------------------------------
 bool TypeValueTypePtr::is__Value() const {
   return klass()->equals(TypeKlassPtr::VALUE->klass());
< prev index next >