8339694: ciTypeFlow does not correctly handle unresolved constant dynamic of array type
Reviewed-by: kvn, vlivanov
This commit is contained in:
parent
7f4ed5001e
commit
c51a086ce3
@ -720,12 +720,18 @@ void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) {
|
|||||||
void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) {
|
void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) {
|
||||||
if (str->is_in_error()) {
|
if (str->is_in_error()) {
|
||||||
trap(str, nullptr, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled,
|
trap(str, nullptr, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled,
|
||||||
Deoptimization::Action_none));
|
Deoptimization::Action_none));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ciConstant con = str->get_constant();
|
ciConstant con = str->get_constant();
|
||||||
if (con.is_valid()) {
|
if (con.is_valid()) {
|
||||||
int cp_index = str->get_constant_pool_index();
|
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);
|
BasicType basic_type = str->get_basic_type_for_constant_at(cp_index);
|
||||||
if (is_reference_type(basic_type)) {
|
if (is_reference_type(basic_type)) {
|
||||||
ciObject* obj = con.as_object();
|
ciObject* obj = con.as_object();
|
||||||
@ -2207,11 +2213,10 @@ bool ciTypeFlow::can_trap(ciBytecodeStream& str) {
|
|||||||
if (!Bytecodes::can_trap(str.cur_bc())) return false;
|
if (!Bytecodes::can_trap(str.cur_bc())) return false;
|
||||||
|
|
||||||
switch (str.cur_bc()) {
|
switch (str.cur_bc()) {
|
||||||
// %%% FIXME: ldc of Class can generate an exception
|
|
||||||
case Bytecodes::_ldc:
|
case Bytecodes::_ldc:
|
||||||
case Bytecodes::_ldc_w:
|
case Bytecodes::_ldc_w:
|
||||||
case Bytecodes::_ldc2_w:
|
case Bytecodes::_ldc2_w:
|
||||||
return str.is_in_error();
|
return str.is_in_error() || !str.get_constant().is_loaded();
|
||||||
|
|
||||||
case Bytecodes::_aload_0:
|
case Bytecodes::_aload_0:
|
||||||
// These bytecodes can trap for rewriting. We need to assume that
|
// These bytecodes can trap for rewriting. We need to assume that
|
||||||
|
@ -1958,26 +1958,13 @@ void Parse::do_one_bytecode() {
|
|||||||
case Bytecodes::_ldc:
|
case Bytecodes::_ldc:
|
||||||
case Bytecodes::_ldc_w:
|
case Bytecodes::_ldc_w:
|
||||||
case Bytecodes::_ldc2_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();
|
ciConstant constant = iter().get_constant();
|
||||||
if (constant.is_loaded()) {
|
assert(constant.is_loaded(), "constant is not loaded");
|
||||||
const Type* con_type = Type::make_from_constant(constant);
|
const Type* con_type = Type::make_from_constant(constant);
|
||||||
if (con_type != nullptr) {
|
if (con_type != nullptr) {
|
||||||
push_node(con_type->basic_type(), makecon(con_type));
|
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 */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -55,5 +55,3 @@ vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all
|
|||||||
compiler/cha/TypeProfileFinalMethod.java 8341039 generic-all
|
compiler/cha/TypeProfileFinalMethod.java 8341039 generic-all
|
||||||
|
|
||||||
gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64
|
gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64
|
||||||
|
|
||||||
runtime/condy/escapeAnalysis/TestEscapeCondy.java 8339694 generic-all
|
|
||||||
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user