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) {
|
||||
Node* sptr = basic_plus_adr(src, src_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);
|
||||
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,
|
||||
false /*unaligned*/, is_mismatched));
|
||||
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));
|
||||
(*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;
|
||||
dest_off += BytesPerInt;
|
||||
} else {
|
||||
|
@ -1275,12 +1281,11 @@ void PhaseMacroExpand::expand_arraycopy_node(ArrayCopyNode *ac) {
|
|||
// The generate_arraycopy subroutine checks this.
|
||||
}
|
||||
// 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) {
|
||||
adr_type = ac->_dest_type->add_offset(Type::OffsetBot)->is_ptr();
|
||||
}
|
||||
if (ac->_src_type != ac->_dest_type) {
|
||||
adr_type = TypeRawPtr::BOTTOM;
|
||||
} else {
|
||||
adr_type = TypeAryPtr::get_array_body_type(dest_elem);
|
||||
}
|
||||
|
||||
generate_arraycopy(ac, alloc, &ctrl, merge_mem, &io,
|
||||
|
|
|
@ -2429,6 +2429,7 @@ Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
Opcode() == Op_StoreVector ||
|
||||
phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw ||
|
||||
(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()),
|
||||
"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