--- old/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Sep 3 13:27:11 2010 +++ new/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Sep 3 13:27:11 2010 @@ -1609,7 +1609,7 @@ assert_clean_int(count, O3); // Make sure 'count' is clean int. Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; - Label L_fill_2_bytes, L_fill_4_bytes, L_fill_32_bytes; + Label L_fill_2_bytes, L_fill_elements, L_fill_32_bytes; int shift = -1; switch (t) { @@ -1635,8 +1635,8 @@ } if (t == T_SHORT) { // Zero extend value - __ sethi(0xffff0000, O3); - __ andn(value, O3, value); + __ sllx(value, 48, value); + __ srlx(value, 48, value); } if (t == T_BYTE || t == T_SHORT) { __ sllx(value, 16, O3); @@ -1644,8 +1644,8 @@ } __ cmp(count, 2<andcc(count, 1<andcc(count, 1, G0); if (!aligned && (t == T_BYTE || t == T_SHORT)) { // align source address at 4 bytes address boundary @@ -1698,7 +1698,7 @@ __ brx(Assembler::less, false, Assembler::pt, L_check_fill_8_bytes); __ delayed()->nop(); - Label L_fill_32_bytes_loop; + Label L_fill_32_bytes_loop, L_fill_4_bytes; __ align(16); __ BIND(L_fill_32_bytes_loop); @@ -1730,6 +1730,9 @@ // fill trailing 4 bytes __ andcc(count, 1<mov(G0, O0); // return 0 + __ delayed()->nop(); + + // Handle copies less than 8 bytes. Int is handled elsewhere. + if (t == T_BYTE) { + __ BIND(L_fill_elements); + Label L_fill_2, L_fill_4; + // in delay slot __ andcc(count, 1, G0); + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); + __ delayed()->andcc(count, 2, G0); + __ stb(value, to, 0); + __ inc(to, 1); + __ BIND(L_fill_2); + __ brx(Assembler::zero, false, Assembler::pt, L_fill_4); + __ delayed()->andcc(count, 4, G0); + __ stb(value, to, 0); + __ stb(value, to, 1); + __ inc(to, 2); + __ BIND(L_fill_4); + __ brx(Assembler::zero, false, Assembler::pt, L_exit); + __ delayed()->nop(); + __ stb(value, to, 0); + __ stb(value, to, 1); + __ stb(value, to, 2); + __ retl(); + __ delayed()->stb(value, to, 3); + } + + if (t == T_SHORT) { + Label L_fill_2; + __ BIND(L_fill_elements); + // in delay slot __ andcc(count, 1, G0); + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); + __ delayed()->andcc(count, 2, G0); + __ sth(value, to, 0); + __ inc(to, 2); + __ BIND(L_fill_2); + __ brx(Assembler::zero, false, Assembler::pt, L_exit); + __ delayed()->nop(); + __ sth(value, to, 0); + __ retl(); + __ delayed()->sth(value, to, 2); + } return start; } --- /dev/null Fri Sep 3 13:27:12 2010 +++ new/test/compiler/6982370/Test6982370.java Fri Sep 3 13:27:12 2010 @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6982370 + * @summary SIGBUS in jbyte_fill + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeFill -Xbatch Test6982370 + */ + +import java.util.Arrays; + +/** + * Exercise the fill routine for various short alignments and sizes + */ + +public class Test6982370 { + public static void main(String[] args) { + test_byte(); + test_char(); + test_short(); + test_int(); + test_float(); + } + + public static void test_int() { + int[] a = new int[16]; + for (int i = 0; i < 200000; i++) { + int start = i & 7; + int end = start + ((i >> 4) & 7); + int value = i; + if ((i & 1) == 1) value = -value; + Arrays.fill(a, start, end, value); + boolean error = false; + for (int j = start; j < end; j++) { + if (a[j] != value) { + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); + error = true; + } + } + if (error) throw new InternalError(); + } + } + + public static void test_float() { + float[] a = new float[16]; + for (int i = 0; i < 200000; i++) { + int start = i & 7; + int end = start + ((i >> 4) & 7); + float value = (float)i; + if ((i & 1) == 1) value = -value; + Arrays.fill(a, start, end, value); + boolean error = false; + for (int j = start; j < end; j++) { + if (a[j] != value) { + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); + error = true; + } + } + if (error) throw new InternalError(); + } + } + public static void test_char() { + char[] a = new char[16]; + for (int i = 0; i < 200000; i++) { + int start = i & 7; + int end = start + ((i >> 4) & 7); + char value = (char)i; + Arrays.fill(a, start, end, value); + boolean error = false; + for (int j = start; j < end; j++) { + if (a[j] != value) { + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); + error = true; + } + } + if (error) throw new InternalError(); + } + } + public static void test_short() { + short[] a = new short[16]; + for (int i = 0; i < 200000; i++) { + int start = i & 7; + int end = start + ((i >> 4) & 7); + short value = (short)i; + if ((i & 1) == 1) value = (short)-value; + Arrays.fill(a, start, end, value); + boolean error = false; + for (int j = start; j < end; j++) { + if (a[j] != value) { + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); + error = true; + } + } + if (error) throw new InternalError(); + } + } + + public static void test_byte() { + for (int i = 0; i < 200000; i++) { + byte[] a = new byte[16]; + int start = i & 7; + int end = start + ((i >> 4) & 7); + byte value = (byte)i; + if ((i & 1) == 1) value = (byte)-value; + Arrays.fill(a, start, end, value); + boolean error = false; + for (int j = start; j < end; j++) { + if (a[j] != value) { + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); + error = true; + } + } + if (error) throw new InternalError(); + } + } +}