< prev index next >

src/hotspot/share/opto/macroArrayCopy.cpp

Print this page

        

*** 70,80 **** const TypePtr* adr_type, Node* parm0, Node* parm1, Node* parm2, Node* parm3, Node* parm4, Node* parm5, Node* parm6, Node* parm7) { - int size = call_type->domain()->cnt(); Node* call = new CallLeafNoFPNode(call_type, call_addr, call_name, adr_type); call->init_req(TypeFunc::Control, ctrl); call->init_req(TypeFunc::I_O , top()); call->init_req(TypeFunc::Memory , mem); call->init_req(TypeFunc::ReturnAdr, top()); --- 70,79 ----
*** 1081,1090 **** --- 1080,1116 ---- src_start, dest_start, copy_length XTOP); finish_arraycopy_call(call, ctrl, mem, adr_type); } + bool PhaseMacroExpand::clone_needs_postbarrier(ArrayCopyNode *ac) { + Node* src = ac->in(ArrayCopyNode::Src); + const TypeOopPtr* src_type = _igvn.type(src)->is_oopptr(); + if (src_type->isa_instptr() != NULL) { + ciInstanceKlass* ik = src_type->klass()->as_instance_klass(); + if ((src_type->klass_is_exact() || (!ik->is_interface() && !ik->has_subklass())) && !ik->has_injected_fields()) { + if (ik->has_object_fields()) { + return true; + } else { + if (!src_type->klass_is_exact()) { + C->dependencies()->assert_leaf_type(ik); + } + } + } else { + return true; + } + } else if (src_type->isa_aryptr()) { + BasicType src_elem = src_type->klass()->as_array_klass()->element_type()->basic_type(); + if (src_elem == T_OBJECT || src_elem == T_ARRAY) { + return true; + } + } else { + return true; + } + return false; + } + void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) { Node* ctrl = ac->in(TypeFunc::Control); Node* io = ac->in(TypeFunc::I_O); Node* src = ac->in(ArrayCopyNode::Src); Node* src_offset = ac->in(ArrayCopyNode::SrcPos);
*** 1105,1115 **** --- 1131,1155 ---- const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); Node* call = make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP); transform_later(call); + if (clone_needs_postbarrier(ac)) { + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; + Node* c = new ProjNode(call,TypeFunc::Control); + transform_later(c); + Node* m = new ProjNode(call, TypeFunc::Memory); + transform_later(m); + BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); + bs->array_copy_post_barrier_at_expansion(ac, c, m, _igvn); + Node* out_c = ac->proj_out(TypeFunc::Control); + Node* out_m = ac->proj_out(TypeFunc::Memory); + _igvn.replace_node(out_c, c); + _igvn.replace_node(out_m, m); + } else { _igvn.replace_node(ac, call); + } return; } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) { Node* mem = ac->in(TypeFunc::Memory); merge_mem = MergeMemNode::make(mem); transform_later(merge_mem);
< prev index next >