# HG changeset patch # User roland # Date 1499085180 -7200 # Node ID 2e49bb347cbcae82f5161af56436030524332312 # Parent 7b6570052b58fe01c2d548c9e38026e041142b9c 8182036: Load from initializing arraycopy uses wrong memory state Reviewed-by: kvn diff -r 7b6570052b58 -r 2e49bb347cbc hotspot/src/share/vm/opto/macroArrayCopy.cpp --- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp Thu Aug 03 08:16:00 2017 -0400 +++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp Mon Jul 03 14:33:00 2017 +0200 @@ -892,16 +892,22 @@ ((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 @@ // 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, diff -r 7b6570052b58 -r 2e49bb347cbc hotspot/src/share/vm/opto/memnode.cpp --- a/hotspot/src/share/vm/opto/memnode.cpp Thu Aug 03 08:16:00 2017 -0400 +++ b/hotspot/src/share/vm/opto/memnode.cpp Mon Jul 03 14:33:00 2017 +0200 @@ -2429,6 +2429,7 @@ 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()]); diff -r 7b6570052b58 -r 2e49bb347cbc hotspot/test/compiler/arraycopy/TestInitializingACLoadWithBadMem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/arraycopy/TestInitializingACLoadWithBadMem.java Mon Jul 03 14:33:00 2017 +0200 @@ -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); + } + } + } +}