8158228: C1 incorrectly folds mismatched loads from stable arrays

Disable constant folding for mismatched loads from stable arrays.

Reviewed-by: vlivanov
This commit is contained in:
Tobias Hartmann 2016-06-07 18:20:44 +02:00
parent e8ef37ca55
commit e45caa8cba
4 changed files with 63 additions and 11 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2016, 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
@ -264,7 +264,7 @@ void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
assert(array == NULL || FoldStableValues, "not enabled");
// Constant fold loads from stable arrays.
if (array != NULL && index != NULL) {
if (!x->mismatched() && array != NULL && index != NULL) {
jint idx = index->value();
if (idx < 0 || idx >= array->value()->length()) {
// Leave the load as is. The range check will handle it.
@ -310,8 +310,6 @@ void Canonicalizer::do_StoreIndexed (StoreIndexed* x) {
return;
}
}
}

View File

@ -4227,11 +4227,11 @@ void GraphBuilder::append_char_access(ciMethod* callee, bool is_store) {
Value index = args->at(1);
if (is_store) {
Value value = args->at(2);
Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false));
Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before, false, true));
store->set_flag(Instruction::NeedsRangeCheckFlag, false);
_memory->store_value(value);
} else {
Instruction* load = append(new LoadIndexed(array, index, NULL, T_CHAR, state_before));
Instruction* load = append(new LoadIndexed(array, index, NULL, T_CHAR, state_before, true));
load->set_flag(Instruction::NeedsRangeCheckFlag, false);
push(load->type(), load);
}

View File

@ -912,14 +912,16 @@ BASE(AccessIndexed, AccessArray)
Value _index;
Value _length;
BasicType _elt_type;
bool _mismatched;
public:
// creation
AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
AccessIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before, bool mismatched)
: AccessArray(as_ValueType(elt_type), array, state_before)
, _index(index)
, _length(length)
, _elt_type(elt_type)
, _mismatched(mismatched)
{
set_flag(Instruction::NeedsRangeCheckFlag, true);
ASSERT_VALUES
@ -929,6 +931,7 @@ BASE(AccessIndexed, AccessArray)
Value index() const { return _index; }
Value length() const { return _length; }
BasicType elt_type() const { return _elt_type; }
bool mismatched() const { return _mismatched; }
void clear_length() { _length = NULL; }
// perform elimination of range checks involving constants
@ -945,8 +948,8 @@ LEAF(LoadIndexed, AccessIndexed)
public:
// creation
LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before)
: AccessIndexed(array, index, length, elt_type, state_before)
LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before, bool mismatched = false)
: AccessIndexed(array, index, length, elt_type, state_before, mismatched)
, _explicit_null_check(NULL) {}
// accessors
@ -974,8 +977,9 @@ LEAF(StoreIndexed, AccessIndexed)
public:
// creation
StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before, bool check_boolean)
: AccessIndexed(array, index, length, elt_type, state_before)
StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* state_before,
bool check_boolean, bool mismatched = false)
: AccessIndexed(array, index, length, elt_type, state_before, mismatched)
, _value(value), _profiled_method(NULL), _profiled_bci(0), _check_boolean(check_boolean)
{
set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2016, 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 TestStableMismatched
* @bug 8158228
* @summary Tests if mismatched char load from stable byte[] returns correct result
* @run main/othervm -XX:-CompactStrings -XX:TieredStopAtLevel=1 -Xcomp
* -XX:CompileOnly=TestStableMismatched::test,::charAt
* TestStableMismatched
* @run main/othervm -XX:-CompactStrings -XX:-TieredCompilation -Xcomp
* -XX:CompileOnly=TestStableMismatched::test,::charAt
* TestStableMismatched
*/
public class TestStableMismatched {
public static void main(String args[]) {
test();
}
public static void test() {
String text = "abcdefg";
// Mismatched char load from @Stable byte[] String.value field
char returned = text.charAt(6);
if (returned != 'g') {
throw new RuntimeException("failed: charAt(6) returned '" + returned + "' instead of 'g'");
}
}
}