changeset 59312:1688221b62ab

8244663: Shenandoah: C2 assertion fails in Matcher::collect_null_checks Reviewed-by: shade
author roland
date Fri, 15 May 2020 21:54:28 +0200
parents da9d92098f44
children 5747b0588472
files src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java
diffstat 2 files changed, 111 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 15 20:38:28 2020 +0100
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Fri May 15 21:54:28 2020 +0200
@@ -1178,6 +1178,9 @@
       CallProjections projs;
       call->extract_projections(&projs, false, false);
 
+#ifdef ASSERT
+      VectorSet cloned(Thread::current()->resource_area());
+#endif
       Node* lrb_clone = lrb->clone();
       phase->register_new_node(lrb_clone, projs.catchall_catchproj);
       phase->set_ctrl(lrb, projs.fallthrough_catchproj);
@@ -1206,6 +1209,7 @@
             stack.set_index(idx+1);
             assert(!u->is_CFG(), "");
             stack.push(u, 0);
+            assert(!cloned.test_set(u->_idx), "only one clone");
             Node* u_clone = u->clone();
             int nb = u_clone->replace_edge(n, n_clone);
             assert(nb > 0, "should have replaced some uses");
@@ -1233,9 +1237,33 @@
                 assert(nb > 0, "should have replaced some uses");
                 replaced = true;
               } else if (!phase->is_dominator(projs.fallthrough_catchproj, c)) {
-                phase->igvn().rehash_node_delayed(u);
-                int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
-                assert(nb > 0, "should have replaced some uses");
+                if (u->is_If()) {
+                  // Can't break If/Bool/Cmp chain
+                  assert(n->is_Bool(), "unexpected If shape");
+                  assert(stack.node_at(stack.size()-2)->is_Cmp(), "unexpected If shape");
+                  assert(n_clone->is_Bool(), "unexpected clone");
+                  assert(clones.at(clones.size()-2)->is_Cmp(), "unexpected clone");
+                  Node* bol_clone = n->clone();
+                  Node* cmp_clone = stack.node_at(stack.size()-2)->clone();
+                  bol_clone->set_req(1, cmp_clone);
+
+                  Node* nn = stack.node_at(stack.size()-3);
+                  Node* nn_clone = clones.at(clones.size()-3);
+                  assert(nn->Opcode() == nn_clone->Opcode(), "mismatch");
+
+                  int nb = cmp_clone->replace_edge(nn, create_phis_on_call_return(ctrl, c, nn, nn_clone, projs, phase));
+                  assert(nb > 0, "should have replaced some uses");
+
+                  phase->register_new_node(bol_clone, u->in(0));
+                  phase->register_new_node(cmp_clone, u->in(0));
+
+                  phase->igvn().replace_input_of(u, 1, bol_clone);
+
+                } else {
+                  phase->igvn().rehash_node_delayed(u);
+                  int nb = u->replace_edge(n, create_phis_on_call_return(ctrl, c, n, n_clone, projs, phase));
+                  assert(nb > 0, "should have replaced some uses");
+                }
                 replaced = true;
               }
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java	Fri May 15 21:54:28 2020 +0200
@@ -0,0 +1,80 @@
+/*
+ * 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 8244663
+ * @summary Shenandoah: C2 assertion fails in Matcher::collect_null_checks
+ * @key gc
+ * @requires vm.flavor == "server"
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement
+ *                   -XX:CompileCommand=dontinline,TestShenandoahCmpPAfterCall::not_inlined TestShenandoahCmpPAfterCall
+ *
+ */
+
+public class TestShenandoahCmpPAfterCall {
+    private static Object field1 = new Object();
+    private static Object field2 = new Object();
+    private static Object o3;
+    private static volatile int barrier;
+
+    public static void main(String[] args) {
+        for (int i = 0; i < 20_000; i++) {
+            test();
+        }
+    }
+
+    private static void test() {
+        Object o1 = null;
+        Object o2 = field2;
+        try {
+            not_inlined();
+            o1 = field1;
+            if (o1 == o2) {
+
+            }
+        } catch (Exception1 ex1) {
+            o1 = field1;
+            if (o1 == o2) {
+
+            }
+        }
+        barrier = 42;
+        if (o1 == o2) {
+
+        }
+    }
+
+    static int count = 0;
+    private static void not_inlined() throws Exception1 {
+        count++;
+        if ((count % 100) == 0) {
+            throw new Exception1();
+        }
+    }
+
+    private static class Exception1 extends Exception {
+    }
+}