< prev index next >

src/share/vm/opto/type.cpp

Print this page

        

@@ -198,12 +198,11 @@
   }
 }
 
 
 //-----------------------make_from_constant------------------------------------
-const Type* Type::make_from_constant(ciConstant constant,
-                                     bool require_constant, bool is_autobox_cache) {
+const Type* Type::make_from_constant(ciConstant constant, bool require_constant) {
   switch (constant.basic_type()) {
   case T_BOOLEAN:  return TypeInt::make(constant.as_boolean());
   case T_CHAR:     return TypeInt::make(constant.as_char());
   case T_BYTE:     return TypeInt::make(constant.as_byte());
   case T_SHORT:    return TypeInt::make(constant.as_short());

@@ -220,19 +219,62 @@
       // An oop is not scavengable if it is in the perm gen.
       ciObject* oop_constant = constant.as_object();
       if (oop_constant->is_null_object()) {
         return Type::get_zero_type(T_OBJECT);
       } else if (require_constant || oop_constant->should_be_constant()) {
-        return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache);
+        return TypeOopPtr::make_from_constant(oop_constant, require_constant);
       }
     }
+  case T_ILLEGAL:
+    // Invalid ciConstant returned due to OutOfMemoryError in the CI
+    assert(Compile::current()->env()->failing(), "otherwise should not see this");
+    return NULL;
   }
   // Fall through to failure
   return NULL;
 }
 
 
+const Type* Type::make_constant(ciField* field, Node* obj) {
+  if (!field->is_constant())  return NULL;
+
+  const Type* con_type = NULL;
+  if (field->is_static()) {
+    // final static field
+    con_type = Type::make_from_constant(field->constant_value(), /*require_const=*/true);
+    if (Compile::current()->eliminate_boxing() && field->is_autobox_cache() && con_type != NULL) {
+      con_type = con_type->is_aryptr()->cast_to_autobox_cache(true);
+    }
+  } else {
+    // final or stable non-static field
+    // Treat final non-static fields of trusted classes (classes in
+    // java.lang.invoke and sun.invoke packages and subpackages) as
+    // compile time constants.
+    if (obj->is_Con()) {
+      const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
+      ciObject* constant_oop = oop_ptr->const_oop();
+      ciConstant constant = field->constant_value_of(constant_oop);
+      con_type = Type::make_from_constant(constant, /*require_const=*/true);
+    }
+  }
+  if (FoldStableValues && field->is_stable() && con_type != NULL) {
+    if (con_type->is_zero_type()) {
+      return NULL; // the field hasn't been initialized yet
+    } else if (con_type->isa_oopptr()) {
+      const Type* stable_type = Type::get_const_type(field->type());
+      if (field->type()->is_array_klass()) {
+        int stable_dimension = field->type()->as_array_klass()->dimension();
+        stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension);
+      }
+      if (stable_type != NULL) {
+        con_type = con_type->join_speculative(stable_type);
+      }
+    }
+  }
+  return con_type;
+}
+
 //------------------------------make-------------------------------------------
 // Create a simple Type, with default empty symbol sets.  Then hashcons it
 // and look for an existing copy in the type dictionary.
 const Type *Type::make( enum TYPES t ) {
   return (new Type(t))->hashcons();

@@ -3007,13 +3049,11 @@
   }
 }
 
 //------------------------------make_from_constant-----------------------------
 // Make a java pointer from an oop constant
-const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o,
-                                                 bool require_constant,
-                                                 bool is_autobox_cache) {
+const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, bool require_constant) {
   assert(!o->is_null_object(), "null object not yet handled here.");
   ciKlass* klass = o->klass();
   if (klass->is_instance_klass()) {
     // Element is an instance
     if (require_constant) {

@@ -3024,24 +3064,20 @@
     return TypeInstPtr::make(o);
   } else if (klass->is_obj_array_klass()) {
     // Element is an object array. Recursively call ourself.
     const TypeOopPtr *etype =
       TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass());
-    if (is_autobox_cache) {
-      // The pointers in the autobox arrays are always non-null.
-      etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
-    }
     const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length()));
     // We used to pass NotNull in here, asserting that the sub-arrays
     // are all not-null.  This is not true in generally, as code can
     // slam NULLs down in the subarrays.
     if (require_constant) {
       if (!o->can_be_constant())  return NULL;
     } else if (!o->should_be_constant()) {
       return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0);
     }
-    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, InlineDepthBottom, is_autobox_cache);
+    const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0);
     return arr;
   } else if (klass->is_type_array_klass()) {
     // Element is an typeArray
     const Type* etype =
       (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type());

@@ -3938,11 +3974,10 @@
   if (new_size == size())  return this;
   const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable());
   return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth);
 }
 
-
 //------------------------------cast_to_stable---------------------------------
 const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const {
   if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable()))
     return this;
 

@@ -3967,10 +4002,22 @@
   if (elem_ptr != NULL && elem_ptr->isa_aryptr())
     dim += elem_ptr->is_aryptr()->stable_dimension();
   return dim;
 }
 
+//----------------------cast_to_autobox_cache-----------------------------------
+const TypeAryPtr* TypeAryPtr::cast_to_autobox_cache(bool cache) const {
+  if (is_autobox_cache() == cache)  return this;
+  const TypeOopPtr* etype = elem()->make_oopptr();
+  if (etype == NULL)  return this;
+  // The pointers in the autobox arrays are always non-null.
+  TypePtr::PTR ptr_type = cache ? TypePtr::NotNull : TypePtr::AnyNull;
+  etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
+  const TypeAry* new_ary = TypeAry::make(etype, size(), is_stable());
+  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth, cache);
+}
+
 //------------------------------eq---------------------------------------------
 // Structural equality check for Type representations
 bool TypeAryPtr::eq( const Type *t ) const {
   const TypeAryPtr *p = t->is_aryptr();
   return

@@ -4453,11 +4500,11 @@
 
 //------------------------------singleton--------------------------------------
 // TRUE if Type is a singleton type, FALSE otherwise.   Singletons are simple
 // constants
 bool TypeMetadataPtr::singleton(void) const {
-  // detune optimizer to not generate constant metadta + constant offset as a constant!
+  // detune optimizer to not generate constant metadata + constant offset as a constant!
   // TopPTR, Null, AnyNull, Constant are all singletons
   return (_offset == 0) && !below_centerline(_ptr);
 }
 
 //------------------------------add_offset-------------------------------------
< prev index next >