8339694: ciTypeFlow does not correctly handle unresolved constant dynamic of array type

Reviewed-by: kvn, vlivanov
This commit is contained in:
Tobias Hartmann 2024-10-18 06:46:23 +00:00
parent 7f4ed5001e
commit c51a086ce3
5 changed files with 117 additions and 24 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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");
}
}

View File

@ -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 "<init>":"()V" stack 1 locals 1 {
aload_0;
invokespecial Method java/lang/Object."<init>":"()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;
}
}