< prev index next >

src/hotspot/share/opto/arraycopynode.cpp

Print this page




 173     ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 174     assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
 175     phase->C->dependencies()->assert_leaf_type(ik);
 176   }
 177 
 178   ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 179   assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
 180 
 181   for (int i = 0; i < count; i++) {
 182     ciField* field = ik->nonstatic_field_at(i);
 183     BasicType bt = field->layout_type();
 184 
 185     const Type *type;
 186     if (bt == T_OBJECT) {
 187       if (!field->type()->is_loaded()) {
 188         type = TypeInstPtr::BOTTOM;
 189       } else {
 190         ciType* field_klass = field->type();
 191         type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 192       }
 193       if (UseLoadBarrier) {
 194         if (can_reshape) {
 195           PhaseIterGVN* igvn = phase->is_IterGVN();
 196           igvn->_worklist.push(mem);
 197         }
 198         return NodeSentinel;
 199       }
 200     } else {
 201       type = Type::get_const_basic_type(bt);
 202     }
 203 
 204     int fieldidx = phase->C->alias_type(field)->index();
 205     const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
 206     Node* off = phase->MakeConX(field->offset());
 207     Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
 208     Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
 209 
 210     Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
 211     v = phase->transform(v);
 212     Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
 213     s = phase->transform(s);


 253       // We don't know if arguments are arrays
 254       return false;
 255     }
 256 
 257     BasicType src_elem  = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 258     BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
 259     if (src_elem  == T_ARRAY)  src_elem  = T_OBJECT;
 260     if (dest_elem == T_ARRAY)  dest_elem = T_OBJECT;
 261 
 262     if (src_elem != dest_elem || dest_elem == T_VOID) {
 263       // We don't know if arguments are arrays of the same type
 264       return false;
 265     }
 266 
 267     if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
 268       // It's an object array copy but we can't emit the card marking
 269       // that is needed
 270       return false;
 271     }
 272 
 273     if (dest_elem == T_OBJECT && UseLoadBarrier) {
 274       return false;
 275     }
 276 
 277     value_type = ary_src->elem();
 278 
 279     base_src = src;
 280     base_dest = dest;
 281 
 282     uint shift  = exact_log2(type2aelembytes(dest_elem));
 283     uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
 284 
 285     adr_src = src;
 286     adr_dest = dest;
 287 
 288     src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
 289     dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
 290 
 291     Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
 292     Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
 293 


 300     adr_src = phase->transform(adr_src);
 301     adr_dest = phase->transform(adr_dest);
 302 
 303     copy_type = dest_elem;
 304   } else {
 305     assert(ary_src != NULL, "should be a clone");
 306     assert(is_clonebasic(), "should be");
 307 
 308     disjoint_bases = true;
 309     assert(src->is_AddP(), "should be base + off");
 310     assert(dest->is_AddP(), "should be base + off");
 311     adr_src = src;
 312     base_src = src->in(AddPNode::Base);
 313     adr_dest = dest;
 314     base_dest = dest->in(AddPNode::Base);
 315 
 316     assert(phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con() == phase->type(dest->in(AddPNode::Offset))->is_intptr_t()->get_con(), "same start offset?");
 317     BasicType elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 318     if (elem == T_ARRAY)  elem = T_OBJECT;
 319 
 320     if (elem == T_OBJECT && UseLoadBarrier) {
 321       return false;
 322     }
 323 
 324     int diff = arrayOopDesc::base_offset_in_bytes(elem) - phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con();
 325     assert(diff >= 0, "clone should not start after 1st array element");
 326     if (diff > 0) {
 327       adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
 328       adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
 329     }
 330 
 331     copy_type = elem;
 332     value_type = ary_src->elem();
 333   }
 334   return true;
 335 }
 336 
 337 const TypePtr* ArrayCopyNode::get_address_type(PhaseGVN *phase, Node* n) {
 338   const Type* at = phase->type(n);
 339   assert(at != Type::TOP, "unexpected type");
 340   const TypePtr* atp = at->isa_ptr();


 359     backward_ctl = phase->transform(new IfTrueNode(iff));
 360   } else {
 361     forward_ctl = ctl;
 362   }
 363 }
 364 
 365 Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
 366                                         bool can_reshape,
 367                                         Node* forward_ctl,
 368                                         Node* start_mem_src,
 369                                         Node* start_mem_dest,
 370                                         const TypePtr* atp_src,
 371                                         const TypePtr* atp_dest,
 372                                         Node* adr_src,
 373                                         Node* base_src,
 374                                         Node* adr_dest,
 375                                         Node* base_dest,
 376                                         BasicType copy_type,
 377                                         const Type* value_type,
 378                                         int count) {
 379   guarantee(!UseLoadBarrier || copy_type != T_OBJECT, "Must be");
 380   Node* mem = phase->C->top();
 381   if (!forward_ctl->is_top()) {
 382     // copy forward
 383     mem = start_mem_dest;
 384 
 385     if (count > 0) {
 386       Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 387       v = phase->transform(v);
 388       mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 389       mem = phase->transform(mem);
 390       for (int i = 1; i < count; i++) {
 391         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 392         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 393         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 394         v = LoadNode::make(*phase, forward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 395         v = phase->transform(v);
 396         mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 397         mem = phase->transform(mem);
 398       }
 399     } else if(can_reshape) {


 402       igvn->_worklist.push(adr_dest);
 403     }
 404   }
 405   return mem;
 406 }
 407 
 408 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
 409                                          bool can_reshape,
 410                                          Node* backward_ctl,
 411                                          Node* start_mem_src,
 412                                          Node* start_mem_dest,
 413                                          const TypePtr* atp_src,
 414                                          const TypePtr* atp_dest,
 415                                          Node* adr_src,
 416                                          Node* base_src,
 417                                          Node* adr_dest,
 418                                          Node* base_dest,
 419                                          BasicType copy_type,
 420                                          const Type* value_type,
 421                                          int count) {
 422   guarantee(!UseLoadBarrier || copy_type != T_OBJECT, "Must be");
 423   Node* mem = phase->C->top();
 424   if (!backward_ctl->is_top()) {
 425     // copy backward
 426     mem = start_mem_dest;
 427 
 428     if (count > 0) {
 429       for (int i = count-1; i >= 1; i--) {
 430         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 431         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 432         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 433         Node* v = LoadNode::make(*phase, backward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 434         v = phase->transform(v);
 435         mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 436         mem = phase->transform(mem);
 437       }
 438       Node* v = LoadNode::make(*phase, backward_ctl, mem, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 439       v = phase->transform(v);
 440       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 441       mem = phase->transform(mem);
 442     } else if(can_reshape) {




 173     ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 174     assert(!ik->is_interface() && !ik->has_subklass(), "inconsistent klass hierarchy");
 175     phase->C->dependencies()->assert_leaf_type(ik);
 176   }
 177 
 178   ciInstanceKlass* ik = inst_src->klass()->as_instance_klass();
 179   assert(ik->nof_nonstatic_fields() <= ArrayCopyLoadStoreMaxElem, "too many fields");
 180 
 181   for (int i = 0; i < count; i++) {
 182     ciField* field = ik->nonstatic_field_at(i);
 183     BasicType bt = field->layout_type();
 184 
 185     const Type *type;
 186     if (bt == T_OBJECT) {
 187       if (!field->type()->is_loaded()) {
 188         type = TypeInstPtr::BOTTOM;
 189       } else {
 190         ciType* field_klass = field->type();
 191         type = TypeOopPtr::make_from_klass(field_klass->as_klass());
 192       }
 193       if (UseZGC) {
 194         if (can_reshape) {
 195           PhaseIterGVN* igvn = phase->is_IterGVN();
 196           igvn->_worklist.push(mem);
 197         }
 198         return NodeSentinel;
 199       }
 200     } else {
 201       type = Type::get_const_basic_type(bt);
 202     }
 203 
 204     int fieldidx = phase->C->alias_type(field)->index();
 205     const TypePtr* adr_type = phase->C->alias_type(field)->adr_type();
 206     Node* off = phase->MakeConX(field->offset());
 207     Node* next_src = phase->transform(new AddPNode(base_src,base_src,off));
 208     Node* next_dest = phase->transform(new AddPNode(base_dest,base_dest,off));
 209 
 210     Node* v = LoadNode::make(*phase, ctl, mem->memory_at(fieldidx), next_src, adr_type, type, bt, MemNode::unordered);
 211     v = phase->transform(v);
 212     Node* s = StoreNode::make(*phase, ctl, mem->memory_at(fieldidx), next_dest, adr_type, v, bt, MemNode::unordered);
 213     s = phase->transform(s);


 253       // We don't know if arguments are arrays
 254       return false;
 255     }
 256 
 257     BasicType src_elem  = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 258     BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
 259     if (src_elem  == T_ARRAY)  src_elem  = T_OBJECT;
 260     if (dest_elem == T_ARRAY)  dest_elem = T_OBJECT;
 261 
 262     if (src_elem != dest_elem || dest_elem == T_VOID) {
 263       // We don't know if arguments are arrays of the same type
 264       return false;
 265     }
 266 
 267     if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {
 268       // It's an object array copy but we can't emit the card marking
 269       // that is needed
 270       return false;
 271     }
 272 
 273     if (dest_elem == T_OBJECT && UseZGC) {
 274       return false;
 275     }
 276 
 277     value_type = ary_src->elem();
 278 
 279     base_src = src;
 280     base_dest = dest;
 281 
 282     uint shift  = exact_log2(type2aelembytes(dest_elem));
 283     uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
 284 
 285     adr_src = src;
 286     adr_dest = dest;
 287 
 288     src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
 289     dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
 290 
 291     Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));
 292     Node* dest_scale = phase->transform(new LShiftXNode(dest_offset, phase->intcon(shift)));
 293 


 300     adr_src = phase->transform(adr_src);
 301     adr_dest = phase->transform(adr_dest);
 302 
 303     copy_type = dest_elem;
 304   } else {
 305     assert(ary_src != NULL, "should be a clone");
 306     assert(is_clonebasic(), "should be");
 307 
 308     disjoint_bases = true;
 309     assert(src->is_AddP(), "should be base + off");
 310     assert(dest->is_AddP(), "should be base + off");
 311     adr_src = src;
 312     base_src = src->in(AddPNode::Base);
 313     adr_dest = dest;
 314     base_dest = dest->in(AddPNode::Base);
 315 
 316     assert(phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con() == phase->type(dest->in(AddPNode::Offset))->is_intptr_t()->get_con(), "same start offset?");
 317     BasicType elem = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 318     if (elem == T_ARRAY)  elem = T_OBJECT;
 319 
 320     if (elem == T_OBJECT && UseZGC) {
 321       return false;
 322     }
 323 
 324     int diff = arrayOopDesc::base_offset_in_bytes(elem) - phase->type(src->in(AddPNode::Offset))->is_intptr_t()->get_con();
 325     assert(diff >= 0, "clone should not start after 1st array element");
 326     if (diff > 0) {
 327       adr_src = phase->transform(new AddPNode(base_src, adr_src, phase->MakeConX(diff)));
 328       adr_dest = phase->transform(new AddPNode(base_dest, adr_dest, phase->MakeConX(diff)));
 329     }
 330 
 331     copy_type = elem;
 332     value_type = ary_src->elem();
 333   }
 334   return true;
 335 }
 336 
 337 const TypePtr* ArrayCopyNode::get_address_type(PhaseGVN *phase, Node* n) {
 338   const Type* at = phase->type(n);
 339   assert(at != Type::TOP, "unexpected type");
 340   const TypePtr* atp = at->isa_ptr();


 359     backward_ctl = phase->transform(new IfTrueNode(iff));
 360   } else {
 361     forward_ctl = ctl;
 362   }
 363 }
 364 
 365 Node* ArrayCopyNode::array_copy_forward(PhaseGVN *phase,
 366                                         bool can_reshape,
 367                                         Node* forward_ctl,
 368                                         Node* start_mem_src,
 369                                         Node* start_mem_dest,
 370                                         const TypePtr* atp_src,
 371                                         const TypePtr* atp_dest,
 372                                         Node* adr_src,
 373                                         Node* base_src,
 374                                         Node* adr_dest,
 375                                         Node* base_dest,
 376                                         BasicType copy_type,
 377                                         const Type* value_type,
 378                                         int count) {
 379   guarantee(!UseZGC || copy_type != T_OBJECT, "Must be");
 380   Node* mem = phase->C->top();
 381   if (!forward_ctl->is_top()) {
 382     // copy forward
 383     mem = start_mem_dest;
 384 
 385     if (count > 0) {
 386       Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 387       v = phase->transform(v);
 388       mem = StoreNode::make(*phase, forward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 389       mem = phase->transform(mem);
 390       for (int i = 1; i < count; i++) {
 391         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 392         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 393         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 394         v = LoadNode::make(*phase, forward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 395         v = phase->transform(v);
 396         mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 397         mem = phase->transform(mem);
 398       }
 399     } else if(can_reshape) {


 402       igvn->_worklist.push(adr_dest);
 403     }
 404   }
 405   return mem;
 406 }
 407 
 408 Node* ArrayCopyNode::array_copy_backward(PhaseGVN *phase,
 409                                          bool can_reshape,
 410                                          Node* backward_ctl,
 411                                          Node* start_mem_src,
 412                                          Node* start_mem_dest,
 413                                          const TypePtr* atp_src,
 414                                          const TypePtr* atp_dest,
 415                                          Node* adr_src,
 416                                          Node* base_src,
 417                                          Node* adr_dest,
 418                                          Node* base_dest,
 419                                          BasicType copy_type,
 420                                          const Type* value_type,
 421                                          int count) {
 422   guarantee(!UseZGC || copy_type != T_OBJECT, "Must be");
 423   Node* mem = phase->C->top();
 424   if (!backward_ctl->is_top()) {
 425     // copy backward
 426     mem = start_mem_dest;
 427 
 428     if (count > 0) {
 429       for (int i = count-1; i >= 1; i--) {
 430         Node* off  = phase->MakeConX(type2aelembytes(copy_type) * i);
 431         Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off));
 432         Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off));
 433         Node* v = LoadNode::make(*phase, backward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered);
 434         v = phase->transform(v);
 435         mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered);
 436         mem = phase->transform(mem);
 437       }
 438       Node* v = LoadNode::make(*phase, backward_ctl, mem, adr_src, atp_src, value_type, copy_type, MemNode::unordered);
 439       v = phase->transform(v);
 440       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 441       mem = phase->transform(mem);
 442     } else if(can_reshape) {


< prev index next >