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