# HG changeset patch # Parent 4ffc7f608c8cd5779c56f36ac0b8600978e0610b diff -r 4ffc7f608c8c -r b7ae94e0a9fd src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Mon Mar 02 21:19:11 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Mon Mar 02 21:53:43 2020 +0100 @@ -901,7 +901,7 @@ phase->register_new_node(heap_stable_cmp, ctrl); Node* heap_stable_test = new BoolNode(heap_stable_cmp, BoolTest::ne); phase->register_new_node(heap_stable_test, ctrl); - IfNode* heap_stable_iff = new IfNode(ctrl, heap_stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); + IfNode* heap_stable_iff = new IfNode(ctrl, heap_stable_test, PROB_FAIR, COUNT_UNKNOWN); phase->register_control(heap_stable_iff, loop, ctrl); heap_stable_ctrl = new IfFalseNode(heap_stable_iff); @@ -1462,6 +1462,27 @@ Node* gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); phase->register_new_node(gc_state, ctrl); + enum { _gc_inactive = 1, _gc_active, PATH_LIMIT_OUTER }; + Node* region_outer = new RegionNode(PATH_LIMIT_OUTER); + Node* val_phi_outer = new PhiNode(region_outer, uncasted_val->bottom_type()->is_oopptr()); + Node* phi_outer = PhiNode::make(region_outer, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); + + Node* gc_active_cmp = new CmpINode(gc_state, phase->igvn().zerocon(T_INT)); + phase->register_new_node(gc_active_cmp, ctrl); + Node* gc_active_test = new BoolNode(gc_active_cmp, BoolTest::ne); + phase->register_new_node(gc_active_test, ctrl); + IfNode* gc_active_iff = new IfNode(ctrl, gc_active_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN); + phase->register_control(gc_active_iff, loop, ctrl); + + Node* gc_inactive_ctrl = new IfFalseNode(gc_active_iff); + phase->register_control(gc_inactive_ctrl, loop, gc_active_iff); + ctrl = new IfTrueNode(gc_active_iff); + phase->register_control(ctrl, loop, gc_active_iff); + + region_outer->init_req(_gc_inactive, gc_inactive_ctrl); + val_phi_outer->init_req(_gc_inactive, uncasted_val); + phi_outer->init_req(_gc_inactive, raw_mem); + if (lrb->need_concmark_barrier()) { Node* heap_stable_ctrl = NULL; Node* null_ctrl = NULL; @@ -1668,11 +1689,15 @@ raw_mem_phi->init_req(_evac_path, result_mem); phase->register_control(region, loop, heap_stable_iff); - Node* out_val = val_phi; phase->register_new_node(val_phi, region); phase->register_new_node(raw_mem_phi, region); - fix_ctrl(lrb, region, fixer, uses, uses_to_ignore, last, phase); + region_outer->init_req(_gc_active, region); + val_phi_outer->init_req(_gc_active, val_phi); + phi_outer->init_req(_gc_active, raw_mem_phi); + Node* out_val = val_phi_outer; + + fix_ctrl(lrb, region_outer, fixer, uses, uses_to_ignore, last, phase); ctrl = orig_ctrl; @@ -1698,7 +1723,7 @@ Node *n = uses.at(next); assert(phase->get_ctrl(n) == ctrl, "bad control"); assert(n != init_raw_mem, "should leave input raw mem above the barrier"); - phase->set_ctrl(n, region); + phase->set_ctrl(n, region_outer); follow_barrier_uses(n, ctrl, uses, phase); } @@ -1708,7 +1733,7 @@ // region and at enclosing loop heads. Use the memory state // collected in memory_nodes to fix the memory graph. Update that // memory state as we go. - fixer.fix_mem(ctrl, region, init_raw_mem, raw_mem_for_ctrl, raw_mem_phi, uses); + fixer.fix_mem(ctrl, region_outer, init_raw_mem, raw_mem_for_ctrl, phi_outer, uses); } // Done expanding load-reference-barriers. assert(ShenandoahBarrierSetC2::bsc2()->state()->load_reference_barriers_count() == 0, "all load reference barrier nodes should have been replaced");