# HG changeset patch # User neliasso # Date 1561970998 -7200 # Node ID 8313c42345d5e8027712613f82ca76876786c496 # Parent df1925d3d40900247d8bc8301f4ddb13be97d2c5 8226287: Make process_users_of_allocation handle gc barriers Reviewed-by: kvn, roland diff -r df1925d3d409 -r 8313c42345d5 src/hotspot/share/gc/shared/c2/barrierSetC2.hpp --- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Mon Jul 01 12:50:34 2019 +0800 +++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp Mon Jul 01 10:49:58 2019 +0200 @@ -267,6 +267,7 @@ virtual bool has_load_barriers() const { return false; } virtual bool is_gc_barrier_node(Node* node) const { return false; } virtual Node* step_over_gc_barrier(Node* c) const { return c; } + virtual Node* step_over_gc_barrier_ctrl(Node* c) const { return c; } // Support for macro expanded GC barriers virtual void register_potential_barrier_node(Node* node) const { } diff -r df1925d3d409 -r 8313c42345d5 src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Mon Jul 01 12:50:34 2019 +0800 +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Mon Jul 01 10:49:58 2019 +0200 @@ -522,7 +522,7 @@ Node* in_val = barrier->in(LoadBarrierNode::Oop); Node* in_adr = barrier->in(LoadBarrierNode::Address); - Node* out_ctrl = barrier->proj_out_or_null(LoadBarrierNode::Control); + Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control); Node* out_res = barrier->proj_out(LoadBarrierNode::Oop); assert(barrier->in(LoadBarrierNode::Oop) != NULL, "oop to loadbarrier node cannot be null"); @@ -552,9 +552,8 @@ result_phi->set_req(1, new_loadp); result_phi->set_req(2, barrier->in(LoadBarrierNode::Oop)); - if (out_ctrl != NULL) { - igvn.replace_node(out_ctrl, result_region); - } + + igvn.replace_node(out_ctrl, result_region); igvn.replace_node(out_res, result_phi); assert(barrier->outcnt() == 0,"LoadBarrier macro node has non-null outputs after expansion!"); @@ -640,6 +639,22 @@ return c; } +Node* ZBarrierSetC2::step_over_gc_barrier_ctrl(Node* c) const { + Node* node = c; + + // 1. This step follows potential ctrl projections of a load barrier before expansion + if (node->is_Proj()) { + node = node->in(0); + } + + // 2. This step checks for unexpanded load barriers + if (node->is_LoadBarrier()) { + return node->in(LoadBarrierNode::Control); + } + + return c; +} + bool ZBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const { return type == T_OBJECT || type == T_ARRAY; } diff -r df1925d3d409 -r 8313c42345d5 src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Mon Jul 01 12:50:34 2019 +0800 +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp Mon Jul 01 10:49:58 2019 +0200 @@ -182,6 +182,7 @@ virtual bool has_load_barriers() const { return true; } virtual bool is_gc_barrier_node(Node* node) const; virtual Node* step_over_gc_barrier(Node* c) const; + virtual Node* step_over_gc_barrier_ctrl(Node* c) const; virtual void register_potential_barrier_node(Node* node) const; virtual void unregister_potential_barrier_node(Node* node) const; diff -r df1925d3d409 -r 8313c42345d5 src/hotspot/share/opto/macro.cpp --- a/src/hotspot/share/opto/macro.cpp Mon Jul 01 12:50:34 2019 +0800 +++ b/src/hotspot/share/opto/macro.cpp Mon Jul 01 10:49:58 2019 +0200 @@ -1008,8 +1008,17 @@ assert(init->outcnt() <= 2, "only a control and memory projection expected"); Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control); if (ctrl_proj != NULL) { - assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection"); - _igvn.replace_node(ctrl_proj, _fallthroughcatchproj); + _igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control)); +#ifdef ASSERT + BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2(); + Node* tmp = init->in(TypeFunc::Control); + while (bs->is_gc_barrier_node(tmp)) { + Node* tmp2 = bs->step_over_gc_barrier_ctrl(tmp); + assert(tmp != tmp2, "Must make progress"); + tmp = tmp2; + } + assert(tmp == _fallthroughcatchproj, "allocation control projection"); +#endif } Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory); if (mem_proj != NULL) {