From c51a086ce32dd4e97aa83dfba3bcf9b0636193cc Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Fri, 18 Oct 2024 06:46:23 +0000 Subject: [PATCH] 8339694: ciTypeFlow does not correctly handle unresolved constant dynamic of array type Reviewed-by: kvn, vlivanov --- src/hotspot/share/ci/ciTypeFlow.cpp | 11 +++- src/hotspot/share/opto/parse2.cpp | 25 ++------ test/hotspot/jtreg/ProblemList-Xcomp.txt | 2 - .../c2/TestUnresolvedConstantDynamic.java | 42 +++++++++++++ .../TestUnresolvedConstantDynamicHelper.jasm | 61 +++++++++++++++++++ 5 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamic.java create mode 100644 test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamicHelper.jasm diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 520eeeb10d5..2d80a18f16b 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -720,12 +720,18 @@ void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) { void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) { if (str->is_in_error()) { trap(str, nullptr, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled, - Deoptimization::Action_none)); + Deoptimization::Action_none)); return; } ciConstant con = str->get_constant(); if (con.is_valid()) { int cp_index = str->get_constant_pool_index(); + if (!con.is_loaded()) { + trap(str, nullptr, Deoptimization::make_trap_request(Deoptimization::Reason_unloaded, + Deoptimization::Action_reinterpret, + cp_index)); + return; + } BasicType basic_type = str->get_basic_type_for_constant_at(cp_index); if (is_reference_type(basic_type)) { ciObject* obj = con.as_object(); @@ -2207,11 +2213,10 @@ bool ciTypeFlow::can_trap(ciBytecodeStream& str) { if (!Bytecodes::can_trap(str.cur_bc())) return false; switch (str.cur_bc()) { - // %%% FIXME: ldc of Class can generate an exception case Bytecodes::_ldc: case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: - return str.is_in_error(); + return str.is_in_error() || !str.get_constant().is_loaded(); case Bytecodes::_aload_0: // These bytecodes can trap for rewriting. We need to assume that diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 6b7cb4eaa99..d428024e53e 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -1958,26 +1958,13 @@ void Parse::do_one_bytecode() { case Bytecodes::_ldc: case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: { + // ciTypeFlow should trap if the ldc is in error state or if the constant is not loaded + assert(!iter().is_in_error(), "ldc is in error state"); ciConstant constant = iter().get_constant(); - if (constant.is_loaded()) { - const Type* con_type = Type::make_from_constant(constant); - if (con_type != nullptr) { - push_node(con_type->basic_type(), makecon(con_type)); - } - } else { - // If the constant is unresolved or in error state, run this BC in the interpreter. - if (iter().is_in_error()) { - uncommon_trap(Deoptimization::make_trap_request(Deoptimization::Reason_unhandled, - Deoptimization::Action_none), - nullptr, "constant in error state", true /* must_throw */); - - } else { - int index = iter().get_constant_pool_index(); - uncommon_trap(Deoptimization::make_trap_request(Deoptimization::Reason_unloaded, - Deoptimization::Action_reinterpret, - index), - nullptr, "unresolved constant", false /* must_throw */); - } + assert(constant.is_loaded(), "constant is not loaded"); + const Type* con_type = Type::make_from_constant(constant); + if (con_type != nullptr) { + push_node(con_type->basic_type(), makecon(con_type)); } break; } diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index 1d3342f9b7e..6df68c1ed62 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -55,5 +55,3 @@ vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all compiler/cha/TypeProfileFinalMethod.java 8341039 generic-all gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64 - -runtime/condy/escapeAnalysis/TestEscapeCondy.java 8339694 generic-all diff --git a/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamic.java b/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamic.java new file mode 100644 index 00000000000..e5879eb88a1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamic.java @@ -0,0 +1,42 @@ +/* + * 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 8339694 + * @summary Test compilation of unresolved constant dynamics. + * @library /test/lib + * @compile TestUnresolvedConstantDynamicHelper.jasm + * @run driver TestUnresolvedConstantDynamic + * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:CompileCommand=compileonly,TestUnresolvedConstantDynamicHelper::test* TestUnresolvedConstantDynamic + */ + +import jdk.test.lib.Asserts; + +public class TestUnresolvedConstantDynamic { + + public static void main(String[] args) { + Asserts.assertEquals(TestUnresolvedConstantDynamicHelper.testBooleanArray(true)[0], true); + Asserts.assertEquals(TestUnresolvedConstantDynamicHelper.testStringArray("42")[0], "42"); + } +} diff --git a/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamicHelper.jasm b/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamicHelper.jasm new file mode 100644 index 00000000000..e633065b26d --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestUnresolvedConstantDynamicHelper.jasm @@ -0,0 +1,61 @@ +/* + * 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. + * + */ + +public class TestUnresolvedConstantDynamicHelper version 55:0 { + public Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + private static Method newBooleanArray:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z" stack 1 locals 3 { + iconst_1; + newarray boolean; + areturn; + } + + private static Method newStringArray:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/String;" stack 1 locals 3 { + iconst_1; + anewarray class java/lang/String; + areturn; + } + + public static Method testBooleanArray:"(Z)[Z" stack 4 locals 2 { + ldc Dynamic REF_invokeStatic:TestUnresolvedConstantDynamicHelper.newBooleanArray:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Z":name:"[Z"; + dup; + iconst_0; + iload_0; + bastore; + areturn; + } + + public static Method testStringArray:"(Ljava/lang/String;)[Ljava/lang/String;" stack 4 locals 2 { + ldc Dynamic REF_invokeStatic:TestUnresolvedConstantDynamicHelper.newStringArray:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/String;":name:"[Ljava/lang/String;"; + dup; + iconst_0; + aload_0; + aastore; + areturn; + } +}