# HG changeset patch # User thartmann # Date 1465316444 -7200 # Node ID d139a133ba270086ecf4dc863663b3841c470dd6 # Parent ec2d5ec5571cdd74525cc94bf20555874824bde8 8158228: C1 incorrectly folds mismatched loads from stable arrays Summary: Disable constant folding for mismatched loads from stable arrays. Reviewed-by: vlivanov diff -r ec2d5ec5571c -r d139a133ba27 hotspot/src/share/vm/c1/c1_Canonicalizer.cpp --- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Tue Jun 07 09:11:32 2016 +0000 +++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Tue Jun 07 18:20:44 2016 +0200 @@ -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 @@ 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 @@ return; } } - - } diff -r ec2d5ec5571c -r d139a133ba27 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Jun 07 09:11:32 2016 +0000 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Tue Jun 07 18:20:44 2016 +0200 @@ -4227,11 +4227,11 @@ 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); } diff -r ec2d5ec5571c -r d139a133ba27 hotspot/src/share/vm/c1/c1_Instruction.hpp --- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Tue Jun 07 09:11:32 2016 +0000 +++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Tue Jun 07 18:20:44 2016 +0200 @@ -912,14 +912,16 @@ 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 @@ 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 @@ 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 @@ 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())); diff -r ec2d5ec5571c -r d139a133ba27 hotspot/test/compiler/stable/TestStableMismatched.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/stable/TestStableMismatched.java Tue Jun 07 18:20:44 2016 +0200 @@ -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'"); + } + } +} +