< prev index next >

src/share/vm/opto/arraycopynode.cpp

Print this page
rev 12906 : [mq]: gc_interface


 234 
 235     // newly allocated object is guaranteed to not overlap with source object
 236     disjoint_bases = is_alloc_tightly_coupled();
 237 
 238     if (ary_src  == NULL || ary_src->klass()  == NULL ||
 239         ary_dest == NULL || ary_dest->klass() == NULL) {
 240       // We don't know if arguments are arrays
 241       return false;
 242     }
 243 
 244     BasicType src_elem  = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 245     BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
 246     if (src_elem  == T_ARRAY)  src_elem  = T_OBJECT;
 247     if (dest_elem == T_ARRAY)  dest_elem = T_OBJECT;
 248 
 249     if (src_elem != dest_elem || dest_elem == T_VOID) {
 250       // We don't know if arguments are arrays of the same type
 251       return false;
 252     }
 253 
 254     if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() || !GraphKit::use_ReduceInitialCardMarks())) {


 255       // It's an object array copy but we can't emit the card marking
 256       // that is needed
 257       return false;
 258     }
 259 
 260     value_type = ary_src->elem();
 261 
 262     base_src = src;
 263     base_dest = dest;
 264 
 265     uint shift  = exact_log2(type2aelembytes(dest_elem));
 266     uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
 267 
 268     adr_src = src;
 269     adr_dest = dest;
 270 
 271     src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
 272     dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
 273 
 274     Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));


 416       v = phase->transform(v);
 417       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 418       mem = phase->transform(mem);
 419     } else if(can_reshape) {
 420       PhaseIterGVN* igvn = phase->is_IterGVN();
 421       igvn->_worklist.push(adr_src);
 422       igvn->_worklist.push(adr_dest);
 423     }
 424   }
 425   return mem;
 426 }
 427 
 428 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
 429                                      Node* ctl, Node *mem) {
 430   if (can_reshape) {
 431     PhaseIterGVN* igvn = phase->is_IterGVN();
 432     igvn->set_delay_transform(false);
 433     if (is_clonebasic()) {
 434       Node* out_mem = proj_out(TypeFunc::Memory);
 435 

 436       if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
 437           out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
 438         assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking");
 439         return false;
 440       }
 441 
 442       igvn->replace_node(out_mem->raw_out(0), mem);
 443 
 444       Node* out_ctl = proj_out(TypeFunc::Control);
 445       igvn->replace_node(out_ctl, ctl);
 446     } else {
 447       // replace fallthrough projections of the ArrayCopyNode by the
 448       // new memory, control and the input IO.
 449       CallProjections callprojs;
 450       extract_projections(&callprojs, true, false);
 451 
 452       if (callprojs.fallthrough_ioproj != NULL) {
 453         igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
 454       }
 455       if (callprojs.fallthrough_memproj != NULL) {
 456         igvn->replace_node(callprojs.fallthrough_memproj, mem);
 457       }
 458       if (callprojs.fallthrough_catchproj != NULL) {




 234 
 235     // newly allocated object is guaranteed to not overlap with source object
 236     disjoint_bases = is_alloc_tightly_coupled();
 237 
 238     if (ary_src  == NULL || ary_src->klass()  == NULL ||
 239         ary_dest == NULL || ary_dest->klass() == NULL) {
 240       // We don't know if arguments are arrays
 241       return false;
 242     }
 243 
 244     BasicType src_elem  = ary_src->klass()->as_array_klass()->element_type()->basic_type();
 245     BasicType dest_elem = ary_dest->klass()->as_array_klass()->element_type()->basic_type();
 246     if (src_elem  == T_ARRAY)  src_elem  = T_OBJECT;
 247     if (dest_elem == T_ARRAY)  dest_elem = T_OBJECT;
 248 
 249     if (src_elem != dest_elem || dest_elem == T_VOID) {
 250       // We don't know if arguments are arrays of the same type
 251       return false;
 252     }
 253 
 254     C2BarrierSetCodeGen* code_gen = Universe::heap()->barrier_set()->c2_code_gen();
 255     if (dest_elem == T_OBJECT && (!is_alloc_tightly_coupled() ||
 256                                   code_gen->array_copy_requires_gc_barriers(T_OBJECT))) {
 257       // It's an object array copy but we can't emit the card marking
 258       // that is needed
 259       return false;
 260     }
 261 
 262     value_type = ary_src->elem();
 263 
 264     base_src = src;
 265     base_dest = dest;
 266 
 267     uint shift  = exact_log2(type2aelembytes(dest_elem));
 268     uint header = arrayOopDesc::base_offset_in_bytes(dest_elem);
 269 
 270     adr_src = src;
 271     adr_dest = dest;
 272 
 273     src_offset = Compile::conv_I2X_index(phase, src_offset, ary_src->size());
 274     dest_offset = Compile::conv_I2X_index(phase, dest_offset, ary_dest->size());
 275 
 276     Node* src_scale = phase->transform(new LShiftXNode(src_offset, phase->intcon(shift)));


 418       v = phase->transform(v);
 419       mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered);
 420       mem = phase->transform(mem);
 421     } else if(can_reshape) {
 422       PhaseIterGVN* igvn = phase->is_IterGVN();
 423       igvn->_worklist.push(adr_src);
 424       igvn->_worklist.push(adr_dest);
 425     }
 426   }
 427   return mem;
 428 }
 429 
 430 bool ArrayCopyNode::finish_transform(PhaseGVN *phase, bool can_reshape,
 431                                      Node* ctl, Node *mem) {
 432   if (can_reshape) {
 433     PhaseIterGVN* igvn = phase->is_IterGVN();
 434     igvn->set_delay_transform(false);
 435     if (is_clonebasic()) {
 436       Node* out_mem = proj_out(TypeFunc::Memory);
 437 
 438       C2BarrierSetCodeGen* code_gen = Universe::heap()->barrier_set()->c2_code_gen();
 439       if (out_mem->outcnt() != 1 || !out_mem->raw_out(0)->is_MergeMem() ||
 440           out_mem->raw_out(0)->outcnt() != 1 || !out_mem->raw_out(0)->raw_out(0)->is_MemBar()) {
 441         assert(code_gen->array_copy_requires_gc_barriers(T_OBJECT), "can only happen with card marking");
 442         return false;
 443       }
 444 
 445       igvn->replace_node(out_mem->raw_out(0), mem);
 446 
 447       Node* out_ctl = proj_out(TypeFunc::Control);
 448       igvn->replace_node(out_ctl, ctl);
 449     } else {
 450       // replace fallthrough projections of the ArrayCopyNode by the
 451       // new memory, control and the input IO.
 452       CallProjections callprojs;
 453       extract_projections(&callprojs, true, false);
 454 
 455       if (callprojs.fallthrough_ioproj != NULL) {
 456         igvn->replace_node(callprojs.fallthrough_ioproj, in(TypeFunc::I_O));
 457       }
 458       if (callprojs.fallthrough_memproj != NULL) {
 459         igvn->replace_node(callprojs.fallthrough_memproj, mem);
 460       }
 461       if (callprojs.fallthrough_catchproj != NULL) {


< prev index next >