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 {