From 4e77cf881d031e5b0320915b3eabd7702e560291 Mon Sep 17 00:00:00 2001 From: Cesar Soares Lucas Date: Wed, 15 May 2024 01:46:22 +0000 Subject: [PATCH] 8330795: C2: assert((uint)type <= T_CONFLICT && _zero_type[type] != nullptr) failed: bad type with -XX:-UseCompressedClassPointers Reviewed-by: kvn --- src/hotspot/share/opto/escape.cpp | 4 +- .../c2/TestReduceAllocationAndLoadKlass.java | 64 +++++++++++++ .../AllocationMergesTests.java | 92 +++++++++++++++---- 3 files changed, 138 insertions(+), 22 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestReduceAllocationAndLoadKlass.java diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp index 71051ee7bd1..4b328806122 100644 --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -548,8 +548,8 @@ bool ConnectionGraph::can_reduce_check_users(Node* n, uint nesting) const { if (!use_use->is_Load() || !use_use->as_Load()->can_split_through_phi_base(_igvn)) { NOT_PRODUCT(if (TraceReduceAllocationMerges) tty->print_cr("Can NOT reduce Phi %d on invocation %d. AddP user isn't a [splittable] Load(): %s", n->_idx, _invocation, use_use->Name());) return false; - } else if (nesting > 0 && load_type->isa_narrowklass()) { - NOT_PRODUCT(if (TraceReduceAllocationMerges) tty->print_cr("Can NOT reduce Phi %d on invocation %d. Nested NarrowKlass Load: %s", n->_idx, _invocation, use_use->Name());) + } else if (load_type->isa_narrowklass() || load_type->isa_klassptr()) { + NOT_PRODUCT(if (TraceReduceAllocationMerges) tty->print_cr("Can NOT reduce Phi %d on invocation %d. [Narrow] Klass Load: %s", n->_idx, _invocation, use_use->Name());) return false; } } diff --git a/test/hotspot/jtreg/compiler/c2/TestReduceAllocationAndLoadKlass.java b/test/hotspot/jtreg/compiler/c2/TestReduceAllocationAndLoadKlass.java new file mode 100644 index 00000000000..e3515eaa20b --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestReduceAllocationAndLoadKlass.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. 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 8330795 + * @summary Check that Reduce Allocation Merges doesn't crash when CompressedClassPointers + * is disabled and there is an access to Klass "field" through the phi. + * @requires vm.bits == 64 & vm.flagless & vm.compiler2.enabled & vm.opt.final.EliminateAllocations + * @run main/othervm -XX:CompileCommand=dontinline,*TestReduceAllocationAndLoadKlass*::test + * -XX:CompileCommand=compileonly,*TestReduceAllocationAndLoadKlass*::test + * -XX:CompileCommand=compileonly,*Shape*::*init* + * -XX:CompileCommand=compileonly,*Point*::*init* + * -XX:CompileCommand=exclude,*TestReduceAllocationAndLoadKlass*::dummy + * -XX:-TieredCompilation + * -XX:-UseCompressedClassPointers + * -Xbatch + * -Xcomp + * -server + * compiler.c2.TestReduceAllocationAndLoadKlass + */ + +package compiler.c2; + +public class TestReduceAllocationAndLoadKlass { + public static void main(String[] args) { + Point p = new Point(); + Line q = new Line(); + + test(true); + test(false); + } + + static Class test(boolean cond) { + Object p = cond ? dummy() : new Line(); + return p.getClass(); + } + + static Point dummy() { return new Point(); } + + static class Shape { } + static class Point extends Shape { } + static class Line extends Shape { } +} diff --git a/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/AllocationMergesTests.java b/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/AllocationMergesTests.java index a3bbf0f4c33..cd3d5329771 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/AllocationMergesTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/AllocationMergesTests.java @@ -31,7 +31,7 @@ import compiler.lib.ir_framework.*; * @bug 8281429 * @summary Tests that C2 can correctly scalar replace some object allocation merges. * @library /test/lib / - * @requires vm.debug == true & vm.bits == 64 & vm.compiler2.enabled & vm.opt.final.UseCompressedOops & vm.opt.final.EliminateAllocations + * @requires vm.debug == true & vm.flagless & vm.bits == 64 & vm.compiler2.enabled & vm.opt.final.EliminateAllocations * @run driver compiler.c2.irTests.scalarReplacement.AllocationMergesTests */ public class AllocationMergesTests { @@ -39,15 +39,44 @@ public class AllocationMergesTests { private static Point global_escape = new Point(2022, 2023); public static void main(String[] args) { - TestFramework.runWithFlags("-XX:+UnlockDiagnosticVMOptions", - "-XX:+ReduceAllocationMerges", - "-XX:+TraceReduceAllocationMerges", - "-XX:+DeoptimizeALot", - "-XX:CompileCommand=inline,*::charAt*", - "-XX:CompileCommand=inline,*PicturePositions::*", - "-XX:CompileCommand=inline,*Point::*", - "-XX:CompileCommand=inline,*Nested::*", - "-XX:CompileCommand=exclude,*::dummy*"); + TestFramework framework = new TestFramework(); + + Scenario scenario0 = new Scenario(0, "-XX:+UnlockDiagnosticVMOptions", + "-XX:+ReduceAllocationMerges", + "-XX:+TraceReduceAllocationMerges", + "-XX:+DeoptimizeALot", + "-XX:+UseCompressedOops", + "-XX:+UseCompressedClassPointers", + "-XX:CompileCommand=inline,*::charAt*", + "-XX:CompileCommand=inline,*PicturePositions::*", + "-XX:CompileCommand=inline,*Point::*", + "-XX:CompileCommand=inline,*Nested::*", + "-XX:CompileCommand=exclude,*::dummy*"); + + Scenario scenario1 = new Scenario(1, "-XX:+UnlockDiagnosticVMOptions", + "-XX:+ReduceAllocationMerges", + "-XX:+TraceReduceAllocationMerges", + "-XX:+DeoptimizeALot", + "-XX:+UseCompressedOops", + "-XX:-UseCompressedClassPointers", + "-XX:CompileCommand=inline,*::charAt*", + "-XX:CompileCommand=inline,*PicturePositions::*", + "-XX:CompileCommand=inline,*Point::*", + "-XX:CompileCommand=inline,*Nested::*", + "-XX:CompileCommand=exclude,*::dummy*"); + + Scenario scenario2 = new Scenario(2, "-XX:+UnlockDiagnosticVMOptions", + "-XX:+ReduceAllocationMerges", + "-XX:+TraceReduceAllocationMerges", + "-XX:+DeoptimizeALot", + "-XX:-UseCompressedOops", + "-XX:CompileCommand=inline,*::charAt*", + "-XX:CompileCommand=inline,*PicturePositions::*", + "-XX:CompileCommand=inline,*Point::*", + "-XX:CompileCommand=inline,*Nested::*", + "-XX:CompileCommand=exclude,*::dummy*"); + + framework.addScenarios(scenario0, scenario1, scenario2).start(); } // ------------------ No Scalar Replacement Should Happen in The Tests Below ------------------- // @@ -94,7 +123,8 @@ public class AllocationMergesTests { "testSRAndNSR_Trap_C2", "testString_one_C2", "testString_two_C2", - "testLoadNarrowKlass_C2", + "testLoadKlassFromCast_C2", + "testLoadKlassFromPhi_C2", "testReReduce_C2" }) public void runner(RunInfo info) { @@ -150,7 +180,8 @@ public class AllocationMergesTests { Asserts.assertEQ(testSRAndNSR_NoTrap_Interp(cond1, x, y), testSRAndNSR_NoTrap_C2(cond1, x, y)); Asserts.assertEQ(testString_one_Interp(cond1), testString_one_C2(cond1)); Asserts.assertEQ(testString_two_Interp(cond1), testString_two_C2(cond1)); - Asserts.assertEQ(testLoadNarrowKlass_Interp(cond1), testLoadNarrowKlass_C2(cond1)); + Asserts.assertEQ(testLoadKlassFromCast_Interp(cond1), testLoadKlassFromCast_C2(cond1)); + Asserts.assertEQ(testLoadKlassFromPhi_Interp(cond1), testLoadKlassFromPhi_C2(cond1)); Asserts.assertEQ(testReReduce_Interp(cond1, x, y), testReReduce_C2(cond1, x, y)); Asserts.assertEQ(testSRAndNSR_Trap_Interp(false, cond1, cond2, x, y), @@ -771,10 +802,11 @@ public class AllocationMergesTests { } @Test - @IR(counts = { IRNode.ALLOC, "2" } ) + @IR(counts = { IRNode.ALLOC, "2" }, applyIf = {"UseCompressedOops", "true"} ) + @IR(failOn = { IRNode.ALLOC }, applyIf = {"UseCompressedOops", "false"} ) // The two Picture objects will be removed. The nested Point objects won't - // be removed because the Phi merging them will have a DecodeN user - which - // currently isn't supported. + // be removed, if CompressedOops is enabled, because the Phi merging them will + // have a DecodeN user - which currently isn't supported. int testNestedObjectsNoEscapeObject_C2(boolean cond, int x, int y) { return testNestedObjectsNoEscapeObject(cond, x, y); } @DontCompile @@ -1258,7 +1290,7 @@ public class AllocationMergesTests { // ------------------------------------------------------------------------- @ForceInline - Class testLoadNarrowKlass(boolean cond1) { + Class testLoadKlassFromCast(boolean cond1) { Object p = new Circle(10); if (cond1) { @@ -1270,12 +1302,32 @@ public class AllocationMergesTests { @Test @IR(counts = { IRNode.ALLOC, "1" }) - // The allocation won't be reduced because we don't support NarrowKlass - // loads under CastPPs. - Class testLoadNarrowKlass_C2(boolean cond1) { return testLoadNarrowKlass(cond1); } + // The allocation won't be reduced because we don't support [Narrow]Klass loads + Class testLoadKlassFromCast_C2(boolean cond1) { return testLoadKlassFromCast(cond1); } @DontCompile - Class testLoadNarrowKlass_Interp(boolean cond1) { return testLoadNarrowKlass(cond1); } + Class testLoadKlassFromCast_Interp(boolean cond1) { return testLoadKlassFromCast(cond1); } + + // ------------------------------------------------------------------------- + + @ForceInline + Class testLoadKlassFromPhi(boolean cond1) { + Shape p = new Square(20); + + if (cond1) { + p = new Circle(10); + } + + return p.getClass(); + } + + @Test + @IR(counts = { IRNode.ALLOC, "2" }) + // The allocation won't be reduced because we don't support [Narrow]Klass loads + Class testLoadKlassFromPhi_C2(boolean cond1) { return testLoadKlassFromPhi(cond1); } + + @DontCompile + Class testLoadKlassFromPhi_Interp(boolean cond1) { return testLoadKlassFromPhi(cond1); } // -------------------------------------------------------------------------