hotspot/test/compiler/jsr292/VMAnonymousClasses.java
changeset 26944 d515f86283be
child 29678 dd2f3932c21e
equal deleted inserted replaced
26943:8b8001fb3aa0 26944:d515f86283be
       
     1 /*
       
     2  * Copyright (c) 2014, 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  * @test
       
    26  * @bug 8058828
       
    27  * @run main/bootclasspath -Xbatch VMAnonymousClasses
       
    28  */
       
    29 
       
    30 import jdk.internal.org.objectweb.asm.ClassWriter;
       
    31 import jdk.internal.org.objectweb.asm.MethodVisitor;
       
    32 import jdk.internal.org.objectweb.asm.Opcodes;
       
    33 import sun.misc.Unsafe;
       
    34 
       
    35 import java.lang.invoke.ConstantCallSite;
       
    36 import java.lang.invoke.MethodHandle;
       
    37 import java.lang.invoke.MethodHandles;
       
    38 import java.lang.invoke.MethodType;
       
    39 import java.lang.invoke.MutableCallSite;
       
    40 import java.lang.invoke.VolatileCallSite;
       
    41 
       
    42 public class VMAnonymousClasses {
       
    43     static final String TEST_METHOD_NAME = "constant";
       
    44 
       
    45     static final Unsafe UNSAFE = Unsafe.getUnsafe();
       
    46 
       
    47     static int getConstantPoolSize(byte[] classFile) {
       
    48         // The first few bytes:
       
    49         // u4 magic;
       
    50         // u2 minor_version;
       
    51         // u2 major_version;
       
    52         // u2 constant_pool_count;
       
    53         return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
       
    54     }
       
    55 
       
    56     static void test(Object value) throws ReflectiveOperationException {
       
    57         System.out.printf("Test: %s", value != null ? value.getClass() : "null");
       
    58 
       
    59         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
       
    60         cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, "Test", null, "java/lang/Object", null);
       
    61 
       
    62         MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, TEST_METHOD_NAME, "()Ljava/lang/Object;", null, null);
       
    63 
       
    64         String placeholder = "CONSTANT";
       
    65         int index = cw.newConst(placeholder);
       
    66         mv.visitLdcInsn(placeholder);
       
    67         mv.visitInsn(Opcodes.ARETURN);
       
    68 
       
    69         mv.visitMaxs(0, 0);
       
    70         mv.visitEnd();
       
    71 
       
    72         byte[] classFile = cw.toByteArray();
       
    73 
       
    74         Object[] cpPatches = new Object[getConstantPoolSize(classFile)];
       
    75         cpPatches[index] = value;
       
    76 
       
    77         Class<?> test = UNSAFE.defineAnonymousClass(VMAnonymousClasses.class, classFile, cpPatches);
       
    78 
       
    79         Object expectedResult = (value != null) ? value : placeholder;
       
    80         for (int i = 0; i<15000; i++) {
       
    81             Object result = test.getMethod(TEST_METHOD_NAME).invoke(null);
       
    82             if (result != expectedResult) {
       
    83                 throw new AssertionError(String.format("Wrong value returned: %s != %s", value, result));
       
    84             }
       
    85         }
       
    86         System.out.println(" PASSED");
       
    87     }
       
    88 
       
    89     public static void main(String[] args) throws ReflectiveOperationException  {
       
    90         // Objects
       
    91         test(new Object());
       
    92         test("TEST");
       
    93         test(new VMAnonymousClasses());
       
    94         test(null);
       
    95 
       
    96         // Class
       
    97         test(String.class);
       
    98 
       
    99         // Arrays
       
   100         test(new boolean[0]);
       
   101         test(new byte[0]);
       
   102         test(new char[0]);
       
   103         test(new short[0]);
       
   104         test(new int[0]);
       
   105         test(new long[0]);
       
   106         test(new float[0]);
       
   107         test(new double[0]);
       
   108         test(new Object[0]);
       
   109 
       
   110         // Multi-dimensional arrays
       
   111         test(new byte[0][0]);
       
   112         test(new Object[0][0]);
       
   113 
       
   114         // MethodHandle-related
       
   115         MethodType   mt = MethodType.methodType(void.class, String[].class);
       
   116         MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
       
   117         test(mt);
       
   118         test(mh);
       
   119         test(new ConstantCallSite(mh));
       
   120         test(new MutableCallSite(MethodType.methodType(void.class)));
       
   121         test(new VolatileCallSite(MethodType.methodType(void.class)));
       
   122 
       
   123         System.out.println("TEST PASSED");
       
   124     }
       
   125 }