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