< prev index next >

src/share/vm/opto/cfgnode.cpp

Print this page
rev 11702 : 8161652: Crash with assert(ft == _type) failed in PhiNode::Value()
Summary: PhiNode::Ideal() unique input logic creates CheckCastPP for null input
Reviewed-by:
rev 11703 : review

*** 1701,1733 **** } } } if (uncasted) { ! // Add a cast node 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. if (phi_type->isa_int()) { ! opcode = Op_CastII; } 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; } else { ! opcode = Op_CheckCastPP; ! } } ! // 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); cast = phase->transform(cast); ! // set all inputs to the new cast 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); } uin = cast; --- 1701,1754 ---- } } } if (uncasted) { ! // 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"); ! // Add casts to carry the control dependency of the Phi that is ! // going away ! Node* cast = NULL; if (phi_type->isa_int()) { ! cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true); } else { const Type* uin_type = phase->type(uin); ! if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) { ! cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true); } else { ! // 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); ! } ! } ! } ! assert(cast != NULL, "cast should be set"); ! // 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); } uin = cast;
< prev index next >