src/share/vm/opto/callnode.cpp

changeset 500
99269dbf4ba8
parent 498
eac007780a58
child 501
6dbf1a175d6b
     1.1 --- a/src/share/vm/opto/callnode.cpp	Thu Mar 13 16:31:32 2008 -0700
     1.2 +++ b/src/share/vm/opto/callnode.cpp	Fri Mar 14 15:26:33 2008 -0700
     1.3 @@ -624,6 +624,87 @@
     1.4    return 0;
     1.5  }
     1.6  
     1.7 +//
     1.8 +// Determine whether the call could modify a memory value  of the
     1.9 +// specified address type
    1.10 +//
    1.11 +bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
    1.12 +  const TypeOopPtr *adrInst_t  = addr_t->isa_oopptr();
    1.13 +
    1.14 +  // if not an InstPtr or not an instance type, assume the worst
    1.15 +  if (adrInst_t == NULL || !adrInst_t->is_instance_field()) {
    1.16 +    return true;
    1.17 +  }
    1.18 +  Compile *C = phase->C;
    1.19 +  int offset = adrInst_t->offset();
    1.20 +  assert(offset >= 0, "should be valid offset");
    1.21 +  assert(addr_t->isa_instptr() || addr_t->isa_aryptr(), "only instances or arrays are expected");
    1.22 +
    1.23 +  int base_idx = C->get_alias_index(adrInst_t);
    1.24 +  ciMethod * meth = is_CallStaticJava() ?  as_CallStaticJava()->method() : NULL;
    1.25 +  BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL;
    1.26 +
    1.27 +  const TypeTuple * d = tf()->domain();
    1.28 +  for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
    1.29 +    const Type* t = d->field_at(i);
    1.30 +    Node *arg = in(i);
    1.31 +    const Type *at = phase->type(arg);
    1.32 +    if (at == TypePtr::NULL_PTR || at == Type::TOP)
    1.33 +      continue;  // null can't affect anything
    1.34 +
    1.35 +    const TypeOopPtr *at_ptr = at->isa_oopptr();
    1.36 +    if (!arg->is_top() && (t->isa_oopptr() != NULL ||
    1.37 +                           t->isa_ptr() && at_ptr != NULL)) {
    1.38 +      assert(at_ptr != NULL, "expecting an OopPtr");
    1.39 +      // If we have found an argument matching adr_base_t, check if the field
    1.40 +      // at the specified offset is modified.  Since we don't know the size,
    1.41 +      // assume 8.
    1.42 +      int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr());
    1.43 +      if (base_idx == at_idx &&
    1.44 +          (bcea == NULL ||
    1.45 +           bcea->is_arg_modified(i - TypeFunc::Parms, offset, 8))) {
    1.46 +        return true;
    1.47 +      }
    1.48 +    }
    1.49 +  }
    1.50 +  return false;
    1.51 +}
    1.52 +
    1.53 +// Does this call have a direct reference to n other than debug information?
    1.54 +bool CallNode::has_non_debug_use(Node *n) {
    1.55 +  const TypeTuple * d = tf()->domain();
    1.56 +  for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
    1.57 +    Node *arg = in(i);
    1.58 +    if (arg == n) {
    1.59 +      return true;
    1.60 +    }
    1.61 +  }
    1.62 +  return false;
    1.63 +}
    1.64 +
    1.65 +// Returns the unique CheckCastPP of a call
    1.66 +// or 'this' if there are several CheckCastPP
    1.67 +// or returns NULL if there is no one.
    1.68 +Node *CallNode::result_cast() {
    1.69 +  Node *cast = NULL;
    1.70 +
    1.71 +  Node *p = proj_out(TypeFunc::Parms);
    1.72 +  if (p == NULL)
    1.73 +    return NULL;
    1.74 +
    1.75 +  for (DUIterator_Fast imax, i = p->fast_outs(imax); i < imax; i++) {
    1.76 +    Node *use = p->fast_out(i);
    1.77 +    if (use->is_CheckCastPP()) {
    1.78 +      if (cast != NULL) {
    1.79 +        return this;  // more than 1 CheckCastPP
    1.80 +      }
    1.81 +      cast = use;
    1.82 +    }
    1.83 +  }
    1.84 +  return cast;
    1.85 +}
    1.86 +
    1.87 +
    1.88  //=============================================================================
    1.89  uint CallJavaNode::size_of() const { return sizeof(*this); }
    1.90  uint CallJavaNode::cmp( const Node &n ) const {

mercurial