1.1 --- a/src/share/vm/opto/callnode.cpp Thu Mar 20 13:51:55 2008 -0700 1.2 +++ b/src/share/vm/opto/callnode.cpp Thu Mar 20 15:11:44 2008 -0700 1.3 @@ -625,8 +625,8 @@ 1.4 } 1.5 1.6 // 1.7 -// Determine whether the call could modify a memory value of the 1.8 -// specified address type 1.9 +// Determine whether the call could modify the field of the specified 1.10 +// instance at the specified offset. 1.11 // 1.12 bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) { 1.13 const TypeOopPtr *adrInst_t = addr_t->isa_oopptr(); 1.14 @@ -638,9 +638,24 @@ 1.15 Compile *C = phase->C; 1.16 int offset = adrInst_t->offset(); 1.17 assert(offset >= 0, "should be valid offset"); 1.18 - assert(addr_t->isa_instptr() || addr_t->isa_aryptr(), "only instances or arrays are expected"); 1.19 + ciKlass* adr_k = adrInst_t->klass(); 1.20 + assert(adr_k->is_loaded() && 1.21 + adr_k->is_java_klass() && 1.22 + !adr_k->is_interface(), 1.23 + "only non-abstract classes are expected"); 1.24 1.25 int base_idx = C->get_alias_index(adrInst_t); 1.26 + int size = BytesPerLong; // If we don't know the size, assume largest. 1.27 + if (adrInst_t->isa_instptr()) { 1.28 + ciField* field = C->alias_type(base_idx)->field(); 1.29 + if (field != NULL) { 1.30 + size = field->size_in_bytes(); 1.31 + } 1.32 + } else { 1.33 + assert(adrInst_t->isa_aryptr(), "only arrays are expected"); 1.34 + size = type2aelembytes(adr_k->as_array_klass()->element_type()->basic_type()); 1.35 + } 1.36 + 1.37 ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL; 1.38 BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL; 1.39 1.40 @@ -656,14 +671,19 @@ 1.41 if (!arg->is_top() && (t->isa_oopptr() != NULL || 1.42 t->isa_ptr() && at_ptr != NULL)) { 1.43 assert(at_ptr != NULL, "expecting an OopPtr"); 1.44 - // If we have found an argument matching adr_base_t, check if the field 1.45 - // at the specified offset is modified. Since we don't know the size, 1.46 - // assume 8. 1.47 - int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr()); 1.48 - if (base_idx == at_idx && 1.49 - (bcea == NULL || 1.50 - bcea->is_arg_modified(i - TypeFunc::Parms, offset, 8))) { 1.51 - return true; 1.52 + ciKlass* at_k = at_ptr->klass(); 1.53 + if ((adrInst_t->base() == at_ptr->base()) && 1.54 + at_k->is_loaded() && 1.55 + at_k->is_java_klass() && 1.56 + !at_k->is_interface()) { 1.57 + // If we have found an argument matching addr_t, check if the field 1.58 + // at the specified offset is modified. 1.59 + int at_idx = C->get_alias_index(at_ptr->add_offset(offset)->isa_oopptr()); 1.60 + if (base_idx == at_idx && 1.61 + (bcea == NULL || 1.62 + bcea->is_arg_modified(i - TypeFunc::Parms, offset, size))) { 1.63 + return true; 1.64 + } 1.65 } 1.66 } 1.67 }