src/share/vm/opto/type.cpp

changeset 598
885ed790ecf0
parent 548
ba764ed4b6f2
child 618
d4dbd9f91680
     1.1 --- a/src/share/vm/opto/type.cpp	Tue May 20 06:32:58 2008 -0700
     1.2 +++ b/src/share/vm/opto/type.cpp	Wed May 21 10:45:07 2008 -0700
     1.3 @@ -311,8 +311,18 @@
     1.4    mreg2type[Op_RegFlags] = TypeInt::CC;
     1.5  
     1.6    TypeAryPtr::RANGE   = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes());
     1.7 -  // There is no shared klass for Object[].  See note in TypeAryPtr::klass().
     1.8 -  TypeAryPtr::OOPS    = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
     1.9 +
    1.10 +  TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
    1.11 +
    1.12 +#ifdef _LP64
    1.13 +  if (UseCompressedOops) {
    1.14 +    TypeAryPtr::OOPS  = TypeAryPtr::NARROWOOPS;
    1.15 +  } else
    1.16 +#endif
    1.17 +  {
    1.18 +    // There is no shared klass for Object[].  See note in TypeAryPtr::klass().
    1.19 +    TypeAryPtr::OOPS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/,  false,  Type::OffsetBot);
    1.20 +  }
    1.21    TypeAryPtr::BYTES   = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE      ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE),   true,  Type::OffsetBot);
    1.22    TypeAryPtr::SHORTS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::SHORT     ,TypeInt::POS), ciTypeArrayKlass::make(T_SHORT),  true,  Type::OffsetBot);
    1.23    TypeAryPtr::CHARS   = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::CHAR      ,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR),   true,  Type::OffsetBot);
    1.24 @@ -321,9 +331,10 @@
    1.25    TypeAryPtr::FLOATS  = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT        ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT),  true,  Type::OffsetBot);
    1.26    TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE       ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true,  Type::OffsetBot);
    1.27  
    1.28 -  TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; // what should this be?
    1.29 +  // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert.
    1.30 +  TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL;
    1.31    TypeAryPtr::_array_body_type[T_OBJECT]  = TypeAryPtr::OOPS;
    1.32 -  TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS;   // arrays are stored in oop arrays
    1.33 +  TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS; // arrays are stored in oop arrays
    1.34    TypeAryPtr::_array_body_type[T_BYTE]    = TypeAryPtr::BYTES;
    1.35    TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES;  // boolean[] is a byte array
    1.36    TypeAryPtr::_array_body_type[T_SHORT]   = TypeAryPtr::SHORTS;
    1.37 @@ -696,7 +707,7 @@
    1.38    ResourceMark rm;
    1.39    Dict d(cmpkey,hashkey);       // Stop recursive type dumping
    1.40    dump2(d,1, st);
    1.41 -  if (isa_ptr() && is_ptr()->is_narrow()) {
    1.42 +  if (is_ptr_to_narrowoop()) {
    1.43      st->print(" [narrow]");
    1.44    }
    1.45  }
    1.46 @@ -2146,6 +2157,67 @@
    1.47  // Convenience common pre-built type.
    1.48  const TypeOopPtr *TypeOopPtr::BOTTOM;
    1.49  
    1.50 +//------------------------------TypeOopPtr-------------------------------------
    1.51 +TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id )
    1.52 +  : TypePtr(t, ptr, offset),
    1.53 +    _const_oop(o), _klass(k),
    1.54 +    _klass_is_exact(xk),
    1.55 +    _is_ptr_to_narrowoop(false),
    1.56 +    _instance_id(instance_id) {
    1.57 +#ifdef _LP64
    1.58 +  if (UseCompressedOops && _offset != 0) {
    1.59 +    if (klass() == NULL) {
    1.60 +      assert(this->isa_aryptr(), "only arrays without klass");
    1.61 +      _is_ptr_to_narrowoop = true;
    1.62 +    } else if (_offset == oopDesc::klass_offset_in_bytes()) {
    1.63 +      _is_ptr_to_narrowoop = true;
    1.64 +    } else if (this->isa_aryptr()) {
    1.65 +      _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
    1.66 +                             _offset != arrayOopDesc::length_offset_in_bytes());
    1.67 +    } else if (klass() == ciEnv::current()->Class_klass() &&
    1.68 +               (_offset == java_lang_Class::klass_offset_in_bytes() ||
    1.69 +                _offset == java_lang_Class::array_klass_offset_in_bytes())) {
    1.70 +      // Special hidden fields from the Class.
    1.71 +      assert(this->isa_instptr(), "must be an instance ptr.");
    1.72 +      _is_ptr_to_narrowoop = true;
    1.73 +    } else if (klass()->is_instance_klass()) {
    1.74 +      ciInstanceKlass* ik = klass()->as_instance_klass();
    1.75 +      ciField* field = NULL;
    1.76 +      if (this->isa_klassptr()) {
    1.77 +        // Perm objects don't use compressed references, except for
    1.78 +        // static fields which are currently compressed.
    1.79 +        field = ik->get_field_by_offset(_offset, true);
    1.80 +        if (field != NULL) {
    1.81 +          BasicType basic_elem_type = field->layout_type();
    1.82 +          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
    1.83 +                                  basic_elem_type == T_ARRAY);
    1.84 +        }
    1.85 +      } else if (_offset == OffsetBot || _offset == OffsetTop) {
    1.86 +        // unsafe access
    1.87 +        _is_ptr_to_narrowoop = true;
    1.88 +      } else { // exclude unsafe ops
    1.89 +        assert(this->isa_instptr(), "must be an instance ptr.");
    1.90 +        // Field which contains a compressed oop references.
    1.91 +        field = ik->get_field_by_offset(_offset, false);
    1.92 +        if (field != NULL) {
    1.93 +          BasicType basic_elem_type = field->layout_type();
    1.94 +          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
    1.95 +                                  basic_elem_type == T_ARRAY);
    1.96 +        } else if (klass()->equals(ciEnv::current()->Object_klass())) {
    1.97 +          // Compile::find_alias_type() cast exactness on all types to verify
    1.98 +          // that it does not affect alias type.
    1.99 +          _is_ptr_to_narrowoop = true;
   1.100 +        } else {
   1.101 +          // Type for the copy start in LibraryCallKit::inline_native_clone().
   1.102 +          assert(!klass_is_exact(), "only non-exact klass");
   1.103 +          _is_ptr_to_narrowoop = true;
   1.104 +        }
   1.105 +      }
   1.106 +    }
   1.107 +  }
   1.108 +#endif
   1.109 +}
   1.110 +
   1.111  //------------------------------make-------------------------------------------
   1.112  const TypeOopPtr *TypeOopPtr::make(PTR ptr,
   1.113                                     int offset) {
   1.114 @@ -2593,9 +2665,13 @@
   1.115  //-----------------------------cast_to_instance-------------------------------
   1.116  const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const {
   1.117    if( instance_id == _instance_id) return this;
   1.118 -  bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true;
   1.119 -
   1.120 -  return make(ptr(), klass(), exact, const_oop(), _offset, instance_id);
   1.121 +  bool exact = true;
   1.122 +  PTR  ptr_t = NotNull;
   1.123 +  if (instance_id == UNKNOWN_INSTANCE) {
   1.124 +    exact = _klass_is_exact;
   1.125 +    ptr_t = _ptr;
   1.126 +  }
   1.127 +  return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
   1.128  }
   1.129  
   1.130  //------------------------------xmeet_unloaded---------------------------------
   1.131 @@ -3014,6 +3090,7 @@
   1.132  // Convenience common pre-built types.
   1.133  const TypeAryPtr *TypeAryPtr::RANGE;
   1.134  const TypeAryPtr *TypeAryPtr::OOPS;
   1.135 +const TypeAryPtr *TypeAryPtr::NARROWOOPS;
   1.136  const TypeAryPtr *TypeAryPtr::BYTES;
   1.137  const TypeAryPtr *TypeAryPtr::SHORTS;
   1.138  const TypeAryPtr *TypeAryPtr::CHARS;
   1.139 @@ -3063,8 +3140,13 @@
   1.140  //-----------------------------cast_to_instance-------------------------------
   1.141  const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const {
   1.142    if( instance_id == _instance_id) return this;
   1.143 -  bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true;
   1.144 -  return make(ptr(), const_oop(), _ary, klass(), exact, _offset, instance_id);
   1.145 +  bool exact = true;
   1.146 +  PTR  ptr_t = NotNull;
   1.147 +  if (instance_id == UNKNOWN_INSTANCE) {
   1.148 +    exact = _klass_is_exact;
   1.149 +    ptr_t = _ptr;
   1.150 +  }
   1.151 +  return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
   1.152  }
   1.153  
   1.154  //-----------------------------narrow_size_type-------------------------------
   1.155 @@ -3547,7 +3629,7 @@
   1.156      k_ary = ciTypeArrayKlass::make(el->basic_type());
   1.157    }
   1.158  
   1.159 -  if( this != TypeAryPtr::OOPS )
   1.160 +  if( this != TypeAryPtr::OOPS ) {
   1.161      // The _klass field acts as a cache of the underlying
   1.162      // ciKlass for this array type.  In order to set the field,
   1.163      // we need to cast away const-ness.
   1.164 @@ -3562,6 +3644,11 @@
   1.165      // a bit less efficient than caching, but calls to
   1.166      // TypeAryPtr::OOPS->klass() are not common enough to matter.
   1.167      ((TypeAryPtr*)this)->_klass = k_ary;
   1.168 +    if (UseCompressedOops && k_ary != NULL && k_ary->is_obj_array_klass() &&
   1.169 +        _offset != 0 && _offset != arrayOopDesc::length_offset_in_bytes()) {
   1.170 +      ((TypeAryPtr*)this)->_is_ptr_to_narrowoop = true;
   1.171 +    }
   1.172 +  }
   1.173    return k_ary;
   1.174  }
   1.175  

mercurial