1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. 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 * 23 */ 24 25 /* 26 * @test 27 * @bug 8150465 28 * @summary Unsafe methods to produce uninitialized arrays 29 * @modules java.base/jdk.internal.misc 30 * 31 * @run main/othervm -ea -Diters=200 -Xint 32 * compiler.intrinsics.unsafe.AllocateUninitializedArray 33 * @run main/othervm -ea -Diters=30000 -XX:TieredStopAtLevel=1 34 * compiler.intrinsics.unsafe.AllocateUninitializedArray 35 * @run main/othervm -ea -Diters=30000 -XX:TieredStopAtLevel=4 36 * compiler.intrinsics.unsafe.AllocateUninitializedArray 37 */ 38 39 package compiler.intrinsics.unsafe; 40 41 import java.lang.reflect.Array; 42 import java.lang.reflect.Field; 43 import java.util.concurrent.Callable; 44 45 public class AllocateUninitializedArray { 46 static final int ITERS = Integer.getInteger("iters", 1); 47 static final jdk.internal.misc.Unsafe UNSAFE; 48 49 static { 50 try { 51 Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe"); 52 f.setAccessible(true); 53 UNSAFE = (jdk.internal.misc.Unsafe) f.get(null); 54 } catch (Exception e) { 55 throw new RuntimeException("Unable to get Unsafe instance.", e); 56 } 57 } 58 59 public static void main(String... args) throws Exception { 60 testIAE(AllConstants::testObject); 61 testIAE(LengthIsConstant::testObject); 62 testIAE(ClassIsConstant::testObject); 63 testIAE(NothingIsConstant::testObject); 64 65 testIAE(AllConstants::testArray); 66 testIAE(LengthIsConstant::testArray); 67 testIAE(ClassIsConstant::testArray); 68 testIAE(NothingIsConstant::testArray); 69 70 testIAE(AllConstants::testNull); 71 testIAE(LengthIsConstant::testNull); 72 testIAE(ClassIsConstant::testNull); 73 testIAE(NothingIsConstant::testNull); 74 75 testOK(boolean[].class, 10, AllConstants::testBoolean); 76 testOK(byte[].class, 10, AllConstants::testByte); 77 testOK(short[].class, 10, AllConstants::testShort); 78 testOK(char[].class, 10, AllConstants::testChar); 79 testOK(int[].class, 10, AllConstants::testInt); 80 testOK(float[].class, 10, AllConstants::testFloat); 81 testOK(long[].class, 10, AllConstants::testLong); 82 testOK(double[].class, 10, AllConstants::testDouble); 83 84 testOK(boolean[].class, 10, LengthIsConstant::testBoolean); 85 testOK(byte[].class, 10, LengthIsConstant::testByte); 86 testOK(short[].class, 10, LengthIsConstant::testShort); 87 testOK(char[].class, 10, LengthIsConstant::testChar); 88 testOK(int[].class, 10, LengthIsConstant::testInt); 89 testOK(float[].class, 10, LengthIsConstant::testFloat); 90 testOK(long[].class, 10, LengthIsConstant::testLong); 91 testOK(double[].class, 10, LengthIsConstant::testDouble); 92 93 testOK(boolean[].class, 10, ClassIsConstant::testBoolean); 94 testOK(byte[].class, 10, ClassIsConstant::testByte); 95 testOK(short[].class, 10, ClassIsConstant::testShort); 96 testOK(char[].class, 10, ClassIsConstant::testChar); 97 testOK(int[].class, 10, ClassIsConstant::testInt); 98 testOK(float[].class, 10, ClassIsConstant::testFloat); 99 testOK(long[].class, 10, ClassIsConstant::testLong); 100 testOK(double[].class, 10, ClassIsConstant::testDouble); 101 102 testOK(boolean[].class, 10, NothingIsConstant::testBoolean); 103 testOK(byte[].class, 10, NothingIsConstant::testByte); 104 testOK(short[].class, 10, NothingIsConstant::testShort); 105 testOK(char[].class, 10, NothingIsConstant::testChar); 106 testOK(int[].class, 10, NothingIsConstant::testInt); 107 testOK(float[].class, 10, NothingIsConstant::testFloat); 108 testOK(long[].class, 10, NothingIsConstant::testLong); 109 testOK(double[].class, 10, NothingIsConstant::testDouble); 110 } 111 112 public static void testOK(Class<?> expectClass, int expectLen, Callable<Object> test) throws Exception { 113 for (int c = 0; c < ITERS; c++) { 114 Object res = test.call(); 115 Class<?> actualClass = res.getClass(); 116 if (!actualClass.equals(expectClass)) { 117 throw new IllegalStateException("Wrong class: expected = " + expectClass + ", but got " + actualClass); 118 } 119 int actualLen = Array.getLength(res); 120 if (actualLen != expectLen) { 121 throw new IllegalStateException("Wrong length: expected = " + expectLen + ", but got " + actualLen); 122 } 123 } 124 } 125 126 static volatile Object sink; 127 128 public static void testIAE(Callable<Object> test) throws Exception { 129 for (int c = 0; c < ITERS; c++) { 130 try { 131 sink = test.call(); 132 throw new IllegalStateException("Expected IAE"); 133 } catch (IllegalArgumentException iae) { 134 // expected 135 } 136 } 137 } 138 139 static volatile int sampleLenNeg = -1; 140 static volatile int sampleLenZero = 0; 141 static volatile int sampleLen = 10; 142 143 144 static volatile Class<?> classBoolean = boolean.class; 145 static volatile Class<?> classByte = byte.class; 146 static volatile Class<?> classShort = short.class; 147 static volatile Class<?> classChar = char.class; 148 static volatile Class<?> classInt = int.class; 149 static volatile Class<?> classFloat = float.class; 150 static volatile Class<?> classLong = long.class; 151 static volatile Class<?> classDouble = double.class; 152 static volatile Class<?> classObject = Object.class; 153 static volatile Class<?> classArray = Object[].class; 154 static volatile Class<?> classNull = null; 155 156 static class AllConstants { 157 static Object testBoolean() { return UNSAFE.allocateUninitializedArray(boolean.class, 10); } 158 static Object testByte() { return UNSAFE.allocateUninitializedArray(byte.class, 10); } 159 static Object testShort() { return UNSAFE.allocateUninitializedArray(short.class, 10); } 160 static Object testChar() { return UNSAFE.allocateUninitializedArray(char.class, 10); } 161 static Object testInt() { return UNSAFE.allocateUninitializedArray(int.class, 10); } 162 static Object testFloat() { return UNSAFE.allocateUninitializedArray(float.class, 10); } 163 static Object testLong() { return UNSAFE.allocateUninitializedArray(long.class, 10); } 164 static Object testDouble() { return UNSAFE.allocateUninitializedArray(double.class, 10); } 165 static Object testObject() { return UNSAFE.allocateUninitializedArray(Object.class, 10); } 166 static Object testArray() { return UNSAFE.allocateUninitializedArray(Object[].class, 10); } 167 static Object testNull() { return UNSAFE.allocateUninitializedArray(null, 10); } 168 static Object testZero() { return UNSAFE.allocateUninitializedArray(int.class, 0); } 169 static Object testNeg() { return UNSAFE.allocateUninitializedArray(int.class, -1); } 170 } 171 172 static class ClassIsConstant { 173 static Object testBoolean() { return UNSAFE.allocateUninitializedArray(boolean.class, sampleLen); } 174 static Object testByte() { return UNSAFE.allocateUninitializedArray(byte.class, sampleLen); } 175 static Object testShort() { return UNSAFE.allocateUninitializedArray(short.class, sampleLen); } 176 static Object testChar() { return UNSAFE.allocateUninitializedArray(char.class, sampleLen); } 177 static Object testInt() { return UNSAFE.allocateUninitializedArray(int.class, sampleLen); } 178 static Object testFloat() { return UNSAFE.allocateUninitializedArray(float.class, sampleLen); } 179 static Object testLong() { return UNSAFE.allocateUninitializedArray(long.class, sampleLen); } 180 static Object testDouble() { return UNSAFE.allocateUninitializedArray(double.class, sampleLen); } 181 static Object testObject() { return UNSAFE.allocateUninitializedArray(Object.class, sampleLen); } 182 static Object testArray() { return UNSAFE.allocateUninitializedArray(Object[].class, sampleLen); } 183 static Object testNull() { return UNSAFE.allocateUninitializedArray(null, sampleLen); } 184 static Object testZero() { return UNSAFE.allocateUninitializedArray(int.class, sampleLenZero); } 185 static Object testNeg() { return UNSAFE.allocateUninitializedArray(int.class, sampleLenNeg); } 186 } 187 188 static class LengthIsConstant { 189 static Object testBoolean() { return UNSAFE.allocateUninitializedArray(classBoolean, 10); } 190 static Object testByte() { return UNSAFE.allocateUninitializedArray(classByte, 10); } 191 static Object testShort() { return UNSAFE.allocateUninitializedArray(classShort, 10); } 192 static Object testChar() { return UNSAFE.allocateUninitializedArray(classChar, 10); } 193 static Object testInt() { return UNSAFE.allocateUninitializedArray(classInt, 10); } 194 static Object testFloat() { return UNSAFE.allocateUninitializedArray(classFloat, 10); } 195 static Object testLong() { return UNSAFE.allocateUninitializedArray(classLong, 10); } 196 static Object testDouble() { return UNSAFE.allocateUninitializedArray(classDouble, 10); } 197 static Object testObject() { return UNSAFE.allocateUninitializedArray(classObject, 10); } 198 static Object testArray() { return UNSAFE.allocateUninitializedArray(classArray, 10); } 199 static Object testNull() { return UNSAFE.allocateUninitializedArray(classNull, 10); } 200 static Object testZero() { return UNSAFE.allocateUninitializedArray(classInt, 0); } 201 static Object testNeg() { return UNSAFE.allocateUninitializedArray(classInt, -1); } 202 } 203 204 static class NothingIsConstant { 205 static Object testBoolean() { return UNSAFE.allocateUninitializedArray(classBoolean, sampleLen); } 206 static Object testByte() { return UNSAFE.allocateUninitializedArray(classByte, sampleLen); } 207 static Object testShort() { return UNSAFE.allocateUninitializedArray(classShort, sampleLen); } 208 static Object testChar() { return UNSAFE.allocateUninitializedArray(classChar, sampleLen); } 209 static Object testInt() { return UNSAFE.allocateUninitializedArray(classInt, sampleLen); } 210 static Object testFloat() { return UNSAFE.allocateUninitializedArray(classFloat, sampleLen); } 211 static Object testLong() { return UNSAFE.allocateUninitializedArray(classLong, sampleLen); } 212 static Object testDouble() { return UNSAFE.allocateUninitializedArray(classDouble, sampleLen); } 213 static Object testObject() { return UNSAFE.allocateUninitializedArray(classObject, sampleLen); } 214 static Object testArray() { return UNSAFE.allocateUninitializedArray(classArray, sampleLen); } 215 static Object testNull() { return UNSAFE.allocateUninitializedArray(classNull, sampleLen); } 216 static Object testZero() { return UNSAFE.allocateUninitializedArray(classInt, sampleLenZero); } 217 static Object testNeg() { return UNSAFE.allocateUninitializedArray(classInt, sampleLenNeg); } 218 } 219 } 220