diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 1c4d96c6526..3aeef8e552c 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -4021,7 +4021,9 @@ 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, bool safe_for_replace) { +// Return `ary` as nullable if `val` is statically known to be null. Beware +// it will also replace_in_map `ary` with the casted version. +Node* GraphKit::inline_array_null_guard(Node* ary, Node* val, int nargs) { RegionNode* region = new RegionNode(3); Node* null_ctl = top(); null_check_oop(val, &null_ctl); @@ -4045,9 +4047,7 @@ Node* GraphKit::inline_array_null_guard(Node* ary, Node* val, int nargs, bool sa 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)); - if (safe_for_replace) { - replace_in_map(ary, cast); - } + replace_in_map(ary, cast); ary = cast; } return ary; diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp index 8ee5db302b2..e57194fbf32 100644 --- a/src/hotspot/share/opto/graphKit.hpp +++ b/src/hotspot/share/opto/graphKit.hpp @@ -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, bool safe_for_replace); + Node* inline_array_null_guard(Node* ary, Node* val, int nargs); Node* gen_subtype_check(Node* obj, Node* superklass); diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 1a3e69337ac..bf01eec2c79 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -253,41 +253,24 @@ 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"); - // 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() // 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, true); - array_type = _gvn.type(array)->is_aryptr(); - } + // 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. + array = inline_array_null_guard(array, stored_value_casted, 3); // Reload array type which could have been updated by inline_array_null_guard(). + array_type = _gvn.type(array)->is_aryptr(); IdealKit ideal(this); ideal.if_then(flat_array_test(array, /* flat = */ false)); { // 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, 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); } } ideal.else_(); { // Flat array sync_kit(ideal); - // Either array can be null-free and flat, and inline_array_null_guard is done above, or it cannot, and we don't need to perform this check. if (!array_type->is_not_flat()) { // Try to determine the inline klass type of the stored value ciInlineKlass* vk = nullptr; @@ -325,7 +308,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, true); + array = inline_array_null_guard(array, stored_value_casted, 3); } } inc_sp(3);