8244721: CTW: C2 (Shenandoah) compilation fails with "unexpected infinite loop graph shape"

Reviewed-by: shade
This commit is contained in:
Roland Westrelin 2020-05-15 10:24:38 +02:00
parent b61c88c693
commit 35a7eff951
2 changed files with 58 additions and 17 deletions

View File

@ -2101,17 +2101,7 @@ void MemoryGraphFixer::collect_memory_nodes() {
mem = call->in(TypeFunc::Memory);
} else if (in->Opcode() == Op_NeverBranch) {
Node* head = in->in(0);
assert(head->is_Region() && head->req() == 3, "unexpected infinite loop graph shape");
assert(_phase->is_dominator(head, head->in(1)) || _phase->is_dominator(head, head->in(2)), "no back branch?");
Node* tail = _phase->is_dominator(head, head->in(1)) ? head->in(1) : head->in(2);
Node* c = tail;
while (c != head) {
if (c->is_SafePoint() && !c->is_CallLeaf()) {
mem = c->in(TypeFunc::Memory);
}
c = _phase->idom(c);
}
assert(mem != NULL, "should have found safepoint");
assert(head->is_Region(), "unexpected infinite loop graph shape");
Node* phi_mem = NULL;
for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
@ -2128,7 +2118,28 @@ void MemoryGraphFixer::collect_memory_nodes() {
}
}
}
if (phi_mem != NULL) {
if (phi_mem == NULL) {
for (uint j = 1; j < head->req(); j++) {
Node* tail = head->in(j);
if (!_phase->is_dominator(head, tail)) {
continue;
}
Node* c = tail;
while (c != head) {
if (c->is_SafePoint() && !c->is_CallLeaf()) {
Node* m =c->in(TypeFunc::Memory);
if (m->is_MergeMem()) {
m = m->as_MergeMem()->memory_at(_alias);
}
assert(mem == NULL || mem == m, "several memory states");
mem = m;
}
c = _phase->idom(c);
}
assert(mem != NULL, "should have found safepoint");
}
assert(mem != NULL, "should have found safepoint");
} else {
mem = phi_mem;
}
}
@ -2237,7 +2248,7 @@ void MemoryGraphFixer::collect_memory_nodes() {
assert(m != NULL || (c->is_Loop() && j == LoopNode::LoopBackControl && iteration == 1) || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "expect memory state");
if (m != NULL) {
if (m == prev_region && ((c->is_Loop() && j == LoopNode::LoopBackControl) || (prev_region->is_Phi() && prev_region->in(0) == c))) {
assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop(), "");
assert(c->is_Loop() && j == LoopNode::LoopBackControl || _phase->C->has_irreducible_loop() || has_never_branch(_phase->C->root()), "");
// continue
} else if (unique == NULL) {
unique = m;

View File

@ -23,29 +23,59 @@
/**
* @test
* @bug 8237837
* @bug 8237837 8244721
* @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
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xcomp -XX:CompileOnly=BarrierInInfiniteLoop::test1
* -XX:CompileOnly=BarrierInInfiniteLoop::test2 -XX:CompileOnly=BarrierInInfiniteLoop::test3 -XX:CompileCommand=quiet BarrierInInfiniteLoop
*
*/
public class BarrierInInfiniteLoop {
private static Object field1 = new Object();
private static Object field2 = new Object();
private static int field3;
public static void main(String[] args) {
test(false);
test1(false);
test2(false, false);
test3(false);
}
private static void test(boolean flag) {
private static void test1(boolean flag) {
if (flag) {
for (;;) {
field1 = field2;
}
}
}
private static void test2(boolean flag1, boolean flag2) {
if (flag1) {
for (;;) {
for (;;) {
if (flag2) {
break;
}
field1 = field2;
}
}
}
}
private static void test3(boolean flag) {
if (flag) {
for (;;) {
for (;;) {
field3 = 42;
if (field1 == field2) {
break;
}
}
}
}
}
}