Tue, 14 Sep 2010 14:09:24 -0700
6982370: SIGBUS in jbyte_fill
Reviewed-by: kvn
src/cpu/sparc/vm/stubGenerator_sparc.cpp | file | annotate | diff | comparison | revisions | |
test/compiler/6982370/Test6982370.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Mon Sep 13 23:24:30 2010 -0700 1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Sep 14 14:09:24 2010 -0700 1.3 @@ -1609,7 +1609,7 @@ 1.4 assert_clean_int(count, O3); // Make sure 'count' is clean int. 1.5 1.6 Label L_exit, L_skip_align1, L_skip_align2, L_fill_byte; 1.7 - Label L_fill_2_bytes, L_fill_4_bytes, L_fill_32_bytes; 1.8 + Label L_fill_2_bytes, L_fill_elements, L_fill_32_bytes; 1.9 1.10 int shift = -1; 1.11 switch (t) { 1.12 @@ -1635,8 +1635,8 @@ 1.13 } 1.14 if (t == T_SHORT) { 1.15 // Zero extend value 1.16 - __ sethi(0xffff0000, O3); 1.17 - __ andn(value, O3, value); 1.18 + __ sllx(value, 48, value); 1.19 + __ srlx(value, 48, value); 1.20 } 1.21 if (t == T_BYTE || t == T_SHORT) { 1.22 __ sllx(value, 16, O3); 1.23 @@ -1644,8 +1644,8 @@ 1.24 } 1.25 1.26 __ cmp(count, 2<<shift); // Short arrays (< 8 bytes) fill by element 1.27 - __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_4_bytes); // use unsigned cmp 1.28 - __ delayed()->andcc(count, 1<<shift, G0); 1.29 + __ brx(Assembler::lessUnsigned, false, Assembler::pn, L_fill_elements); // use unsigned cmp 1.30 + __ delayed()->andcc(count, 1, G0); 1.31 1.32 if (!aligned && (t == T_BYTE || t == T_SHORT)) { 1.33 // align source address at 4 bytes address boundary 1.34 @@ -1698,7 +1698,7 @@ 1.35 __ brx(Assembler::less, false, Assembler::pt, L_check_fill_8_bytes); 1.36 __ delayed()->nop(); 1.37 1.38 - Label L_fill_32_bytes_loop; 1.39 + Label L_fill_32_bytes_loop, L_fill_4_bytes; 1.40 __ align(16); 1.41 __ BIND(L_fill_32_bytes_loop); 1.42 1.43 @@ -1730,6 +1730,9 @@ 1.44 1.45 // fill trailing 4 bytes 1.46 __ andcc(count, 1<<shift, G0); // in delay slot of branches 1.47 + if (t == T_INT) { 1.48 + __ BIND(L_fill_elements); 1.49 + } 1.50 __ BIND(L_fill_4_bytes); 1.51 __ brx(Assembler::zero, false, Assembler::pt, L_fill_2_bytes); 1.52 if (t == T_BYTE || t == T_SHORT) { 1.53 @@ -1762,7 +1765,48 @@ 1.54 } 1.55 __ BIND(L_exit); 1.56 __ retl(); 1.57 - __ delayed()->mov(G0, O0); // return 0 1.58 + __ delayed()->nop(); 1.59 + 1.60 + // Handle copies less than 8 bytes. Int is handled elsewhere. 1.61 + if (t == T_BYTE) { 1.62 + __ BIND(L_fill_elements); 1.63 + Label L_fill_2, L_fill_4; 1.64 + // in delay slot __ andcc(count, 1, G0); 1.65 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); 1.66 + __ delayed()->andcc(count, 2, G0); 1.67 + __ stb(value, to, 0); 1.68 + __ inc(to, 1); 1.69 + __ BIND(L_fill_2); 1.70 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_4); 1.71 + __ delayed()->andcc(count, 4, G0); 1.72 + __ stb(value, to, 0); 1.73 + __ stb(value, to, 1); 1.74 + __ inc(to, 2); 1.75 + __ BIND(L_fill_4); 1.76 + __ brx(Assembler::zero, false, Assembler::pt, L_exit); 1.77 + __ delayed()->nop(); 1.78 + __ stb(value, to, 0); 1.79 + __ stb(value, to, 1); 1.80 + __ stb(value, to, 2); 1.81 + __ retl(); 1.82 + __ delayed()->stb(value, to, 3); 1.83 + } 1.84 + 1.85 + if (t == T_SHORT) { 1.86 + Label L_fill_2; 1.87 + __ BIND(L_fill_elements); 1.88 + // in delay slot __ andcc(count, 1, G0); 1.89 + __ brx(Assembler::zero, false, Assembler::pt, L_fill_2); 1.90 + __ delayed()->andcc(count, 2, G0); 1.91 + __ sth(value, to, 0); 1.92 + __ inc(to, 2); 1.93 + __ BIND(L_fill_2); 1.94 + __ brx(Assembler::zero, false, Assembler::pt, L_exit); 1.95 + __ delayed()->nop(); 1.96 + __ sth(value, to, 0); 1.97 + __ retl(); 1.98 + __ delayed()->sth(value, to, 2); 1.99 + } 1.100 return start; 1.101 } 1.102
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/6982370/Test6982370.java Tue Sep 14 14:09:24 2010 -0700 2.3 @@ -0,0 +1,139 @@ 2.4 +/* 2.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +/** 2.29 + * @test 2.30 + * @bug 6982370 2.31 + * @summary SIGBUS in jbyte_fill 2.32 + * 2.33 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+OptimizeFill -Xbatch Test6982370 2.34 + */ 2.35 + 2.36 +import java.util.Arrays; 2.37 + 2.38 +/** 2.39 + * Exercise the fill routine for various short alignments and sizes 2.40 + */ 2.41 + 2.42 +public class Test6982370 { 2.43 + public static void main(String[] args) { 2.44 + test_byte(); 2.45 + test_char(); 2.46 + test_short(); 2.47 + test_int(); 2.48 + test_float(); 2.49 + } 2.50 + 2.51 + public static void test_int() { 2.52 + int[] a = new int[16]; 2.53 + for (int i = 0; i < 200000; i++) { 2.54 + int start = i & 7; 2.55 + int end = start + ((i >> 4) & 7); 2.56 + int value = i; 2.57 + if ((i & 1) == 1) value = -value; 2.58 + Arrays.fill(a, start, end, value); 2.59 + boolean error = false; 2.60 + for (int j = start; j < end; j++) { 2.61 + if (a[j] != value) { 2.62 + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); 2.63 + error = true; 2.64 + } 2.65 + } 2.66 + if (error) throw new InternalError(); 2.67 + } 2.68 + } 2.69 + 2.70 + public static void test_float() { 2.71 + float[] a = new float[16]; 2.72 + for (int i = 0; i < 200000; i++) { 2.73 + int start = i & 7; 2.74 + int end = start + ((i >> 4) & 7); 2.75 + float value = (float)i; 2.76 + if ((i & 1) == 1) value = -value; 2.77 + Arrays.fill(a, start, end, value); 2.78 + boolean error = false; 2.79 + for (int j = start; j < end; j++) { 2.80 + if (a[j] != value) { 2.81 + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); 2.82 + error = true; 2.83 + } 2.84 + } 2.85 + if (error) throw new InternalError(); 2.86 + } 2.87 + } 2.88 + public static void test_char() { 2.89 + char[] a = new char[16]; 2.90 + for (int i = 0; i < 200000; i++) { 2.91 + int start = i & 7; 2.92 + int end = start + ((i >> 4) & 7); 2.93 + char value = (char)i; 2.94 + Arrays.fill(a, start, end, value); 2.95 + boolean error = false; 2.96 + for (int j = start; j < end; j++) { 2.97 + if (a[j] != value) { 2.98 + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); 2.99 + error = true; 2.100 + } 2.101 + } 2.102 + if (error) throw new InternalError(); 2.103 + } 2.104 + } 2.105 + public static void test_short() { 2.106 + short[] a = new short[16]; 2.107 + for (int i = 0; i < 200000; i++) { 2.108 + int start = i & 7; 2.109 + int end = start + ((i >> 4) & 7); 2.110 + short value = (short)i; 2.111 + if ((i & 1) == 1) value = (short)-value; 2.112 + Arrays.fill(a, start, end, value); 2.113 + boolean error = false; 2.114 + for (int j = start; j < end; j++) { 2.115 + if (a[j] != value) { 2.116 + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); 2.117 + error = true; 2.118 + } 2.119 + } 2.120 + if (error) throw new InternalError(); 2.121 + } 2.122 + } 2.123 + 2.124 + public static void test_byte() { 2.125 + for (int i = 0; i < 200000; i++) { 2.126 + byte[] a = new byte[16]; 2.127 + int start = i & 7; 2.128 + int end = start + ((i >> 4) & 7); 2.129 + byte value = (byte)i; 2.130 + if ((i & 1) == 1) value = (byte)-value; 2.131 + Arrays.fill(a, start, end, value); 2.132 + boolean error = false; 2.133 + for (int j = start; j < end; j++) { 2.134 + if (a[j] != value) { 2.135 + System.err.println("a[" + j + "] = " + a[j] + " != " + value + " for " + a.length); 2.136 + error = true; 2.137 + } 2.138 + } 2.139 + if (error) throw new InternalError(); 2.140 + } 2.141 + } 2.142 +}