1.1 --- a/src/share/vm/opto/memnode.cpp Thu Mar 13 16:06:34 2008 -0700 1.2 +++ b/src/share/vm/opto/memnode.cpp Thu Mar 13 16:31:32 2008 -0700 1.3 @@ -87,6 +87,58 @@ 1.4 1.5 #endif 1.6 1.7 +static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st) { 1.8 + uint alias_idx = phase->C->get_alias_index(tp); 1.9 + Node *mem = mmem; 1.10 +#ifdef ASSERT 1.11 + { 1.12 + // Check that current type is consistent with the alias index used during graph construction 1.13 + assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); 1.14 + bool consistent = adr_check == NULL || adr_check->empty() || 1.15 + phase->C->must_alias(adr_check, alias_idx ); 1.16 + // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] 1.17 + if( !consistent && adr_check != NULL && !adr_check->empty() && 1.18 + tp->isa_aryptr() && tp->offset() == Type::OffsetBot && 1.19 + adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot && 1.20 + ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() || 1.21 + adr_check->offset() == oopDesc::klass_offset_in_bytes() || 1.22 + adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) { 1.23 + // don't assert if it is dead code. 1.24 + consistent = true; 1.25 + } 1.26 + if( !consistent ) { 1.27 + st->print("alias_idx==%d, adr_check==", alias_idx); 1.28 + if( adr_check == NULL ) { 1.29 + st->print("NULL"); 1.30 + } else { 1.31 + adr_check->dump(); 1.32 + } 1.33 + st->cr(); 1.34 + print_alias_types(); 1.35 + assert(consistent, "adr_check must match alias idx"); 1.36 + } 1.37 + } 1.38 +#endif 1.39 + // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally 1.40 + // means an array I have not precisely typed yet. Do not do any 1.41 + // alias stuff with it any time soon. 1.42 + const TypeOopPtr *tinst = tp->isa_oopptr(); 1.43 + if( tp->base() != Type::AnyPtr && 1.44 + !(tinst && 1.45 + tinst->klass()->is_java_lang_Object() && 1.46 + tinst->offset() == Type::OffsetBot) ) { 1.47 + // compress paths and change unreachable cycles to TOP 1.48 + // If not, we can update the input infinitely along a MergeMem cycle 1.49 + // Equivalent code in PhiNode::Ideal 1.50 + Node* m = phase->transform(mmem); 1.51 + // If tranformed to a MergeMem, get the desired slice 1.52 + // Otherwise the returned node represents memory for every slice 1.53 + mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; 1.54 + // Update input if it is progress over what we have now 1.55 + } 1.56 + return mem; 1.57 +} 1.58 + 1.59 //--------------------------Ideal_common--------------------------------------- 1.60 // Look for degenerate control and memory inputs. Bypass MergeMem inputs. 1.61 // Unhook non-raw memories from complete (macro-expanded) initializations. 1.62 @@ -119,48 +171,8 @@ 1.63 if (mem->is_MergeMem()) { 1.64 MergeMemNode* mmem = mem->as_MergeMem(); 1.65 const TypePtr *tp = t_adr->is_ptr(); 1.66 - uint alias_idx = phase->C->get_alias_index(tp); 1.67 -#ifdef ASSERT 1.68 - { 1.69 - // Check that current type is consistent with the alias index used during graph construction 1.70 - assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); 1.71 - const TypePtr *adr_t = adr_type(); 1.72 - bool consistent = adr_t == NULL || adr_t->empty() || phase->C->must_alias(adr_t, alias_idx ); 1.73 - // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] 1.74 - if( !consistent && adr_t != NULL && !adr_t->empty() && 1.75 - tp->isa_aryptr() && tp->offset() == Type::OffsetBot && 1.76 - adr_t->isa_aryptr() && adr_t->offset() != Type::OffsetBot && 1.77 - ( adr_t->offset() == arrayOopDesc::length_offset_in_bytes() || 1.78 - adr_t->offset() == oopDesc::klass_offset_in_bytes() || 1.79 - adr_t->offset() == oopDesc::mark_offset_in_bytes() ) ) { 1.80 - // don't assert if it is dead code. 1.81 - consistent = true; 1.82 - } 1.83 - if( !consistent ) { 1.84 - tty->print("alias_idx==%d, adr_type()==", alias_idx); if( adr_t == NULL ) { tty->print("NULL"); } else { adr_t->dump(); } 1.85 - tty->cr(); 1.86 - print_alias_types(); 1.87 - assert(consistent, "adr_type must match alias idx"); 1.88 - } 1.89 - } 1.90 -#endif 1.91 - // TypeInstPtr::NOTNULL+any is an OOP with unknown offset - generally 1.92 - // means an array I have not precisely typed yet. Do not do any 1.93 - // alias stuff with it any time soon. 1.94 - const TypeInstPtr *tinst = tp->isa_instptr(); 1.95 - if( tp->base() != Type::AnyPtr && 1.96 - !(tinst && 1.97 - tinst->klass()->is_java_lang_Object() && 1.98 - tinst->offset() == Type::OffsetBot) ) { 1.99 - // compress paths and change unreachable cycles to TOP 1.100 - // If not, we can update the input infinitely along a MergeMem cycle 1.101 - // Equivalent code in PhiNode::Ideal 1.102 - Node* m = phase->transform(mmem); 1.103 - // If tranformed to a MergeMem, get the desired slice 1.104 - // Otherwise the returned node represents memory for every slice 1.105 - mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; 1.106 - // Update input if it is progress over what we have now 1.107 - } 1.108 + 1.109 + mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty); 1.110 } 1.111 1.112 if (mem != old_mem) { 1.113 @@ -534,7 +546,10 @@ 1.114 const Node* call = adr->in(0); 1.115 if (call->is_CallStaticJava()) { 1.116 const CallStaticJavaNode* call_java = call->as_CallStaticJava(); 1.117 - assert(call_java && call_java->method() == NULL, "must be runtime call"); 1.118 + const TypeTuple *r = call_java->tf()->range(); 1.119 + assert(r->cnt() > TypeFunc::Parms, "must return value"); 1.120 + const Type* ret_type = r->field_at(TypeFunc::Parms); 1.121 + assert(ret_type && ret_type->isa_ptr(), "must return pointer"); 1.122 // We further presume that this is one of 1.123 // new_instance_Java, new_array_Java, or 1.124 // the like, but do not assert for this. 1.125 @@ -732,6 +747,21 @@ 1.126 return NULL; 1.127 } 1.128 1.129 +//----------------------is_instance_field_load_with_local_phi------------------ 1.130 +bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) { 1.131 + if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl && 1.132 + in(MemNode::Address)->is_AddP() ) { 1.133 + const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr(); 1.134 + // Only instances. 1.135 + if( t_oop != NULL && t_oop->is_instance_field() && 1.136 + t_oop->offset() != Type::OffsetBot && 1.137 + t_oop->offset() != Type::OffsetTop) { 1.138 + return true; 1.139 + } 1.140 + } 1.141 + return false; 1.142 +} 1.143 + 1.144 //------------------------------Identity--------------------------------------- 1.145 // Loads are identity if previous store is to same address 1.146 Node *LoadNode::Identity( PhaseTransform *phase ) { 1.147 @@ -754,6 +784,25 @@ 1.148 // usually runs first, producing the singleton type of the Con.) 1.149 return value; 1.150 } 1.151 + 1.152 + // Search for an existing data phi which was generated before for the same 1.153 + // instance's field to avoid infinite genertion of phis in a loop. 1.154 + Node *region = mem->in(0); 1.155 + if (is_instance_field_load_with_local_phi(region)) { 1.156 + const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); 1.157 + int this_index = phase->C->get_alias_index(addr_t); 1.158 + int this_offset = addr_t->offset(); 1.159 + int this_id = addr_t->is_oopptr()->instance_id(); 1.160 + const Type* this_type = bottom_type(); 1.161 + for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { 1.162 + Node* phi = region->fast_out(i); 1.163 + if (phi->is_Phi() && phi != mem && 1.164 + phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) { 1.165 + return phi; 1.166 + } 1.167 + } 1.168 + } 1.169 + 1.170 return this; 1.171 } 1.172 1.173 @@ -1189,6 +1238,17 @@ 1.174 return value->bottom_type(); 1.175 } 1.176 1.177 + const TypeOopPtr *tinst = tp->isa_oopptr(); 1.178 + if (tinst != NULL && tinst->is_instance_field()) { 1.179 + // If we have an instance type and our memory input is the 1.180 + // programs's initial memory state, there is no matching store, 1.181 + // so just return a zero of the appropriate type 1.182 + Node *mem = in(MemNode::Memory); 1.183 + if (mem->is_Parm() && mem->in(0)->is_Start()) { 1.184 + assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm"); 1.185 + return Type::get_zero_type(_type->basic_type()); 1.186 + } 1.187 + } 1.188 return _type; 1.189 } 1.190 1.191 @@ -1712,7 +1772,7 @@ 1.192 const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr(); 1.193 if (adr_oop == NULL) 1.194 return false; 1.195 - if (!adr_oop->is_instance()) 1.196 + if (!adr_oop->is_instance_field()) 1.197 return false; // if not a distinct instance, there may be aliases of the address 1.198 for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) { 1.199 Node *use = adr->fast_out(i); 1.200 @@ -3244,7 +3304,7 @@ 1.201 } 1.202 } 1.203 1.204 - assert(verify_sparse(), "please, no dups of base"); 1.205 + assert(progress || verify_sparse(), "please, no dups of base"); 1.206 return progress; 1.207 } 1.208