Mercurial > hg > truffle
comparison src/share/vm/opto/callnode.cpp @ 704:ad8c635e757e
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
Summary: Use a HaltNode on the fall through path of the AllocateArrayNode to indicate that it is unreachable if the array length is negative.
Reviewed-by: never, jrose
author | kvn |
---|---|
date | Fri, 03 Apr 2009 13:33:32 -0700 |
parents | 523ded093c31 |
children | bd02caa94611 9987d9d5eb0e |
comparison
equal
deleted
inserted
replaced
685:4e35bfab60a5 | 704:ad8c635e757e |
---|---|
1041 } | 1041 } |
1042 | 1042 |
1043 //============================================================================= | 1043 //============================================================================= |
1044 uint AllocateArrayNode::size_of() const { return sizeof(*this); } | 1044 uint AllocateArrayNode::size_of() const { return sizeof(*this); } |
1045 | 1045 |
1046 Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1047 if (remove_dead_region(phase, can_reshape)) return this; | |
1048 | |
1049 const Type* type = phase->type(Ideal_length()); | |
1050 if (type->isa_int() && type->is_int()->_hi < 0) { | |
1051 if (can_reshape) { | |
1052 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
1053 // Unreachable fall through path (negative array length), | |
1054 // the allocation can only throw so disconnect it. | |
1055 Node* proj = proj_out(TypeFunc::Control); | |
1056 Node* catchproj = NULL; | |
1057 if (proj != NULL) { | |
1058 for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { | |
1059 Node *cn = proj->fast_out(i); | |
1060 if (cn->is_Catch()) { | |
1061 catchproj = cn->as_Multi()->proj_out(CatchProjNode::fall_through_index); | |
1062 break; | |
1063 } | |
1064 } | |
1065 } | |
1066 if (catchproj != NULL && catchproj->outcnt() > 0 && | |
1067 (catchproj->outcnt() > 1 || | |
1068 catchproj->unique_out()->Opcode() != Op_Halt)) { | |
1069 assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); | |
1070 Node* nproj = catchproj->clone(); | |
1071 igvn->register_new_node_with_optimizer(nproj); | |
1072 | |
1073 Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr ); | |
1074 frame = phase->transform(frame); | |
1075 // Halt & Catch Fire | |
1076 Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame ); | |
1077 phase->C->root()->add_req(halt); | |
1078 phase->transform(halt); | |
1079 | |
1080 igvn->replace_node(catchproj, phase->C->top()); | |
1081 return this; | |
1082 } | |
1083 } else { | |
1084 // Can't correct it during regular GVN so register for IGVN | |
1085 phase->C->record_for_igvn(this); | |
1086 } | |
1087 } | |
1088 return NULL; | |
1089 } | |
1090 | |
1046 // Retrieve the length from the AllocateArrayNode. Narrow the type with a | 1091 // Retrieve the length from the AllocateArrayNode. Narrow the type with a |
1047 // CastII, if appropriate. If we are not allowed to create new nodes, and | 1092 // CastII, if appropriate. If we are not allowed to create new nodes, and |
1048 // a CastII is appropriate, return NULL. | 1093 // a CastII is appropriate, return NULL. |
1049 Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTransform *phase, bool allow_new_nodes) { | 1094 Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseTransform *phase, bool allow_new_nodes) { |
1050 Node *length = in(AllocateNode::ALength); | 1095 Node *length = in(AllocateNode::ALength); |