src/share/vm/opto/type.cpp

changeset 5710
884ed7a10f09
parent 5694
7944aba7ba41
parent 5658
edb5ab0f3fe5
child 5791
c9ccd7b85f20
     1.1 --- a/src/share/vm/opto/type.cpp	Fri Sep 13 07:57:13 2013 +0200
     1.2 +++ b/src/share/vm/opto/type.cpp	Mon Sep 16 09:41:03 2013 +0200
     1.3 @@ -189,6 +189,38 @@
     1.4  }
     1.5  
     1.6  
     1.7 +//-----------------------make_from_constant------------------------------------
     1.8 +const Type* Type::make_from_constant(ciConstant constant,
     1.9 +                                     bool require_constant, bool is_autobox_cache) {
    1.10 +  switch (constant.basic_type()) {
    1.11 +  case T_BOOLEAN:  return TypeInt::make(constant.as_boolean());
    1.12 +  case T_CHAR:     return TypeInt::make(constant.as_char());
    1.13 +  case T_BYTE:     return TypeInt::make(constant.as_byte());
    1.14 +  case T_SHORT:    return TypeInt::make(constant.as_short());
    1.15 +  case T_INT:      return TypeInt::make(constant.as_int());
    1.16 +  case T_LONG:     return TypeLong::make(constant.as_long());
    1.17 +  case T_FLOAT:    return TypeF::make(constant.as_float());
    1.18 +  case T_DOUBLE:   return TypeD::make(constant.as_double());
    1.19 +  case T_ARRAY:
    1.20 +  case T_OBJECT:
    1.21 +    {
    1.22 +      // cases:
    1.23 +      //   can_be_constant    = (oop not scavengable || ScavengeRootsInCode != 0)
    1.24 +      //   should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2)
    1.25 +      // An oop is not scavengable if it is in the perm gen.
    1.26 +      ciObject* oop_constant = constant.as_object();
    1.27 +      if (oop_constant->is_null_object()) {
    1.28 +        return Type::get_zero_type(T_OBJECT);
    1.29 +      } else if (require_constant || oop_constant->should_be_constant()) {
    1.30 +        return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache);
    1.31 +      }
    1.32 +    }
    1.33 +  }
    1.34 +  // Fall through to failure
    1.35 +  return NULL;
    1.36 +}
    1.37 +
    1.38 +
    1.39  //------------------------------make-------------------------------------------
    1.40  // Create a simple Type, with default empty symbol sets.  Then hashcons it
    1.41  // and look for an existing copy in the type dictionary.
    1.42 @@ -1824,12 +1856,12 @@
    1.43  }
    1.44  
    1.45  //------------------------------make-------------------------------------------
    1.46 -const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
    1.47 +const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) {
    1.48    if (UseCompressedOops && elem->isa_oopptr()) {
    1.49      elem = elem->make_narrowoop();
    1.50    }
    1.51    size = normalize_array_size(size);
    1.52 -  return (TypeAry*)(new TypeAry(elem,size))->hashcons();
    1.53 +  return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons();
    1.54  }
    1.55  
    1.56  //------------------------------meet-------------------------------------------
    1.57 @@ -1850,7 +1882,8 @@
    1.58    case Array: {                 // Meeting 2 arrays?
    1.59      const TypeAry *a = t->is_ary();
    1.60      return TypeAry::make(_elem->meet(a->_elem),
    1.61 -                         _size->xmeet(a->_size)->is_int());
    1.62 +                         _size->xmeet(a->_size)->is_int(),
    1.63 +                         _stable & a->_stable);
    1.64    }
    1.65    case Top:
    1.66      break;
    1.67 @@ -1863,7 +1896,7 @@
    1.68  const Type *TypeAry::xdual() const {
    1.69    const TypeInt* size_dual = _size->dual()->is_int();
    1.70    size_dual = normalize_array_size(size_dual);
    1.71 -  return new TypeAry( _elem->dual(), size_dual);
    1.72 +  return new TypeAry(_elem->dual(), size_dual, !_stable);
    1.73  }
    1.74  
    1.75  //------------------------------eq---------------------------------------------
    1.76 @@ -1871,13 +1904,14 @@
    1.77  bool TypeAry::eq( const Type *t ) const {
    1.78    const TypeAry *a = (const TypeAry*)t;
    1.79    return _elem == a->_elem &&
    1.80 +    _stable == a->_stable &&
    1.81      _size == a->_size;
    1.82  }
    1.83  
    1.84  //------------------------------hash-------------------------------------------
    1.85  // Type-specific hashing function.
    1.86  int TypeAry::hash(void) const {
    1.87 -  return (intptr_t)_elem + (intptr_t)_size;
    1.88 +  return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0);
    1.89  }
    1.90  
    1.91  //----------------------interface_vs_oop---------------------------------------
    1.92 @@ -1894,6 +1928,7 @@
    1.93  //------------------------------dump2------------------------------------------
    1.94  #ifndef PRODUCT
    1.95  void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const {
    1.96 +  if (_stable)  st->print("stable:");
    1.97    _elem->dump2(d, depth, st);
    1.98    st->print("[");
    1.99    _size->dump2(d, depth, st);
   1.100 @@ -3457,11 +3492,39 @@
   1.101    assert(new_size != NULL, "");
   1.102    new_size = narrow_size_type(new_size);
   1.103    if (new_size == size())  return this;
   1.104 -  const TypeAry* new_ary = TypeAry::make(elem(), new_size);
   1.105 +  const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable());
   1.106    return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
   1.107  }
   1.108  
   1.109  
   1.110 +//------------------------------cast_to_stable---------------------------------
   1.111 +const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const {
   1.112 +  if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable()))
   1.113 +    return this;
   1.114 +
   1.115 +  const Type* elem = this->elem();
   1.116 +  const TypePtr* elem_ptr = elem->make_ptr();
   1.117 +
   1.118 +  if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) {
   1.119 +    // If this is widened from a narrow oop, TypeAry::make will re-narrow it.
   1.120 +    elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1);
   1.121 +  }
   1.122 +
   1.123 +  const TypeAry* new_ary = TypeAry::make(elem, size(), stable);
   1.124 +
   1.125 +  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
   1.126 +}
   1.127 +
   1.128 +//-----------------------------stable_dimension--------------------------------
   1.129 +int TypeAryPtr::stable_dimension() const {
   1.130 +  if (!is_stable())  return 0;
   1.131 +  int dim = 1;
   1.132 +  const TypePtr* elem_ptr = elem()->make_ptr();
   1.133 +  if (elem_ptr != NULL && elem_ptr->isa_aryptr())
   1.134 +    dim += elem_ptr->is_aryptr()->stable_dimension();
   1.135 +  return dim;
   1.136 +}
   1.137 +
   1.138  //------------------------------eq---------------------------------------------
   1.139  // Structural equality check for Type representations
   1.140  bool TypeAryPtr::eq( const Type *t ) const {
   1.141 @@ -3570,7 +3633,7 @@
   1.142          // Something like byte[int+] meets char[int+].
   1.143          // This must fall to bottom, not (int[-128..65535])[int+].
   1.144          instance_id = InstanceBot;
   1.145 -        tary = TypeAry::make(Type::BOTTOM, tary->_size);
   1.146 +        tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
   1.147        }
   1.148      } else // Non integral arrays.
   1.149      // Must fall to bottom if exact klasses in upper lattice
   1.150 @@ -3584,7 +3647,7 @@
   1.151           (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
   1.152           // 'this' is exact and super or unrelated:
   1.153           (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
   1.154 -      tary = TypeAry::make(Type::BOTTOM, tary->_size);
   1.155 +      tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
   1.156        return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot );
   1.157      }
   1.158  

mercurial