8377652: C2: Simplify Compile::flatten_alias_type for array

Reviewed-by: roland, mhaessig
This commit is contained in:
Quan Anh Mai 2026-02-23 09:36:31 +00:00
parent 0f70a9a924
commit 2a9d144f26

View File

@ -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;
}
}