# HG changeset patch # Parent c35c467b894e4f94e1cc3b9cc7cc5edaecb14f81 [backport] 8244663: Shenandoah: C2 assertion fails in Matcher::collect_null_checks diff -r c35c467b894e -r cdd0173d906c src/share/vm/gc_implementation/shenandoah/c2/shenandoahSupport.cpp --- a/src/share/vm/gc_implementation/shenandoah/c2/shenandoahSupport.cpp Tue Dec 08 14:22:39 2020 +0100 +++ b/src/share/vm/gc_implementation/shenandoah/c2/shenandoahSupport.cpp Tue Dec 08 14:44:33 2020 +0100 @@ -1271,6 +1271,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); @@ -1299,6 +1302,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"); @@ -1321,9 +1325,33 @@ } } else { if (phase->is_dominator(projs.catchall_catchproj, c)) { - phase->igvn().rehash_node_delayed(u); - int nb = u->replace_edge(n, n_clone); - 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; } else if (!phase->is_dominator(projs.fallthrough_catchproj, c)) { phase->igvn().rehash_node_delayed(u); diff -r c35c467b894e -r cdd0173d906c test/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/shenandoah/compiler/TestShenandoahCmpPAfterCall.java Tue Dec 08 14:44:33 2020 +0100 @@ -0,0 +1,78 @@ +/* + * 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 + * + * @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 { + } +}