--- old/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2019-10-30 15:25:05.401464868 +0100 +++ new/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp 2019-10-30 15:25:05.175460011 +0100 @@ -38,6 +38,7 @@ #include "opto/movenode.hpp" #include "opto/narrowptrnode.hpp" #include "opto/rootnode.hpp" +#include "opto/runtime.hpp" ShenandoahBarrierSetC2* ShenandoahBarrierSetC2::bsc2() { return reinterpret_cast(BarrierSet::barrier_set()->barrier_set_c2()); @@ -779,6 +780,72 @@ return false; } +static Node* shenandoah_call_clone_barrier(PhaseMacroExpand* phase, Node* call, Node* dest) { + assert (UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled"); + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; + Node* c = new ProjNode(call,TypeFunc::Control); + phase->transform_later(c); + Node* m = new ProjNode(call, TypeFunc::Memory); + phase->transform_later(m); + assert(dest->is_AddP(), "bad input"); + call = phase->make_leaf_call(c, m, ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(), + CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), + "shenandoah_clone_barrier", raw_adr_type, dest->in(AddPNode::Base)); + phase->transform_later(call); + return call; +} + +#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); + 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"); + const char* copyfunc_name = "arraycopy"; + address copyfunc_addr = + phase->basictype2arraycopy(T_LONG, NULL, NULL, + true, copyfunc_name, true); + + const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; + const TypeFunc* call_type = OptoRuntime::fast_arraycopy_Type(); + + Node* call = phase->make_leaf_call(ctrl, mem, call_type, copyfunc_addr, copyfunc_name, raw_adr_type, src, dest, length XTOP); + phase->transform_later(call); + + if (ShenandoahCloneBarrier) { + const TypeOopPtr* src_type = phase->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()) { + call = shenandoah_call_clone_barrier(phase, call, dest); + } else { + if (!src_type->klass_is_exact()) { + phase->C->dependencies()->assert_leaf_type(ik); + } + } + } else { + call = shenandoah_call_clone_barrier(phase, call, dest); + } + } 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) { + call = shenandoah_call_clone_barrier(phase, call, dest); + } + } else { + call = shenandoah_call_clone_barrier(phase, call, dest); + } + } + + phase->igvn().replace_node(ac, call); +} + // Support for macro expanded GC barriers void ShenandoahBarrierSetC2::register_potential_barrier_node(Node* node) const { if (node->Opcode() == Op_ShenandoahEnqueueBarrier) { --- old/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp 2019-10-30 15:25:06.278483715 +0100 +++ new/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp 2019-10-30 15:25:06.027478321 +0100 @@ -108,6 +108,8 @@ // This is the entry-point for the backend to perform accesses through the Access API. virtual void clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const; + virtual void clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const; + // These are general helper methods used by C2 virtual bool array_copy_requires_gc_barriers(BasicType type) const; --- old/src/hotspot/share/opto/macro.hpp 2019-10-30 15:25:07.211503766 +0100 +++ new/src/hotspot/share/opto/macro.hpp 2019-10-30 15:25:06.974498673 +0100 @@ -202,9 +202,6 @@ Node* make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset, Node* ctl, Node* mem, BasicType ft, const Type *ftype, AllocateNode *alloc); -#if INCLUDE_SHENANDOAHGC - Node* shenandoah_call_clone_barrier(Node* call, Node* dest); -#endif public: PhaseMacroExpand(PhaseIterGVN &igvn) : Phase(Macro_Expand), _igvn(igvn), _has_locks(false) { _igvn.set_delay_transform(true); --- old/src/hotspot/share/opto/macroArrayCopy.cpp 2019-10-30 15:25:08.126523431 +0100 +++ new/src/hotspot/share/opto/macroArrayCopy.cpp 2019-10-30 15:25:07.881518165 +0100 @@ -1087,23 +1087,6 @@ finish_arraycopy_call(call, ctrl, mem, adr_type); } -#if INCLUDE_SHENANDOAHGC -Node* PhaseMacroExpand::shenandoah_call_clone_barrier(Node* call, Node* dest) { - assert (UseShenandoahGC && ShenandoahCloneBarrier, "Should be enabled"); - 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); - assert(dest->is_AddP(), "bad input"); - call = make_leaf_call(c, m, ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(), - CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), - "shenandoah_clone_barrier", raw_adr_type, dest->in(AddPNode::Base)); - transform_later(call); - return call; -} -#endif - void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) { Node* ctrl = ac->in(TypeFunc::Control); Node* io = ac->in(TypeFunc::I_O); @@ -1115,52 +1098,8 @@ MergeMemNode* merge_mem = NULL; if (ac->is_clonebasic()) { - if (UseShenandoahGC) { // TODO: Move to SBSC2::clone_at_expansion - assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null"); - Node* mem = ac->in(TypeFunc::Memory); - const char* copyfunc_name = "arraycopy"; - address copyfunc_addr = - basictype2arraycopy(T_LONG, NULL, NULL, - true, copyfunc_name, true); - - const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; - 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 INCLUDE_SHENANDOAHGC - if (UseShenandoahGC && ShenandoahCloneBarrier) { - 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()) { - call = shenandoah_call_clone_barrier(call, dest); - } else { - if (!src_type->klass_is_exact()) { - C->dependencies()->assert_leaf_type(ik); - } - } - } else { - call = shenandoah_call_clone_barrier(call, dest); - } - } 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) { - call = shenandoah_call_clone_barrier(call, dest); - } - } else { - call = shenandoah_call_clone_barrier(call, dest); - } - } -#endif - - _igvn.replace_node(ac, call); - } else { - BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); - bs->clone_at_expansion(this, ac); - } + BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); + bs->clone_at_expansion(this, ac); return; } else if (ac->is_copyof() || ac->is_copyofrange() || ac->is_cloneoop()) { Node* mem = ac->in(TypeFunc::Memory);