1.1 --- a/src/share/vm/opto/callnode.cpp Thu Apr 02 10:49:41 2009 -0700 1.2 +++ b/src/share/vm/opto/callnode.cpp Fri Apr 03 13:33:32 2009 -0700 1.3 @@ -1043,6 +1043,51 @@ 1.4 //============================================================================= 1.5 uint AllocateArrayNode::size_of() const { return sizeof(*this); } 1.6 1.7 +Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.8 + if (remove_dead_region(phase, can_reshape)) return this; 1.9 + 1.10 + const Type* type = phase->type(Ideal_length()); 1.11 + if (type->isa_int() && type->is_int()->_hi < 0) { 1.12 + if (can_reshape) { 1.13 + PhaseIterGVN *igvn = phase->is_IterGVN(); 1.14 + // Unreachable fall through path (negative array length), 1.15 + // the allocation can only throw so disconnect it. 1.16 + Node* proj = proj_out(TypeFunc::Control); 1.17 + Node* catchproj = NULL; 1.18 + if (proj != NULL) { 1.19 + for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { 1.20 + Node *cn = proj->fast_out(i); 1.21 + if (cn->is_Catch()) { 1.22 + catchproj = cn->as_Multi()->proj_out(CatchProjNode::fall_through_index); 1.23 + break; 1.24 + } 1.25 + } 1.26 + } 1.27 + if (catchproj != NULL && catchproj->outcnt() > 0 && 1.28 + (catchproj->outcnt() > 1 || 1.29 + catchproj->unique_out()->Opcode() != Op_Halt)) { 1.30 + assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); 1.31 + Node* nproj = catchproj->clone(); 1.32 + igvn->register_new_node_with_optimizer(nproj); 1.33 + 1.34 + Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr ); 1.35 + frame = phase->transform(frame); 1.36 + // Halt & Catch Fire 1.37 + Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame ); 1.38 + phase->C->root()->add_req(halt); 1.39 + phase->transform(halt); 1.40 + 1.41 + igvn->replace_node(catchproj, phase->C->top()); 1.42 + return this; 1.43 + } 1.44 + } else { 1.45 + // Can't correct it during regular GVN so register for IGVN 1.46 + phase->C->record_for_igvn(this); 1.47 + } 1.48 + } 1.49 + return NULL; 1.50 +} 1.51 + 1.52 // Retrieve the length from the AllocateArrayNode. Narrow the type with a 1.53 // CastII, if appropriate. If we are not allowed to create new nodes, and 1.54 // a CastII is appropriate, return NULL.