Skip to content

Commit

Permalink
8237837: Shenandoah: assert(mem == __null) failed: only one safepoint
Browse files Browse the repository at this point in the history
Reviewed-by: rkennke
  • Loading branch information
rwestrel committed Jan 28, 2020
1 parent a59ed93 commit 8c0fab8
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 20 deletions.
58 changes: 38 additions & 20 deletions src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2014,21 +2014,22 @@ void ShenandoahBarrierC2Support::optimize_after_expansion(VectorSet &visited, No
if (loop != phase->ltree_root() && if (loop != phase->ltree_root() &&
loop->_child == NULL && loop->_child == NULL &&
!loop->_irreducible) { !loop->_irreducible) {
LoopNode* head = loop->_head->as_Loop(); Node* head = loop->_head;
if ((!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) && if (head->is_Loop() &&
(!head->is_CountedLoop() || head->as_CountedLoop()->is_main_loop() || head->as_CountedLoop()->is_normal_loop()) &&
!seen.test_set(head->_idx)) { !seen.test_set(head->_idx)) {
IfNode* iff = find_unswitching_candidate(loop, phase); IfNode* iff = find_unswitching_candidate(loop, phase);
if (iff != NULL) { if (iff != NULL) {
Node* bol = iff->in(1); Node* bol = iff->in(1);
if (head->is_strip_mined()) { if (head->as_Loop()->is_strip_mined()) {
head->verify_strip_mined(0); head->as_Loop()->verify_strip_mined(0);
} }
move_heap_stable_test_out_of_loop(iff, phase); move_heap_stable_test_out_of_loop(iff, phase);


AutoNodeBudget node_budget(phase); AutoNodeBudget node_budget(phase);


if (loop->policy_unswitching(phase)) { if (loop->policy_unswitching(phase)) {
if (head->is_strip_mined()) { if (head->as_Loop()->is_strip_mined()) {
OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop(); OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop();
hide_strip_mined_loop(outer, head->as_CountedLoop(), phase); hide_strip_mined_loop(outer, head->as_CountedLoop(), phase);
} }
Expand Down Expand Up @@ -2296,7 +2297,12 @@ void MemoryGraphFixer::collect_memory_nodes() {
if (in_opc == Op_Return || in_opc == Op_Rethrow) { if (in_opc == Op_Return || in_opc == Op_Rethrow) {
mem = in->in(TypeFunc::Memory); mem = in->in(TypeFunc::Memory);
} else if (in_opc == Op_Halt) { } else if (in_opc == Op_Halt) {
if (!in->in(0)->is_Region()) { if (in->in(0)->is_Region()) {
Node* r = in->in(0);
for (uint j = 1; j < r->req(); j++) {
assert(r->in(j)->Opcode() != Op_NeverBranch, "");
}
} else {
Node* proj = in->in(0); Node* proj = in->in(0);
assert(proj->is_Proj(), ""); assert(proj->is_Proj(), "");
Node* in = proj->in(0); Node* in = proj->in(0);
Expand All @@ -2308,25 +2314,37 @@ void MemoryGraphFixer::collect_memory_nodes() {
assert(call->is_Call(), ""); assert(call->is_Call(), "");
mem = call->in(TypeFunc::Memory); mem = call->in(TypeFunc::Memory);
} else if (in->Opcode() == Op_NeverBranch) { } else if (in->Opcode() == Op_NeverBranch) {
ResourceMark rm; Node* head = in->in(0);
Unique_Node_List wq; assert(head->is_Region() && head->req() == 3, "unexpected infinite loop graph shape");
wq.push(in); assert(_phase->is_dominator(head, head->in(1)) || _phase->is_dominator(head, head->in(2)), "no back branch?");
wq.push(in->as_Multi()->proj_out(0)); Node* tail = _phase->is_dominator(head, head->in(1)) ? head->in(1) : head->in(2);
for (uint j = 1; j < wq.size(); j++) { Node* c = tail;
Node* c = wq.at(j); while (c != head) {
assert(!c->is_Root(), "shouldn't leave loop"); if (c->is_SafePoint() && !c->is_CallLeaf()) {
if (c->is_SafePoint()) {
assert(mem == NULL, "only one safepoint");
mem = c->in(TypeFunc::Memory); mem = c->in(TypeFunc::Memory);
} }
for (DUIterator_Fast kmax, k = c->fast_outs(kmax); k < kmax; k++) { c = _phase->idom(c);
Node* u = c->fast_out(k); }
if (u->is_CFG()) { assert(mem != NULL, "should have found safepoint");
wq.push(u);
Node* phi_mem = NULL;
for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
Node* u = head->fast_out(j);
if (u->is_Phi() && u->bottom_type() == Type::MEMORY) {
if (_phase->C->get_alias_index(u->adr_type()) == _alias) {
assert(phi_mem == NULL || phi_mem->adr_type() == TypePtr::BOTTOM, "");
phi_mem = u;
} else if (u->adr_type() == TypePtr::BOTTOM) {
assert(phi_mem == NULL || _phase->C->get_alias_index(phi_mem->adr_type()) == _alias, "");
if (phi_mem == NULL) {
phi_mem = u;
}
} }
} }
} }
assert(mem != NULL, "should have found safepoint"); if (phi_mem != NULL) {
mem = phi_mem;
}
} }
} }
} else { } else {
Expand Down
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2020, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test
* @bug 8237837
* @summary Shenandoah: assert(mem == __null) failed: only one safepoint
* @key gc
* @requires vm.flavor == "server"
* @requires vm.gc.Shenandoah & !vm.graal.enabled
*
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test -XX:CompileCommand=quiet BarrierInInfiniteLoop
*
*/

public class BarrierInInfiniteLoop {
private static Object field1 = new Object();
private static Object field2 = new Object();

public static void main(String[] args) {
test(false);
}

private static void test(boolean flag) {
if (flag) {
for (;;) {
field1 = field2;
}
}
}
}

0 comments on commit 8c0fab8

Please sign in to comment.