src/share/vm/opto/callnode.cpp

changeset 1139
ad8c635e757e
parent 1036
523ded093c31
child 1279
bd02caa94611
child 1335
9987d9d5eb0e
     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.

mercurial