/* * Copyright (c) 2016, 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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 8153540 * @modules java.base/jdk.internal.misc * * @run main/bootclasspath -Xbatch -XX:CompileCommand=dontinline,*AllocateInstance.test* * compiler.unsafe.AllocateInstance */ package compiler.unsafe; import jdk.internal.misc.Unsafe; import java.util.concurrent.Callable; public class AllocateInstance { static final Unsafe U = Unsafe.getUnsafe(); static class T {} static final Class T_CLASS; static { try { T_CLASS = Class.forName(T.class.getName(), false, ClassLoader.getSystemClassLoader()); } catch (ClassNotFoundException e) { throw new Error(e); } } static abstract class A {} static Object testNull() throws InstantiationException { return U.allocateInstance(null); } static Object testPrim() throws InstantiationException { return U.allocateInstance(int.class); } static Object testPrimArray() throws InstantiationException { return U.allocateInstance(int[].class); } static Object testObjArray() throws InstantiationException { return U.allocateInstance(Object[].class); } static Object testIntf() throws InstantiationException { return U.allocateInstance(Runnable.class); } static Object testAbstract() throws InstantiationException { return U.allocateInstance(A.class); } static Object testObject() throws InstantiationException { return U.allocateInstance(Object.class); } static Object testObjectInit() throws InstantiationException { return U.allocateInstance(T_CLASS); } static Object testReflective(Class c) throws InstantiationException { return U.allocateInstance(c); } static void run(String name, Callable c, boolean shouldSucceed, boolean verbose) { if (verbose) System.out.print(name); run(c, shouldSucceed, verbose); } static void run(Class c, boolean shouldSucceed, boolean verbose) { if (verbose) System.out.print(c != null ? c.getName() : "null"); run(() -> testReflective(c), shouldSucceed, verbose); } static void run(Callable c, boolean shouldSucceed, boolean verbose) { try { Object o = c.call(); if (o == null) { System.out.println(" => null"); } else { if (verbose) System.out.println(" => allocated"); } if (!shouldSucceed) { throw new AssertionError("allocation should fail"); } } catch (Exception e) { if (verbose) { System.out.println(" => exception " + e.getClass().getName() + ": " + e.getMessage()); } if (shouldSucceed) { throw new AssertionError("allocation should succeed"); } } } static void runTests(boolean verbose) { run("null", AllocateInstance::testNull, false, verbose); run("int", AllocateInstance::testPrim, false, verbose); run("int[]", AllocateInstance::testPrimArray, false, verbose); run("Object[]", AllocateInstance::testObjArray, false, verbose); run("interface", AllocateInstance::testIntf, false, verbose); run("abstract", AllocateInstance::testAbstract, false, verbose); run("Object", AllocateInstance::testObject, true, verbose); run("ObjectInit", AllocateInstance::testObjectInit, true, verbose); run((Class)null, false, verbose); run(Object.class, true, verbose); run(A.class, false, verbose); run(Runnable.class, false, verbose); run(Object[].class, false, verbose); run(int.class, false, verbose); run(int[].class, false, verbose); } static void warmup() { for (int i = 0; i < 20_000; i ++) { runTests(false); } } public static void main(String[] args) { runTests(true); warmup(); runTests(true); System.out.println("TEST PASSED"); } }