Wed, 01 May 2019 22:02:48 +0530
8202414: Unsafe write after primitive array creation may result in array length change
Summary: Avoided collecting unaligned stores in Initialize node by making can_capture_store return false for same
Reviewed-by: dlong, kvn, vlivanov
1 /*
2 * Copyright (c) 2019, Huawei Technologies Co. Ltd. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /**
25 * @test
26 * @bug 8202414
27 * @summary Unsafe write after primitive array creation may result in array length change
28 * @requires (os.arch != "sparc") & (os.arch != "sparcv9")
29 * @run main/othervm compiler.c2.Test8202414
30 */
32 package compiler.c2;
34 import sun.misc.Unsafe;
35 import java.lang.reflect.Field;
36 import java.security.AccessController;
37 import java.security.PrivilegedAction;
39 public class Test8202414 {
41 public static void main(String[] args) {
42 System.err.close();
43 int count = 0;
44 while (count++ < 120000) {
45 test();
46 }
47 }
49 public static void test() {
50 byte[] newBufb = serByte(397);
51 short[] newBufs = serShort(397);
52 int[] newBufi = serInt(397);
53 long[] newBufl = serLong(397);
54 if (newBufb.length != 397 || newBufs.length != 397
55 || newBufi.length != 397 || newBufl.length != 397) {
56 System.out.println("array length internal error");
57 throw new RuntimeException("Test failed");
58 }
60 }
62 public static byte[] serByte(int bufLen) {
63 byte[] buf = new byte[bufLen];
64 THE_UNSAFE.putByte(buf, BYTE_ARRAY_BASE_OFFSET + 1, (byte) buf.length);
65 System.err.println("ref " + buf);
66 return buf;
67 }
69 public static short[] serShort(int bufLen) {
70 short[] buf = new short[bufLen];
71 THE_UNSAFE.putShort(buf, SHORT_ARRAY_BASE_OFFSET + 1, (short) buf.length);
72 System.err.println("ref " + buf);
73 return buf;
74 }
76 public static int[] serInt(int bufLen) {
77 int[] buf = new int[bufLen];
78 THE_UNSAFE.putInt(buf, INT_ARRAY_BASE_OFFSET + 1, buf.length);
79 System.err.println("ref " + buf);
80 return buf;
81 }
83 public static long[] serLong(int bufLen) {
84 long[] buf = new long[bufLen];
85 THE_UNSAFE.putLong(buf, LONG_ARRAY_BASE_OFFSET + 1, buf.length);
86 System.err.println("ref " + buf);
87 return buf;
88 }
90 /* Unsafe fields and initialization
91 */
92 static final Unsafe THE_UNSAFE;
93 static final long BYTE_ARRAY_BASE_OFFSET;
94 static final long SHORT_ARRAY_BASE_OFFSET;
95 static final long INT_ARRAY_BASE_OFFSET;
96 static final long LONG_ARRAY_BASE_OFFSET;
97 static {
98 THE_UNSAFE = (Unsafe) AccessController.doPrivileged (
99 new PrivilegedAction<Object>() {
100 @Override
101 public Object run() {
102 try {
103 Field f = Unsafe.class.getDeclaredField("theUnsafe");
104 f.setAccessible(true);
105 return f.get(null);
106 } catch (NoSuchFieldException | IllegalAccessException e) {
107 throw new Error();
108 }
109 }
110 }
111 );
112 BYTE_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(byte[].class);
113 SHORT_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(short[].class);
114 INT_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(int[].class);
115 LONG_ARRAY_BASE_OFFSET = THE_UNSAFE.arrayBaseOffset(long[].class);
116 }
117 }