From d9e45ac1aca1f6a13889b7962c1807afbd95078c Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Sat, 30 Jul 2016 04:05:28 -0700 Subject: [PATCH 1/2] 8161652: Crash with assert(ft == _type) failed in PhiNode::Value() Use CastPP and CheckCastPP when NotNull and klass have to be casted on Phi with unique input. Reviewed-by: kvn --- hotspot/src/share/vm/opto/cfgnode.cpp | 46 ++++++++++++++++++++------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp index 594ffd2e70a..47606b6a599 100644 --- a/hotspot/src/share/vm/opto/cfgnode.cpp +++ b/hotspot/src/share/vm/opto/cfgnode.cpp @@ -1703,29 +1703,51 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { } if (uncasted) { - // Add a cast node between the phi to be removed and its unique input. + // Add cast nodes between the phi to be removed and its unique input. // Wait until after parsing for the type information to propagate from the casts. assert(can_reshape, "Invalid during parsing"); const Type* phi_type = bottom_type(); assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type"); - int opcode; - // Determine the type of cast to be added. + // Add casts to carry the control dependency of the Phi that is + // going away + Node* cast = NULL; if (phi_type->isa_int()) { - opcode = Op_CastII; + cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true); } else { const Type* uin_type = phase->type(uin); - if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) || - (!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) { - opcode = Op_CastPP; + if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); } else { - opcode = Op_CheckCastPP; + // Use a CastPP for a cast to not null and a CheckCastPP for + // a cast to a new klass (and both if both null-ness and + // klass change). + + // If the type of phi is not null but the type of uin may be + // null, uin's type must be casted to not null + if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() && + uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true); + } + + // If the type of phi and uin, both casted to not null, + // differ the klass of uin must be (check)cast'ed to match + // that of phi + if (phi_type->join_speculative(TypePtr::NOTNULL) != uin_type->join_speculative(TypePtr::NOTNULL)) { + Node* n = uin; + if (cast != NULL) { + cast = phase->transform(cast); + n = cast; + } + cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true); + } + if (cast == NULL) { + cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); + } } } - // Add a cast to carry the control dependency of the Phi that is - // going away - Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true); + assert(cast != NULL, "cast should be set"); cast = phase->transform(cast); - // set all inputs to the new cast so the Phi is removed by Identity + // set all inputs to the new cast(s) so the Phi is removed by Identity PhaseIterGVN* igvn = phase->is_IterGVN(); for (uint i = 1; i < req(); i++) { set_req_X(i, cast, igvn); From 1c6137737503ba39ba0c9d8002b472ee1bfdfa1b Mon Sep 17 00:00:00 2001 From: Dean Long Date: Tue, 2 Aug 2016 11:06:25 -0700 Subject: [PATCH 2/2] 8029441: assert(!((nmethod*)_cb)->is_deopt_pc(_pc)) failed: invariant broken Move patchable check into patch_pc Reviewed-by: dcubed --- hotspot/src/cpu/sparc/vm/frame_sparc.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp index ab6aeeeeabf..de731a39e67 100644 --- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp @@ -357,12 +357,6 @@ void frame::init(intptr_t* sp, address pc, CodeBlob* cb) { _cb = CodeCache::find_blob(_pc); } _deopt_state = unknown; -#ifdef ASSERT - if ( _cb != NULL && _cb->is_compiled()) { - // Without a valid unextended_sp() we can't convert the pc to "original" - assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken"); - } -#endif // ASSERT } frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) { @@ -534,6 +528,7 @@ frame frame::sender(RegisterMap* map) const { void frame::patch_pc(Thread* thread, address pc) { + vmassert(_deopt_state != unknown, "frame is unpatchable"); if(thread == Thread::current()) { StubRoutines::Sparc::flush_callers_register_windows_func()(); }