Mercurial > hg > truffle
comparison src/share/vm/opto/type.cpp @ 163:885ed790ecf0
6695810: null oop passed to encode_heap_oop_not_null
Summary: fix several problems in C2 related to Escape Analysis and Compressed Oops.
Reviewed-by: never, jrose
author | kvn |
---|---|
date | Wed, 21 May 2008 10:45:07 -0700 |
parents | ba764ed4b6f2 |
children | d4dbd9f91680 |
comparison
equal
deleted
inserted
replaced
162:8aa010f60e0f | 163:885ed790ecf0 |
---|---|
309 mreg2type[Op_RegD] = Type::DOUBLE; | 309 mreg2type[Op_RegD] = Type::DOUBLE; |
310 mreg2type[Op_RegL] = TypeLong::LONG; | 310 mreg2type[Op_RegL] = TypeLong::LONG; |
311 mreg2type[Op_RegFlags] = TypeInt::CC; | 311 mreg2type[Op_RegFlags] = TypeInt::CC; |
312 | 312 |
313 TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes()); | 313 TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes()); |
314 // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). | 314 |
315 TypeAryPtr::OOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); | 315 TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); |
316 | |
317 #ifdef _LP64 | |
318 if (UseCompressedOops) { | |
319 TypeAryPtr::OOPS = TypeAryPtr::NARROWOOPS; | |
320 } else | |
321 #endif | |
322 { | |
323 // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). | |
324 TypeAryPtr::OOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); | |
325 } | |
316 TypeAryPtr::BYTES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE), true, Type::OffsetBot); | 326 TypeAryPtr::BYTES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE), true, Type::OffsetBot); |
317 TypeAryPtr::SHORTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::SHORT ,TypeInt::POS), ciTypeArrayKlass::make(T_SHORT), true, Type::OffsetBot); | 327 TypeAryPtr::SHORTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::SHORT ,TypeInt::POS), ciTypeArrayKlass::make(T_SHORT), true, Type::OffsetBot); |
318 TypeAryPtr::CHARS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::CHAR ,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, Type::OffsetBot); | 328 TypeAryPtr::CHARS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::CHAR ,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, Type::OffsetBot); |
319 TypeAryPtr::INTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::INT ,TypeInt::POS), ciTypeArrayKlass::make(T_INT), true, Type::OffsetBot); | 329 TypeAryPtr::INTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::INT ,TypeInt::POS), ciTypeArrayKlass::make(T_INT), true, Type::OffsetBot); |
320 TypeAryPtr::LONGS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeLong::LONG ,TypeInt::POS), ciTypeArrayKlass::make(T_LONG), true, Type::OffsetBot); | 330 TypeAryPtr::LONGS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeLong::LONG ,TypeInt::POS), ciTypeArrayKlass::make(T_LONG), true, Type::OffsetBot); |
321 TypeAryPtr::FLOATS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT), true, Type::OffsetBot); | 331 TypeAryPtr::FLOATS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT), true, Type::OffsetBot); |
322 TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true, Type::OffsetBot); | 332 TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true, Type::OffsetBot); |
323 | 333 |
324 TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; // what should this be? | 334 // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert. |
335 TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; | |
325 TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS; | 336 TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS; |
326 TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays | 337 TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays |
327 TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES; | 338 TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES; |
328 TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array | 339 TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array |
329 TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS; | 340 TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS; |
330 TypeAryPtr::_array_body_type[T_CHAR] = TypeAryPtr::CHARS; | 341 TypeAryPtr::_array_body_type[T_CHAR] = TypeAryPtr::CHARS; |
331 TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS; | 342 TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS; |
694 //------------------------------dump------------------------------------------- | 705 //------------------------------dump------------------------------------------- |
695 void Type::dump_on(outputStream *st) const { | 706 void Type::dump_on(outputStream *st) const { |
696 ResourceMark rm; | 707 ResourceMark rm; |
697 Dict d(cmpkey,hashkey); // Stop recursive type dumping | 708 Dict d(cmpkey,hashkey); // Stop recursive type dumping |
698 dump2(d,1, st); | 709 dump2(d,1, st); |
699 if (isa_ptr() && is_ptr()->is_narrow()) { | 710 if (is_ptr_to_narrowoop()) { |
700 st->print(" [narrow]"); | 711 st->print(" [narrow]"); |
701 } | 712 } |
702 } | 713 } |
703 | 714 |
704 //------------------------------data------------------------------------------- | 715 //------------------------------data------------------------------------------- |
2143 #endif | 2154 #endif |
2144 | 2155 |
2145 //============================================================================= | 2156 //============================================================================= |
2146 // Convenience common pre-built type. | 2157 // Convenience common pre-built type. |
2147 const TypeOopPtr *TypeOopPtr::BOTTOM; | 2158 const TypeOopPtr *TypeOopPtr::BOTTOM; |
2159 | |
2160 //------------------------------TypeOopPtr------------------------------------- | |
2161 TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id ) | |
2162 : TypePtr(t, ptr, offset), | |
2163 _const_oop(o), _klass(k), | |
2164 _klass_is_exact(xk), | |
2165 _is_ptr_to_narrowoop(false), | |
2166 _instance_id(instance_id) { | |
2167 #ifdef _LP64 | |
2168 if (UseCompressedOops && _offset != 0) { | |
2169 if (klass() == NULL) { | |
2170 assert(this->isa_aryptr(), "only arrays without klass"); | |
2171 _is_ptr_to_narrowoop = true; | |
2172 } else if (_offset == oopDesc::klass_offset_in_bytes()) { | |
2173 _is_ptr_to_narrowoop = true; | |
2174 } else if (this->isa_aryptr()) { | |
2175 _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() && | |
2176 _offset != arrayOopDesc::length_offset_in_bytes()); | |
2177 } else if (klass() == ciEnv::current()->Class_klass() && | |
2178 (_offset == java_lang_Class::klass_offset_in_bytes() || | |
2179 _offset == java_lang_Class::array_klass_offset_in_bytes())) { | |
2180 // Special hidden fields from the Class. | |
2181 assert(this->isa_instptr(), "must be an instance ptr."); | |
2182 _is_ptr_to_narrowoop = true; | |
2183 } else if (klass()->is_instance_klass()) { | |
2184 ciInstanceKlass* ik = klass()->as_instance_klass(); | |
2185 ciField* field = NULL; | |
2186 if (this->isa_klassptr()) { | |
2187 // Perm objects don't use compressed references, except for | |
2188 // static fields which are currently compressed. | |
2189 field = ik->get_field_by_offset(_offset, true); | |
2190 if (field != NULL) { | |
2191 BasicType basic_elem_type = field->layout_type(); | |
2192 _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT || | |
2193 basic_elem_type == T_ARRAY); | |
2194 } | |
2195 } else if (_offset == OffsetBot || _offset == OffsetTop) { | |
2196 // unsafe access | |
2197 _is_ptr_to_narrowoop = true; | |
2198 } else { // exclude unsafe ops | |
2199 assert(this->isa_instptr(), "must be an instance ptr."); | |
2200 // Field which contains a compressed oop references. | |
2201 field = ik->get_field_by_offset(_offset, false); | |
2202 if (field != NULL) { | |
2203 BasicType basic_elem_type = field->layout_type(); | |
2204 _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT || | |
2205 basic_elem_type == T_ARRAY); | |
2206 } else if (klass()->equals(ciEnv::current()->Object_klass())) { | |
2207 // Compile::find_alias_type() cast exactness on all types to verify | |
2208 // that it does not affect alias type. | |
2209 _is_ptr_to_narrowoop = true; | |
2210 } else { | |
2211 // Type for the copy start in LibraryCallKit::inline_native_clone(). | |
2212 assert(!klass_is_exact(), "only non-exact klass"); | |
2213 _is_ptr_to_narrowoop = true; | |
2214 } | |
2215 } | |
2216 } | |
2217 } | |
2218 #endif | |
2219 } | |
2148 | 2220 |
2149 //------------------------------make------------------------------------------- | 2221 //------------------------------make------------------------------------------- |
2150 const TypeOopPtr *TypeOopPtr::make(PTR ptr, | 2222 const TypeOopPtr *TypeOopPtr::make(PTR ptr, |
2151 int offset) { | 2223 int offset) { |
2152 assert(ptr != Constant, "no constant generic pointers"); | 2224 assert(ptr != Constant, "no constant generic pointers"); |
2591 } | 2663 } |
2592 | 2664 |
2593 //-----------------------------cast_to_instance------------------------------- | 2665 //-----------------------------cast_to_instance------------------------------- |
2594 const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const { | 2666 const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const { |
2595 if( instance_id == _instance_id) return this; | 2667 if( instance_id == _instance_id) return this; |
2596 bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true; | 2668 bool exact = true; |
2597 | 2669 PTR ptr_t = NotNull; |
2598 return make(ptr(), klass(), exact, const_oop(), _offset, instance_id); | 2670 if (instance_id == UNKNOWN_INSTANCE) { |
2671 exact = _klass_is_exact; | |
2672 ptr_t = _ptr; | |
2673 } | |
2674 return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id); | |
2599 } | 2675 } |
2600 | 2676 |
2601 //------------------------------xmeet_unloaded--------------------------------- | 2677 //------------------------------xmeet_unloaded--------------------------------- |
2602 // Compute the MEET of two InstPtrs when at least one is unloaded. | 2678 // Compute the MEET of two InstPtrs when at least one is unloaded. |
2603 // Assume classes are different since called after check for same name/class-loader | 2679 // Assume classes are different since called after check for same name/class-loader |
3012 | 3088 |
3013 //============================================================================= | 3089 //============================================================================= |
3014 // Convenience common pre-built types. | 3090 // Convenience common pre-built types. |
3015 const TypeAryPtr *TypeAryPtr::RANGE; | 3091 const TypeAryPtr *TypeAryPtr::RANGE; |
3016 const TypeAryPtr *TypeAryPtr::OOPS; | 3092 const TypeAryPtr *TypeAryPtr::OOPS; |
3093 const TypeAryPtr *TypeAryPtr::NARROWOOPS; | |
3017 const TypeAryPtr *TypeAryPtr::BYTES; | 3094 const TypeAryPtr *TypeAryPtr::BYTES; |
3018 const TypeAryPtr *TypeAryPtr::SHORTS; | 3095 const TypeAryPtr *TypeAryPtr::SHORTS; |
3019 const TypeAryPtr *TypeAryPtr::CHARS; | 3096 const TypeAryPtr *TypeAryPtr::CHARS; |
3020 const TypeAryPtr *TypeAryPtr::INTS; | 3097 const TypeAryPtr *TypeAryPtr::INTS; |
3021 const TypeAryPtr *TypeAryPtr::LONGS; | 3098 const TypeAryPtr *TypeAryPtr::LONGS; |
3061 } | 3138 } |
3062 | 3139 |
3063 //-----------------------------cast_to_instance------------------------------- | 3140 //-----------------------------cast_to_instance------------------------------- |
3064 const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const { | 3141 const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const { |
3065 if( instance_id == _instance_id) return this; | 3142 if( instance_id == _instance_id) return this; |
3066 bool exact = (instance_id == UNKNOWN_INSTANCE) ? _klass_is_exact : true; | 3143 bool exact = true; |
3067 return make(ptr(), const_oop(), _ary, klass(), exact, _offset, instance_id); | 3144 PTR ptr_t = NotNull; |
3145 if (instance_id == UNKNOWN_INSTANCE) { | |
3146 exact = _klass_is_exact; | |
3147 ptr_t = _ptr; | |
3148 } | |
3149 return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id); | |
3068 } | 3150 } |
3069 | 3151 |
3070 //-----------------------------narrow_size_type------------------------------- | 3152 //-----------------------------narrow_size_type------------------------------- |
3071 // Local cache for arrayOopDesc::max_array_length(etype), | 3153 // Local cache for arrayOopDesc::max_array_length(etype), |
3072 // which is kind of slow (and cached elsewhere by other users). | 3154 // which is kind of slow (and cached elsewhere by other users). |
3545 "integral arrays must be pre-equipped with a class"); | 3627 "integral arrays must be pre-equipped with a class"); |
3546 // Compute array klass directly from basic type | 3628 // Compute array klass directly from basic type |
3547 k_ary = ciTypeArrayKlass::make(el->basic_type()); | 3629 k_ary = ciTypeArrayKlass::make(el->basic_type()); |
3548 } | 3630 } |
3549 | 3631 |
3550 if( this != TypeAryPtr::OOPS ) | 3632 if( this != TypeAryPtr::OOPS ) { |
3551 // The _klass field acts as a cache of the underlying | 3633 // The _klass field acts as a cache of the underlying |
3552 // ciKlass for this array type. In order to set the field, | 3634 // ciKlass for this array type. In order to set the field, |
3553 // we need to cast away const-ness. | 3635 // we need to cast away const-ness. |
3554 // | 3636 // |
3555 // IMPORTANT NOTE: we *never* set the _klass field for the | 3637 // IMPORTANT NOTE: we *never* set the _klass field for the |
3560 // | 3642 // |
3561 // Recomputing the underlying ciKlass for each request is | 3643 // Recomputing the underlying ciKlass for each request is |
3562 // a bit less efficient than caching, but calls to | 3644 // a bit less efficient than caching, but calls to |
3563 // TypeAryPtr::OOPS->klass() are not common enough to matter. | 3645 // TypeAryPtr::OOPS->klass() are not common enough to matter. |
3564 ((TypeAryPtr*)this)->_klass = k_ary; | 3646 ((TypeAryPtr*)this)->_klass = k_ary; |
3647 if (UseCompressedOops && k_ary != NULL && k_ary->is_obj_array_klass() && | |
3648 _offset != 0 && _offset != arrayOopDesc::length_offset_in_bytes()) { | |
3649 ((TypeAryPtr*)this)->_is_ptr_to_narrowoop = true; | |
3650 } | |
3651 } | |
3565 return k_ary; | 3652 return k_ary; |
3566 } | 3653 } |
3567 | 3654 |
3568 | 3655 |
3569 //------------------------------add_offset------------------------------------- | 3656 //------------------------------add_offset------------------------------------- |