diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 80bb1dcf408..f1ea8231df9 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1369,72 +1369,37 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { cast_to_ptr_type(ptr)-> with_offset(offset); } - } else if (ta) { - // For arrays indexed by constant indices, we flatten the alias - // space to include all of the array body. Only the header, klass - // and array length can be accessed un-aliased. - if( offset != Type::OffsetBot ) { - if( ta->const_oop() ) { // MethodData* or Method* - offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = ta-> - remove_speculative()-> - cast_to_ptr_type(ptr)-> - cast_to_exactness(false)-> - with_offset(offset); - } else if( offset == arrayOopDesc::length_offset_in_bytes() ) { - // range is OK as-is. - tj = ta = TypeAryPtr::RANGE; - } else if( offset == oopDesc::klass_offset_in_bytes() ) { - tj = TypeInstPtr::KLASS; // all klass loads look alike - ta = TypeAryPtr::RANGE; // generic ignored junk - ptr = TypePtr::BotPTR; - } else if( offset == oopDesc::mark_offset_in_bytes() ) { - tj = TypeInstPtr::MARK; - ta = TypeAryPtr::RANGE; // generic ignored junk - ptr = TypePtr::BotPTR; - } else { // Random constant offset into array body - offset = Type::OffsetBot; // Flatten constant access into array body - tj = ta = ta-> - remove_speculative()-> - cast_to_ptr_type(ptr)-> - cast_to_exactness(false)-> - with_offset(offset); - } + } else if (ta != nullptr) { + // Common slices + if (offset == arrayOopDesc::length_offset_in_bytes()) { + return TypeAryPtr::RANGE; + } else if (offset == oopDesc::klass_offset_in_bytes()) { + return TypeInstPtr::KLASS; + } else if (offset == oopDesc::mark_offset_in_bytes()) { + return TypeInstPtr::MARK; } - // Arrays of fixed size alias with arrays of unknown size. - if (ta->size() != TypeInt::POS) { - const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS); - tj = ta = ta-> - remove_speculative()-> - cast_to_ptr_type(ptr)-> - with_ary(tary)-> - cast_to_exactness(false); - } - // Arrays of known objects become arrays of unknown objects. - if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) { - const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,nullptr,false,offset); - } - if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) { - const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size()); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,nullptr,false,offset); + + // Remove size and stability + const TypeAry* normalized_ary = TypeAry::make(ta->elem(), TypeInt::POS, false); + // Remove ptr, const_oop, and offset + if (ta->elem() == Type::BOTTOM) { + // Bottom array (meet of int[] and byte[] for example), accesses to it will be done with + // Unsafe. This should alias with all arrays. For now just leave it as it is (this is + // incorrect, see JDK-8331133). + tj = ta = TypeAryPtr::make(TypePtr::BotPTR, nullptr, normalized_ary, nullptr, false, Type::OffsetBot); + } else if (ta->elem()->make_oopptr() != nullptr) { + // Object arrays, all of them share the same slice + const TypeAry* tary = TypeAry::make(TypeInstPtr::BOTTOM, TypeInt::POS, false); + tj = ta = TypeAryPtr::make(TypePtr::BotPTR, nullptr, tary, nullptr, false, Type::OffsetBot); + } else { + // Primitive arrays + tj = ta = TypeAryPtr::make(TypePtr::BotPTR, nullptr, normalized_ary, ta->exact_klass(), true, Type::OffsetBot); } + // Arrays of bytes and of booleans both use 'bastore' and 'baload' so // cannot be distinguished by bytecode alone. if (ta->elem() == TypeInt::BOOL) { - const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size()); - ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE); - tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); - } - // During the 2nd round of IterGVN, NotNull castings are removed. - // Make sure the Bottom and NotNull variants alias the same. - // Also, make sure exact and non-exact variants alias the same. - if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != nullptr) { - tj = ta = ta-> - remove_speculative()-> - cast_to_ptr_type(TypePtr::BotPTR)-> - cast_to_exactness(false)-> - with_offset(offset); + tj = ta = TypeAryPtr::BYTES; } }