# HG changeset patch # Parent 7a64f4b361ce89962a19e207e1aed8b507b506ea diff -r 7a64f4b361ce -r 637dd853c3f3 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Thu Jun 27 14:22:15 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Tue Jul 02 19:57:08 2019 +0200 @@ -546,7 +546,7 @@ if (access.is_oop()) { if (ShenandoahLoadRefBarrier) { - load = new ShenandoahLoadReferenceBarrierNode(NULL, load, adr); + load = new ShenandoahLoadReferenceBarrierNode(NULL, load); if (access.is_parse_access()) { load = static_cast(access).kit()->gvn().transform(load); } else { @@ -631,7 +631,7 @@ load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); } #endif - load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, kit->null())); + load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store)); return load_store; } return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); @@ -699,7 +699,7 @@ } Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type); if (access.is_oop()) { - result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, kit->null())); + result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result)); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, result /* pre_val */, T_OBJECT); diff -r 7a64f4b361ce -r 637dd853c3f3 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Thu Jun 27 14:22:15 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Tue Jul 02 19:57:08 2019 +0200 @@ -1523,7 +1523,9 @@ // Call lrb-stub and wire up that path in slots 4 Node* result_mem = NULL; Node* fwd = new_val; - call_lrb_stub(ctrl, fwd, lrb->in(ShenandoahLoadReferenceBarrierNode::LoadAddr), result_mem, raw_mem, phase); + VectorSet visited(Thread::current()->resource_area()); + Node* addr = get_load_addr(phase, visited, lrb); + call_lrb_stub(ctrl, fwd, addr, result_mem, raw_mem, phase); region->init_req(_evac_path, ctrl); val_phi->init_req(_evac_path, fwd); raw_mem_phi->init_req(_evac_path, result_mem); @@ -1726,6 +1728,58 @@ } +Node* ShenandoahBarrierC2Support::get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* in) { + if (visited.test_set(in->_idx)) { + return NULL; + } + switch (in->Opcode()) { + case Op_Proj: + return get_load_addr(phase, visited, in->in(0)); + case Op_CastPP: + case Op_CheckCastPP: + case Op_DecodeN: + case Op_EncodeP: + return get_load_addr(phase, visited, in->in(1)); + case Op_CompareAndExchangeN: + case Op_CompareAndExchangeP: + case Op_GetAndSetN: + case Op_GetAndSetP: + case Op_LoadN: + case Op_LoadP: + case Op_ShenandoahCompareAndExchangeP: + case Op_ShenandoahCompareAndExchangeN: + return in->in(MemNode::Address); + case Op_Phi: { + Node* addr = NULL; + for (uint i = 1; i < in->req(); i++) { + Node* addr1 = get_load_addr(phase, visited, in->in(i)); + if (addr == NULL) { + addr = addr1; + } + if (addr != addr1) { + return phase->igvn().zerocon(T_OBJECT); + } + } + return addr; + } + case Op_ShenandoahLoadReferenceBarrier: + return get_load_addr(phase, visited, in->in(ShenandoahLoadReferenceBarrierNode::ValueIn)); + case Op_CallDynamicJava: + case Op_CallLeaf: + case Op_CallStaticJava: + case Op_ConN: + case Op_ConP: + return phase->igvn().zerocon(T_OBJECT); + default: +#ifdef ASSERT + in->dump(); + ShouldNotReachHere(); +#endif + return phase->igvn().zerocon(T_OBJECT); + } + +} + void ShenandoahBarrierC2Support::move_heap_stable_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase) { IdealLoopTree *loop = phase->get_loop(iff); Node* loop_head = loop->_head; @@ -2966,8 +3020,8 @@ } } -ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, Node* load_addr) -: Node(ctrl, obj, load_addr) { +ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj) +: Node(ctrl, obj) { ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this); } diff -r 7a64f4b361ce -r 637dd853c3f3 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Thu Jun 27 14:22:15 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Tue Jul 02 19:57:08 2019 +0200 @@ -71,6 +71,7 @@ static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase); static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase); + static Node* get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* lrb); public: static bool is_dominator(Node* d_c, Node* n_c, Node* d, Node* n, PhaseIdealLoop* phase); static bool is_dominator_same_ctrl(Node* c, Node* d, Node* n, PhaseIdealLoop* phase); @@ -227,15 +228,14 @@ public: enum { Control, - ValueIn, - LoadAddr + ValueIn }; enum Strength { NONE, WEAK, STRONG, NA }; - ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, Node* load_addr); + ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val); virtual int Opcode() const; virtual const Type* bottom_type() const;