< 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 >