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