< prev index next >

src/hotspot/share/opto/arraycopynode.cpp

Print this page




 165   Node* base_src = src->in(AddPNode::Base);
 166   Node* base_dest = dest->in(AddPNode::Base);
 167 
 168   MergeMemNode* mem = MergeMemNode::make(in_mem);
 169 
 170   const TypeInstPtr* inst_src = src_type->isa_instptr();
 171 
 172   if (inst_src == NULL) {
 173     return NULL;
 174   }
 175 
 176   if (!inst_src->klass_is_exact()) {
 177     ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 178     assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
 179     phase->C->dependencies()->assert_leaf_type(ik);
 180   }
 181 
 182   ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 183   assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
 184 

 185   for (int i = 0; i < count; i++) {
 186     ciField* field = ik->nonstatic_field_at(i);
 187     int fieldidx = phase->C->alias_type(field)->index();
 188     const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
 189     Node* off = phase->MakeConX(field->offset());
 190     Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
 191     Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
 192     BasicType bt = field->layout_type();
 193 
 194     const Type *type;
 195     if (bt == T_OBJECT) {
 196       if (!field->type()->is_loaded()) {
 197         type = TypeInstPtr::BOTTOM;
 198       } else {
 199         ciType* field_klass = field->type();
 200         type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 201       }
 202     } else {
 203       type = Type::get_const_basic_type(bt);
 204     }
 205 
 206     Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
 207     v = phase->transform(v);



 208     Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
 209     s = phase->transform(s);
 210     mem->set_memory_at(fieldidx, s);
 211   }
 212 
 213   if (!finish_transform(phase, can_reshape, ctl, mem)) {
 214     // Return NodeSentinel to indicate that the transform failed
 215     return NodeSentinel;
 216   }
 217 
 218   return mem;
 219 }
 220 
 221 bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape,
 222                                        Node*& adr_src,
 223                                        Node*& base_src,
 224                                        Node*& adr_dest,
 225                                        Node*& base_dest,
 226                                        BasicType& copy_type,
 227                                        const Type*& value_type,


 359                                         const TypePtr* atp_src,
 360                                         const TypePtr* atp_dest,
 361                                         Node* adr_src,
 362                                         Node* base_src,
 363                                         Node* adr_dest,
 364                                         Node* base_dest,
 365                                         BasicType copy_type,
 366                                         const Type* value_type,
 367                                         int count) {
 368   if (!forward_ctl->is_top()) {
 369     // copy forward
 370     mm = mm->clone()->as_MergeMem();
 371     uint alias_idx_src = phase->C->get_alias_index(atp_src);
 372     uint alias_idx_dest = phase->C->get_alias_index(atp_dest);
 373     Node *start_mem_src = mm->memory_at(alias_idx_src);
 374     Node *start_mem_dest = mm->memory_at(alias_idx_dest);
 375     Node* mem = start_mem_dest;
 376     bool same_alias = (alias_idx_src == alias_idx_dest);
 377 
 378     if (count > 0) {

 379       Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 380       v = phase->transform(v);



 381       mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 382       mem = phase->transform(mem);
 383       for (int i = 1; i < count; i++) {
 384         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 385         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 386         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 387         v = LoadNode::make(*phase, forward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 388         v = phase->transform(v);



 389         mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 390         mem = phase->transform(mem);
 391       }
 392       mm->set_memory_at(alias_idx_dest, mem);
 393     } else if(can_reshape) {
 394       PhaseIterGVN* igvn = phase->is_IterGVN();
 395       igvn->_worklist.push(adr_src);
 396       igvn->_worklist.push(adr_dest);
 397     }
 398     return mm;
 399   }
 400   return phase->C->top();
 401 }
 402 
 403 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
 404                                          bool can_reshape,
 405                                          Node*& backward_ctl,
 406                                          MergeMemNode* mm,
 407                                          const TypePtr* atp_src,
 408                                          const TypePtr* atp_dest,


 416   if (!backward_ctl->is_top()) {
 417     // copy backward
 418     mm = mm->clone()->as_MergeMem();
 419     uint alias_idx_src = phase->C->get_alias_index(atp_src);
 420     uint alias_idx_dest = phase->C->get_alias_index(atp_dest);
 421     Node *start_mem_src = mm->memory_at(alias_idx_src);
 422     Node *start_mem_dest = mm->memory_at(alias_idx_dest);
 423     Node* mem = start_mem_dest;
 424 
 425     BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
 426     assert(copy_type != T_OBJECT || !bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, BarrierSetC2::Optimization), "only tightly coupled allocations for object arrays");
 427     bool same_alias = (alias_idx_src == alias_idx_dest);
 428 
 429     if (count > 0) {
 430       for (int i = count-1; i >= 1; i--) {
 431         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 432         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 433         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 434         Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 435         v = phase->transform(v);



 436         mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 437         mem = phase->transform(mem);
 438       }
 439       Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 440       v = phase->transform(v);



 441       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 442       mem = phase->transform(mem);
 443       mm->set_memory_at(alias_idx_dest, mem);
 444     } else if(can_reshape) {
 445       PhaseIterGVN* igvn = phase->is_IterGVN();
 446       igvn->_worklist.push(adr_src);
 447       igvn->_worklist.push(adr_dest);
 448     }
 449     return phase->transform(mm);
 450   }
 451   return phase->C->top();
 452 }
 453 
 454 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
 455                                      Node* ctl, Node *mem) {
 456   if (can_reshape) {
 457     PhaseIterGVN* igvn = phase->is_IterGVN();
 458     igvn->set_delay_transform(false);
 459     if (is_clonebasic()) {
 460       Node* out_mem = proj_out(TypeFunc::Memory);




 165   Node* base_src = src->in(AddPNode::Base);
 166   Node* base_dest = dest->in(AddPNode::Base);
 167 
 168   MergeMemNode* mem = MergeMemNode::make(in_mem);
 169 
 170   const TypeInstPtr* inst_src = src_type->isa_instptr();
 171 
 172   if (inst_src == NULL) {
 173     return NULL;
 174   }
 175 
 176   if (!inst_src->klass_is_exact()) {
 177     ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 178     assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
 179     phase->C->dependencies()->assert_leaf_type(ik);
 180   }
 181 
 182   ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 183   assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
 184 
 185   BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
 186   for (int i = 0; i < count; i++) {
 187     ciField* field = ik->nonstatic_field_at(i);
 188     int fieldidx = phase->C->alias_type(field)->index();
 189     const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
 190     Node* off = phase->MakeConX(field->offset());
 191     Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
 192     Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
 193     BasicType bt = field->layout_type();
 194 
 195     const Type *type;
 196     if (bt == T_OBJECT) {
 197       if (!field->type()->is_loaded()) {
 198         type = TypeInstPtr::BOTTOM;
 199       } else {
 200         ciType* field_klass = field->type();
 201         type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 202       }
 203     } else {
 204       type = Type::get_const_basic_type(bt);
 205     }
 206 
 207     Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
 208     v = phase->transform(v);
 209     if (bt == T_OBJECT) {
 210       v = bs->array_copy_load_store_barrier(phase, can_reshape, v, mem, ctl);
 211     }
 212     Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
 213     s = phase->transform(s);
 214     mem->set_memory_at(fieldidx, s);
 215   }
 216 
 217   if (!finish_transform(phase, can_reshape, ctl, mem)) {
 218     // Return NodeSentinel to indicate that the transform failed
 219     return NodeSentinel;
 220   }
 221 
 222   return mem;
 223 }
 224 
 225 bool ArrayCopyNode::prepare_array_copy(PhaseGVN *phase, bool can_reshape,
 226                                        Node*& adr_src,
 227                                        Node*& base_src,
 228                                        Node*& adr_dest,
 229                                        Node*& base_dest,
 230                                        BasicType& copy_type,
 231                                        const Type*& value_type,


 363                                         const TypePtr* atp_src,
 364                                         const TypePtr* atp_dest,
 365                                         Node* adr_src,
 366                                         Node* base_src,
 367                                         Node* adr_dest,
 368                                         Node* base_dest,
 369                                         BasicType copy_type,
 370                                         const Type* value_type,
 371                                         int count) {
 372   if (!forward_ctl->is_top()) {
 373     // copy forward
 374     mm = mm->clone()->as_MergeMem();
 375     uint alias_idx_src = phase->C->get_alias_index(atp_src);
 376     uint alias_idx_dest = phase->C->get_alias_index(atp_dest);
 377     Node *start_mem_src = mm->memory_at(alias_idx_src);
 378     Node *start_mem_dest = mm->memory_at(alias_idx_dest);
 379     Node* mem = start_mem_dest;
 380     bool same_alias = (alias_idx_src == alias_idx_dest);
 381 
 382     if (count > 0) {
 383       BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
 384       Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 385       v = phase->transform(v);
 386       if (copy_type == T_OBJECT) {
 387         v = bs->array_copy_load_store_barrier(phase, can_reshape, v, mm, forward_ctl);
 388       }
 389       mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 390       mem = phase->transform(mem);
 391       for (int i = 1; i < count; i++) {
 392         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 393         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 394         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 395         v = LoadNode::make(*phase, forward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 396         v = phase->transform(v);
 397         if (copy_type == T_OBJECT) {
 398           v = bs->array_copy_load_store_barrier(phase, can_reshape, v, mm, forward_ctl);
 399         }
 400         mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 401         mem = phase->transform(mem);
 402       }
 403       mm->set_memory_at(alias_idx_dest, mem);
 404     } else if(can_reshape) {
 405       PhaseIterGVN* igvn = phase->is_IterGVN();
 406       igvn->_worklist.push(adr_src);
 407       igvn->_worklist.push(adr_dest);
 408     }
 409     return mm;
 410   }
 411   return phase->C->top();
 412 }
 413 
 414 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
 415                                          bool can_reshape,
 416                                          Node*& backward_ctl,
 417                                          MergeMemNode* mm,
 418                                          const TypePtr* atp_src,
 419                                          const TypePtr* atp_dest,


 427   if (!backward_ctl->is_top()) {
 428     // copy backward
 429     mm = mm->clone()->as_MergeMem();
 430     uint alias_idx_src = phase->C->get_alias_index(atp_src);
 431     uint alias_idx_dest = phase->C->get_alias_index(atp_dest);
 432     Node *start_mem_src = mm->memory_at(alias_idx_src);
 433     Node *start_mem_dest = mm->memory_at(alias_idx_dest);
 434     Node* mem = start_mem_dest;
 435 
 436     BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
 437     assert(copy_type != T_OBJECT || !bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, BarrierSetC2::Optimization), "only tightly coupled allocations for object arrays");
 438     bool same_alias = (alias_idx_src == alias_idx_dest);
 439 
 440     if (count > 0) {
 441       for (int i = count-1; i >= 1; i--) {
 442         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 443         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 444         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 445         Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 446         v = phase->transform(v);
 447         if (copy_type == T_OBJECT) {
 448           v = bs->array_copy_load_store_barrier(phase, can_reshape, v, mm, backward_ctl);
 449         }
 450         mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 451         mem = phase->transform(mem);
 452       }
 453       Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 454       v = phase->transform(v);
 455       if (copy_type == T_OBJECT) {
 456         v = bs->array_copy_load_store_barrier(phase, can_reshape, v, mm, backward_ctl);
 457       }
 458       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 459       mem = phase->transform(mem);
 460       mm->set_memory_at(alias_idx_dest, mem);
 461     } else if(can_reshape) {
 462       PhaseIterGVN* igvn = phase->is_IterGVN();
 463       igvn->_worklist.push(adr_src);
 464       igvn->_worklist.push(adr_dest);
 465     }
 466     return phase->transform(mm);
 467   }
 468   return phase->C->top();
 469 }
 470 
 471 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
 472                                      Node* ctl, Node *mem) {
 473   if (can_reshape) {
 474     PhaseIterGVN* igvn = phase->is_IterGVN();
 475     igvn->set_delay_transform(false);
 476     if (is_clonebasic()) {
 477       Node* out_mem = proj_out(TypeFunc::Memory);


< prev index next >