diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 8d8839a0f22..1c4d96c6526 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -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; diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp index e57194fbf32..8ee5db302b2 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); + Node* inline_array_null_guard(Node* ary, Node* val, int nargs, bool safe_for_replace); 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 3c571d5e62b..1a3e69337ac 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -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);