8244721: CTW: C2 (Shenandoah) compilation fails with "unexpected infinite loop graph shape"
Reviewed-by: shade
This commit is contained in:
parent
b61c88c693
commit
35a7eff951
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user