# HG changeset patch # User roland # Date 1531489494 -7200 # Node ID ad9d95f1a1f6380d0c96f842e2b37d119fec90c2 # Parent 2282560a3d29f58dbfcaf3300f54774e896d2895 8200282: Serializing non-zero byte as zero to ByteBuffer Summary: arraycopy converted as a series of loads/stores uses wrong slice for loads Reviewed-by: kvn, thartmann diff -r 2282560a3d29 -r ad9d95f1a1f6 src/hotspot/share/opto/arraycopynode.cpp --- a/src/hotspot/share/opto/arraycopynode.cpp Fri Jul 13 07:08:59 2018 -0700 +++ b/src/hotspot/share/opto/arraycopynode.cpp Fri Jul 13 15:44:54 2018 +0200 @@ -366,6 +366,9 @@ if (!forward_ctl->is_top()) { // copy forward mem = start_mem_dest; + uint alias_idx_src = phase->C->get_alias_index(atp_src); + uint alias_idx_dest = phase->C->get_alias_index(atp_dest); + bool same_alias = (alias_idx_src == alias_idx_dest); if (count > 0) { Node* v = LoadNode::make(*phase, forward_ctl, start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered); @@ -376,7 +379,7 @@ Node* off = phase->MakeConX(type2aelembytes(copy_type) * i); Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off)); Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off)); - v = LoadNode::make(*phase, forward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered); + v = LoadNode::make(*phase, forward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered); v = phase->transform(v); mem = StoreNode::make(*phase, forward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered); mem = phase->transform(mem); @@ -408,18 +411,21 @@ if (!backward_ctl->is_top()) { // copy backward mem = start_mem_dest; + uint alias_idx_src = phase->C->get_alias_index(atp_src); + uint alias_idx_dest = phase->C->get_alias_index(atp_dest); + bool same_alias = (alias_idx_src == alias_idx_dest); if (count > 0) { for (int i = count-1; i >= 1; i--) { Node* off = phase->MakeConX(type2aelembytes(copy_type) * i); Node* next_src = phase->transform(new AddPNode(base_src,adr_src,off)); Node* next_dest = phase->transform(new AddPNode(base_dest,adr_dest,off)); - Node* v = LoadNode::make(*phase, backward_ctl, mem, next_src, atp_src, value_type, copy_type, MemNode::unordered); + Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, next_src, atp_src, value_type, copy_type, MemNode::unordered); v = phase->transform(v); mem = StoreNode::make(*phase, backward_ctl,mem,next_dest,atp_dest,v, copy_type, MemNode::unordered); mem = phase->transform(mem); } - Node* v = LoadNode::make(*phase, backward_ctl, mem, adr_src, atp_src, value_type, copy_type, MemNode::unordered); + Node* v = LoadNode::make(*phase, backward_ctl, same_alias ? mem : start_mem_src, adr_src, atp_src, value_type, copy_type, MemNode::unordered); v = phase->transform(v); mem = StoreNode::make(*phase, backward_ctl, mem, adr_dest, atp_dest, v, copy_type, MemNode::unordered); mem = phase->transform(mem); diff -r 2282560a3d29 -r ad9d95f1a1f6 test/hotspot/jtreg/compiler/arraycopy/ACasLoadsStoresBadMem.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/arraycopy/ACasLoadsStoresBadMem.java Fri Jul 13 15:44:54 2018 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, 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 8200282 + * @summary arraycopy converted as a series of loads/stores uses wrong slice for loads + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,ACasLoadsStoresBadMem::not_inlined ACasLoadsStoresBadMem + * + */ + +public class ACasLoadsStoresBadMem { + public static void main(String[] args) { + int[] dst = new int[5]; + for (int i = 0; i < 20_000; i++) { + test1(dst, 1); + for (int j = 1; j < 5; j++) { + if (dst[j] != j) { + throw new RuntimeException("Bad copy "); + } + } + } + } + + private static void test1(int[] dst, int dstPos) { + int[] src = new int[4]; + not_inlined(); + src[0] = 1; + src[1] = 2; + src[2] = 3; + src[3] = 4; + System.arraycopy(src, 0, dst, dstPos, 4); + } + + private static void not_inlined() { + } +}