mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8182036: Load from initializing arraycopy uses wrong memory state
Reviewed-by: kvn
This commit is contained in:
parent
7c8c0a97fc
commit
a6490b0abc
3 changed files with 71 additions and 8 deletions
|
@ -892,16 +892,22 @@ bool PhaseMacroExpand::generate_block_arraycopy(Node** ctrl, MergeMemNode** mem,
|
||||||
((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
|
((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
|
||||||
Node* sptr = basic_plus_adr(src, src_off);
|
Node* sptr = basic_plus_adr(src, src_off);
|
||||||
Node* dptr = basic_plus_adr(dest, dest_off);
|
Node* dptr = basic_plus_adr(dest, dest_off);
|
||||||
uint alias_idx = C->get_alias_index(adr_type);
|
const TypePtr* s_adr_type = _igvn.type(sptr)->is_ptr();
|
||||||
|
assert(s_adr_type->isa_aryptr(), "impossible slice");
|
||||||
|
uint s_alias_idx = C->get_alias_index(s_adr_type);
|
||||||
|
uint d_alias_idx = C->get_alias_index(adr_type);
|
||||||
bool is_mismatched = (basic_elem_type != T_INT);
|
bool is_mismatched = (basic_elem_type != T_INT);
|
||||||
Node* sval = transform_later(
|
Node* sval = transform_later(
|
||||||
LoadNode::make(_igvn, *ctrl, (*mem)->memory_at(alias_idx), sptr, adr_type,
|
LoadNode::make(_igvn, *ctrl, (*mem)->memory_at(s_alias_idx), sptr, s_adr_type,
|
||||||
TypeInt::INT, T_INT, MemNode::unordered, LoadNode::DependsOnlyOnTest,
|
TypeInt::INT, T_INT, MemNode::unordered, LoadNode::DependsOnlyOnTest,
|
||||||
false /*unaligned*/, is_mismatched));
|
false /*unaligned*/, is_mismatched));
|
||||||
Node* st = transform_later(
|
Node* st = transform_later(
|
||||||
StoreNode::make(_igvn, *ctrl, (*mem)->memory_at(alias_idx), dptr, adr_type,
|
StoreNode::make(_igvn, *ctrl, (*mem)->memory_at(d_alias_idx), dptr, adr_type,
|
||||||
sval, T_INT, MemNode::unordered));
|
sval, T_INT, MemNode::unordered));
|
||||||
(*mem)->set_memory_at(alias_idx, st);
|
if (is_mismatched) {
|
||||||
|
st->as_Store()->set_mismatched_access();
|
||||||
|
}
|
||||||
|
(*mem)->set_memory_at(d_alias_idx, st);
|
||||||
src_off += BytesPerInt;
|
src_off += BytesPerInt;
|
||||||
dest_off += BytesPerInt;
|
dest_off += BytesPerInt;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1275,12 +1281,11 @@ void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
|
||||||
// The generate_arraycopy subroutine checks this.
|
// The generate_arraycopy subroutine checks this.
|
||||||
}
|
}
|
||||||
// This is where the memory effects are placed:
|
// This is where the memory effects are placed:
|
||||||
const TypePtr* adr_type = TypeAryPtr::get_array_body_type(dest_elem);
|
const TypePtr* adr_type = NULL;
|
||||||
if (ac->_dest_type != TypeOopPtr::BOTTOM) {
|
if (ac->_dest_type != TypeOopPtr::BOTTOM) {
|
||||||
adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
|
adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
|
||||||
}
|
} else {
|
||||||
if (ac->_src_type != ac->_dest_type) {
|
adr_type = TypeAryPtr::get_array_body_type(dest_elem);
|
||||||
adr_type = TypeRawPtr::BOTTOM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,
|
generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,
|
||||||
|
|
|
@ -2429,6 +2429,7 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
Opcode() == Op_StoreVector ||
|
Opcode() == Op_StoreVector ||
|
||||||
phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
|
phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
|
||||||
(Opcode() == Op_StoreL && st->Opcode() == Op_StoreI) || // expanded ClearArrayNode
|
(Opcode() == Op_StoreL && st->Opcode() == Op_StoreI) || // expanded ClearArrayNode
|
||||||
|
(Opcode() == Op_StoreI && st->Opcode() == Op_StoreL) || // initialization by arraycopy
|
||||||
(is_mismatched_access() || st->as_Store()->is_mismatched_access()),
|
(is_mismatched_access() || st->as_Store()->is_mismatched_access()),
|
||||||
"no mismatched stores, except on raw memory: %s %s", NodeClassNames[Opcode()], NodeClassNames[st->Opcode()]);
|
"no mismatched stores, except on raw memory: %s %s", NodeClassNames[Opcode()], NodeClassNames[st->Opcode()]);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Red Hat, Inc. 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 8182036
|
||||||
|
* @summary Load from initializing arraycopy uses wrong memory state
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+StressGCM -XX:+StressLCM TestInitializingACLoadWithBadMem
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class TestInitializingACLoadWithBadMem {
|
||||||
|
static Object test_dummy;
|
||||||
|
static int test1() {
|
||||||
|
int[] src = new int[10];
|
||||||
|
test_dummy = src;
|
||||||
|
int[] dst = new int[10];
|
||||||
|
src[1] = 0x42;
|
||||||
|
// arraycopy generates a load from src/store to dst which must
|
||||||
|
// be after the store to src above.
|
||||||
|
System.arraycopy(src, 1, dst, 1, 9);
|
||||||
|
return dst[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static public void main(String[] args) {
|
||||||
|
int[] src = new int[10];
|
||||||
|
for (int i = 0; i < 20000; i++) {
|
||||||
|
int res = test1();
|
||||||
|
if (res != 0x42) {
|
||||||
|
throw new RuntimeException("bad result: " + res + " != " + 0x42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue