diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index b4b519e4298..babd84a0097 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -5006,7 +5006,14 @@ bool LibraryCallKit::inline_getArrayProperties(ArrayPropertiesCheck check) { // '_next_refined_array_klass' linked list being the default (see ObjArrayKlass::klass_with_properties). Node* LibraryCallKit::load_default_refined_array_klass(Node* klass_node, bool type_array_guard) { RegionNode* region = new RegionNode(2); - Node* phi = new PhiNode(region, TypeInstKlassPtr::OBJECT_OR_NULL); + const TypeAryKlassPtr* load_type = TypeAryKlassPtr::OBJECT_ARRAY_OR_NULL; + const TypeKlassPtr* phi_type; + if (type_array_guard) { + phi_type = TypeInstKlassPtr::OBJECT_OR_NULL; // Use very general type for Phi + } else { + phi_type = load_type; + } + Node* phi = new PhiNode(region, phi_type); if (type_array_guard) { generate_typeArray_guard(klass_node, region); @@ -5015,7 +5022,7 @@ Node* LibraryCallKit::load_default_refined_array_klass(Node* klass_node, bool ty } } Node* adr_refined_klass = basic_plus_adr(top(), klass_node, in_bytes(ObjArrayKlass::next_refined_array_klass_offset())); - Node* refined_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), adr_refined_klass, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); + Node* refined_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), adr_refined_klass, TypeRawPtr::BOTTOM, load_type)); // Can be null if not initialized yet, just deopt Node* null_ctl = top(); @@ -5043,7 +5050,7 @@ Node* LibraryCallKit::load_non_refined_array_klass(Node* klass_node) { phi->add_req(klass_node); } Node* super_adr = basic_plus_adr(top(), klass_node, in_bytes(Klass::super_offset())); - Node* super_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), super_adr, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT)); + Node* super_klass = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), super_adr, TypeRawPtr::BOTTOM, TypeAryKlassPtr::OBJECT_ARRAY)); region->init_req(1, control()); phi->init_req(1, super_klass); @@ -5209,18 +5216,20 @@ bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { klass_node = null_check(klass_node); const TypeAryPtr* src_t = _gvn.type(original)->is_aryptr(); - const TypeKlassPtr* dest_klass_t = _gvn.type(klass_node)->is_klassptr()->is_klassptr(); + const TypeKlassPtr* dest_klass_t = _gvn.type(klass_node)->is_klassptr(); - Node* success_proj; + Node* bailout_ctrl; if (should_bail_out_on_non_ref_arrays(src_t, dest_klass_t)) { - success_proj = generate_non_refArray_guard(klass_node, bailout); + bailout_ctrl = generate_non_refArray_guard(klass_node, bailout); } else { - success_proj = generate_typeArray_guard(klass_node, bailout); + bailout_ctrl = generate_typeArray_guard(klass_node, bailout); } Node* refined_klass_node = load_default_refined_array_klass(klass_node, /* type_array_guard= */ false); - if (success_proj != nullptr) { + // The current path is dead if the default refined array klass is not initialized, + // yet, or the guard is always taken (i.e. bailout). + if (!stopped() && (bailout_ctrl != nullptr)) { // Improve the klass node's type from the new optimistic assumption: ciKlass* ak = ciArrayKlass::make(env()->Object_klass()); bool not_flat = !UseArrayFlattening; diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index a84418075d4..09a4237ab0b 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -731,6 +731,9 @@ void Type::Initialize_shared(Compile* current) { TypeInstKlassPtr::OBJECT = TypeInstKlassPtr::make(TypePtr::NotNull, current->env()->Object_klass(), Offset(0)); TypeInstKlassPtr::OBJECT_OR_NULL = TypeInstKlassPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), Offset(0)); + TypeAryKlassPtr::OBJECT_ARRAY = TypeAryKlassPtr::make(TypePtr::NotNull, TypeInstKlassPtr::OBJECT, nullptr, Offset(0), false, false, false, false, false, false); + TypeAryKlassPtr::OBJECT_ARRAY_OR_NULL = TypeAryKlassPtr::make(TypePtr::BotPTR, TypeInstKlassPtr::OBJECT, nullptr, Offset(0), false, false, false, false, false, false); + const Type **fi2c = TypeTuple::fields(2); fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method* fi2c[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // argument pointer @@ -6743,6 +6746,12 @@ void TypeInstKlassPtr::dump2(Dict& d, uint depth, outputStream* st) const { } #endif // PRODUCT +//============================================================================= +// Convenience common pre-built types. + +const TypeAryKlassPtr* TypeAryKlassPtr::OBJECT_ARRAY; // Not-null object array klass +const TypeAryKlassPtr* TypeAryKlassPtr::OBJECT_ARRAY_OR_NULL; // Maybe-null object array klass + bool TypeAryKlassPtr::can_be_inline_array() const { return _elem->isa_instklassptr() && _elem->is_instklassptr()->_klass->can_be_inline_klass(); } diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index 0ad9938aaea..03a641bee87 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -2230,6 +2230,10 @@ public: bool is_refined_type() const { return _refined_type; } virtual bool can_be_inline_array() const; + // Convenience common pre-built types. + static const TypeAryKlassPtr* OBJECT_ARRAY; // Not-null object array klass + static const TypeAryKlassPtr* OBJECT_ARRAY_OR_NULL; // Maybe-null object array klass + #ifndef PRODUCT virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping #endif