--- old/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2019-09-17 11:35:39.879897473 +0200 +++ new/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2019-09-17 11:35:39.773897476 +0200 @@ -461,9 +461,11 @@ } const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() { - const Type **fields = TypeTuple::fields(1); - fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value - const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); + const Type **fields = TypeTuple::fields(3); + fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // src + fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // dst + fields[TypeFunc::Parms+2] = TypeInt::INT; // length + const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields); // create result type (range) fields = TypeTuple::fields(0); @@ -705,11 +707,6 @@ return result; } -void ShenandoahBarrierSetC2::clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const { - assert(!src->is_AddP(), "unexpected input"); - BarrierSetC2::clone(kit, src, dst, size, is_array); -} - // Support for GC barriers emitted during parsing bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const { if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) return true; @@ -771,9 +768,8 @@ return true; } -bool ShenandoahBarrierSetC2::clone_needs_postbarrier(ArrayCopyNode *ac, PhaseIterGVN& igvn) { - Node* src = ac->in(ArrayCopyNode::Src); - const TypeOopPtr* src_type = igvn.type(src)->is_oopptr(); +bool ShenandoahBarrierSetC2::clone_needs_barrier(Node* src, PhaseGVN& gvn) { + const TypeOopPtr* src_type = gvn.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()) { @@ -781,7 +777,7 @@ return true; } else { if (!src_type->klass_is_exact()) { - igvn.C->dependencies()->assert_leaf_type(ik); + Compile::current()->dependencies()->assert_leaf_type(ik); } } } else { @@ -798,42 +794,28 @@ return false; } -void ShenandoahBarrierSetC2::clone_barrier_at_expansion(ArrayCopyNode* ac, Node* call, PhaseIterGVN& igvn) const { - assert(ac->is_clonebasic(), "no other kind of arraycopy here"); - - if (!clone_needs_postbarrier(ac, igvn)) { - BarrierSetC2::clone_barrier_at_expansion(ac, call, igvn); - return; - } - - const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; - Node* c = new ProjNode(call,TypeFunc::Control); - c = igvn.transform(c); - Node* m = new ProjNode(call, TypeFunc::Memory); - m = igvn.transform(m); +#define XTOP LP64_ONLY(COMMA phase->top()) +void ShenandoahBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { + Node* ctrl = ac->in(TypeFunc::Control); + Node* mem = ac->in(TypeFunc::Memory); + Node* src = ac->in(ArrayCopyNode::Src); + Node* src_offset = ac->in(ArrayCopyNode::SrcPos); Node* dest = ac->in(ArrayCopyNode::Dest); - assert(dest->is_AddP(), "bad input"); - Node* barrier_call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(), - CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), - "shenandoah_clone_barrier", raw_adr_type); - barrier_call->init_req(TypeFunc::Control, c); - barrier_call->init_req(TypeFunc::I_O , igvn.C->top()); - barrier_call->init_req(TypeFunc::Memory , m); - barrier_call->init_req(TypeFunc::ReturnAdr, igvn.C->top()); - barrier_call->init_req(TypeFunc::FramePtr, igvn.C->top()); - barrier_call->init_req(TypeFunc::Parms+0, dest->in(AddPNode::Base)); - - barrier_call = igvn.transform(barrier_call); - c = new ProjNode(barrier_call,TypeFunc::Control); - c = igvn.transform(c); - m = new ProjNode(barrier_call, TypeFunc::Memory); - m = igvn.transform(m); - - 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); + Node* dest_offset = ac->in(ArrayCopyNode::DestPos); + Node* length = ac->in(ArrayCopyNode::Length); + assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null"); + if (ShenandoahCloneBarrier && clone_needs_barrier(src, phase->igvn())) { + const char* copyfunc_name = "shenandoah_clone"; + address copyfunc_addr = CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier); + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; + const TypeFunc* call_type = ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(); + Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length); + call = phase->transform_later(call); + phase->igvn().replace_node(ac, call); + } else { + BarrierSetC2::clone_at_expansion(phase, ac); + } }