Do it fully

This commit is contained in:
Marc Chevalier 2026-07-16 13:20:37 +02:00
parent 145eb524c8
commit a1f22fd38c
3 changed files with 21 additions and 11 deletions

View File

@ -4021,7 +4021,7 @@ Node* GraphKit::atomic_layout_array_test_and_get_layout_kind(Node* array, Region
}
// Deoptimize if 'ary' is a null-free inline type array and 'val' is null
Node* GraphKit::inline_array_null_guard(Node* ary, Node* val, int nargs) {
Node* GraphKit::inline_array_null_guard(Node* ary, Node* val, int nargs, bool safe_for_replace) {
RegionNode* region = new RegionNode(3);
Node* null_ctl = top();
null_check_oop(val, &null_ctl);
@ -4045,7 +4045,9 @@ Node* GraphKit::inline_array_null_guard(Node* ary, Node* val, int nargs) {
const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
ary_t = ary_t->cast_to_not_null_free();
Node* cast = _gvn.transform(new CheckCastPPNode(control(), ary, ary_t));
replace_in_map(ary, cast);
if (safe_for_replace) {
replace_in_map(ary, cast);
}
ary = cast;
}
return ary;

View File

@ -842,7 +842,7 @@ class GraphKit : public Phase {
Node* null_free_array_test(Node* array, bool null_free = true);
Node* null_free_atomic_array_test(Node* array, ciInlineKlass* vk);
Node* atomic_layout_array_test_and_get_layout_kind(Node* array, RegionNode* atomic_region);
Node* inline_array_null_guard(Node* ary, Node* val, int nargs);
Node* inline_array_null_guard(Node* ary, Node* val, int nargs, bool safe_for_replace);
Node* gen_subtype_check(Node* obj, Node* superklass);

View File

@ -253,11 +253,17 @@ void Parse::array_store(BasicType bt) {
// Array might be a flat array, emit runtime checks (for null, a simple inline_array_null_guard is sufficient).
assert(UseArrayFlattening && !not_flat && elemtype->is_oopptr()->can_be_inline_type() &&
(!array_type->klass_is_exact() || array_type->is_flat()), "array can't be a flat array");
// TODO 8350865 Depending on the available layouts, we can avoid this check in below flat/not-flat branches. Also the safe_for_replace arg is now always true.
// If the array cannot be flat and null-free, we don't need to do inline_array_null_guard
// in the flat branch under. In this case, the flat branch is thus a bit faster, but the
// non-flat branch always need to be protected. If the array can be both flat and null-free,
// we just do the inline_array_null_guard guard the flat/non-flat branching so we don't
// duplicate it.
bool can_be_flat_and_null_free =
elemtype->is_inlinetypeptr() && (elemtype->inline_klass()->has_null_free_atomic_layout() || elemtype->inline_klass()->has_null_free_non_atomic_layout());
!elemtype->is_inlinetypeptr() // Can't tell statically whether it's possible, so we must soundly assume so
|| elemtype->inline_klass()->has_null_free_atomic_layout()
|| elemtype->inline_klass()->has_null_free_non_atomic_layout();
if (can_be_flat_and_null_free) {
array = inline_array_null_guard(array, stored_value_casted, 3);
array = inline_array_null_guard(array, stored_value_casted, 3, true);
array_type = _gvn.type(array)->is_aryptr();
}
// Reload array type which could have been updated by inline_array_null_guard().
@ -266,13 +272,15 @@ void Parse::array_store(BasicType bt) {
// Non-flat array
if (!array_type->is_flat()) {
sync_kit(ideal);
Node* array_ = array;
const TypeAryPtr* array_type_ = array_type;
if (!can_be_flat_and_null_free) {
array = inline_array_null_guard(array, stored_value_casted, 3);
array_type = _gvn.type(array)->is_aryptr();
array_ = inline_array_null_guard(array_, stored_value_casted, 3, false);
array_type_ = _gvn.type(array_)->is_aryptr();
}
assert(array_type->is_not_flat() || ideal.ctrl()->in(0)->as_If()->is_flat_array_check(&_gvn), "Should be found");
assert(array_type_->is_not_flat() || ideal.ctrl()->in(0)->as_If()->is_flat_array_check(&_gvn), "Should be found");
inc_sp(3);
access_store_at(array, adr, adr_type, stored_value_casted, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY, false);
access_store_at(array_, adr, adr_type, stored_value_casted, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY, false);
dec_sp(3);
ideal.sync_kit(this);
}
@ -317,7 +325,7 @@ void Parse::array_store(BasicType bt) {
} else if (!array_type->is_not_null_free()) {
// Array is not flat but may be null free
assert(elemtype->is_oopptr()->can_be_inline_type(), "array can't be null-free");
array = inline_array_null_guard(array, stored_value_casted, 3);
array = inline_array_null_guard(array, stored_value_casted, 3, true);
}
}
inc_sp(3);