test/jdk/java/lang/invoke/condy/CondyNestedTest.java
changeset 48830 11920d5d14a8
parent 48826 c4d9d1b08e2e
--- a/test/jdk/java/lang/invoke/condy/CondyNestedTest.java	Thu Feb 01 02:05:35 2018 +0100
+++ b/test/jdk/java/lang/invoke/condy/CondyNestedTest.java	Wed Jan 31 17:43:46 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -25,188 +25,146 @@
  * @test
  * @bug 8186046
  * @summary Test nested dynamic constant declarations that are recursive
- * @library /lib/testlibrary/bytecode
- * @build jdk.experimental.bytecode.BasicClassBuilder
+ * @compile CondyNestedTest_Code.jcod
  * @run testng CondyNestedTest
  * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:UseBootstrapCallInfo=3 CondyNestedTest
  */
 
-import jdk.experimental.bytecode.BasicClassBuilder;
-import jdk.experimental.bytecode.Flag;
-import jdk.experimental.bytecode.MacroCodeBuilder;
-import jdk.experimental.bytecode.PoolHelper;
-import jdk.experimental.bytecode.TypeTag;
-import jdk.experimental.bytecode.TypedCodeBuilder;
 import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Base64;
 
 public class CondyNestedTest {
 
-    /**
-     * NOTE: This is a temporary solution until asmtools is updated to support
-     * dynamic constant and jtreg is updated to include a new version of
-     * asmtools.
-     *
-     * These are the class file bytes for a class named CondyNestedTest_Code
-     * whose bytes are 1) generated by the generator() function;  2) the bytes
-     * converted to a jcod file:
-     *
-     * java -jar asmtools.jar jdec CondyNestedTest_Code.class >
-     * CondyNestedTest_Code.jcod
-     *
-     * which was then edited so that dynamic constant declarations are
-     * recursive both for an ldc or invokedynamic (specifically declaring a
-     * BSM+attributes whose static argument is a dynamic constant
-     * that refers to the same BSM+attributes); 3) the jcod file is converted
-     * back to a class file:
-     *
-     * java -jar asmtools.jar jdis [options] CondyNestedTest_Code.jcod
-     *
-     * ;and finally 4) the newly generated class file bytes are converted to
-     * a base64 representation and embedded in the following String.
-     */
-    static final String CLASS_CondyNestedTest_Code =
-            "yv66vgAAADcAQgEAEGphdmEvbGFuZy9PYmplY3QHAAEBAAY8aW5pdD4BAAMoKVYMAAMABAoAAgAFAQAE" +
-            "Q29kZQEAEGphdmEvbGFuZy9TdHJpbmcHAAgBAAZpbnRlcm4BABQoKUxqYXZhL2xhbmcvU3RyaW5nOwwA" +
-            "CgALCgAJAAwBABNjb25keV9ic21fY29uZHlfYnNtCAAOAQAUQ29uZHlOZXN0ZWRUZXN0X0NvZGUHABAB" +
-            "ABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwADgASCgARABMBABZpbmR5X2JzbUluZHlfY29uZHlfYnNtCAAV" +
-            "DAAVABIKABEAFwEAEmluZHlfYnNtX2NvbmR5X2JzbQgAGQwAGQASCgARABsBAA1TdGFja01hcFRhYmxl" +
-            "AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBABtqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5" +
-            "cGUHACABACFqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGUHACIBAB5qYXZhL2xhbmcvaW52" +
-            "b2tlL01ldGhvZEhhbmRsZXMHACQBAAhjb25zdGFudAEARChMamF2YS9sYW5nL0NsYXNzO0xqYXZhL2xh" +
-            "bmcvT2JqZWN0OylMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGU7DAAmACcKACUAKAEAIihMamF2" +
-            "YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGU7KVYMAAMAKgoAIwArAQADYnNtAQBxKExqYXZhL2xhbmcv" +
-            "aW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvT2Jq" +
-            "ZWN0O0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAdic21JbmR5AQB6KExqYXZh" +
-            "L2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xh" +
-            "bmcvT2JqZWN0O0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL2ludm9rZS9DYWxsU2l0ZTsBAAlE" +
-            "VU1NWV9BUkcIADEMAC0ALgoAEQAzDwYANAEABG5hbWUBABJMamF2YS9sYW5nL1N0cmluZzsMADYANxEA" +
-            "AAA4EQABADgMAC8AMAoAEQA7DwYAPAwANgALEgACAD4SAAEAPgEAEEJvb3RzdHJhcE1ldGhvZHMAAAAR" +
-            "AAIAAAAAAAcAAQADAAQAAQAHAAAAEQABAAEAAAAFKrcABrEAAAAAAAkAHgAfAAEABwAAAEIAAgACAAAA" +
-            "JioDMrYADUwrEg+mAAe4ABSxKxIWpgAHuAAYsSsSGqYAB7gAHLGxAAAAAQAdAAAACgAD/AARBwAJCQkA" +
-            "CQAtAC4AAQAHAAAALQAEAAQAAAAYLMEAIQOfABG7ACNZEgkruAAptwAssCuwAAAAAQAdAAAAAwABFgAJ" +
-            "AC8AMAABAAcAAAAaAAQABAAAAA67ACNZEgkruAAptwAssAAAAAAACQAOABIAAQAHAAAADwABAAAAAAAD" +
-            "EjqwAAAAAAAJABUAEgABAAcAAAASAAEAAAAAAAa6AD8AALAAAAAAAAkAGQASAAEABwAAABIAAQAAAAAA" +
-            "BroAQAAAsAAAAAAAAQBBAAAAFAADADUAAQAyADUAAQA6AD0AAQA6";
-
-    static final MethodHandles.Lookup L = MethodHandles.lookup();
-
     static final Class[] THROWABLES = {InvocationTargetException.class, StackOverflowError.class};
 
     Class<?> c;
 
-    public static byte[] generator() throws Exception {
-        String genClassName = L.lookupClass().getSimpleName() + "_Code";
-        String bsmDescriptor = MethodType.methodType(Object.class, MethodHandles.Lookup.class, String.class, Object.class, Object.class).toMethodDescriptorString();
-        String bsmIndyDescriptor = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, Object.class, Object.class).toMethodDescriptorString();
-
-        byte[] byteArray = new BasicClassBuilder(genClassName, 55, 0)
-                .withSuperclass("java/lang/Object")
-                .withMethod("<init>", "()V", M ->
-                        M.withFlags(Flag.ACC_PUBLIC)
-                                .withCode(TypedCodeBuilder::new, C ->
-                                        C.aload_0().invokespecial("java/lang/Object", "<init>", "()V", false).return_()
-                                ))
-                .withMethod("main", "([Ljava/lang/String;)V", M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C -> {
-                                    C.aload_0().iconst_0().aaload();
-                                    C.invokevirtual("java/lang/String", "intern", "()Ljava/lang/String;", false);
-                                    C.astore_1();
-
-                                    C.aload_1();
-                                    C.ldc("condy_bsm_condy_bsm");
-                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE1");
-                                    C.invokestatic(genClassName, "condy_bsm_condy_bsm", "()Ljava/lang/Object;", false).return_();
-
-                                    C.label("CASE1");
-                                    C.aload_1();
-                                    C.ldc("indy_bsmIndy_condy_bsm");
-                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE2");
-                                    C.invokestatic(genClassName, "indy_bsmIndy_condy_bsm", "()Ljava/lang/Object;", false).return_();
-
-                                    C.label("CASE2");
-                                    C.aload_1();
-                                    C.ldc("indy_bsm_condy_bsm");
-                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE3");
-                                    C.invokestatic(genClassName, "indy_bsm_condy_bsm", "()Ljava/lang/Object;", false).return_();
-
-                                    C.label("CASE3");
-                                    C.return_();
-                                }))
-                .withMethod("bsm", bsmDescriptor, M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C -> {
-                                    C.aload_2();
-                                    C.instanceof_("java/lang/invoke/MethodType");
-                                    C.iconst_0();
-                                    C.ifcmp(TypeTag.I, MacroCodeBuilder.CondKind.EQ, "CONDY");
-                                    C.new_("java/lang/invoke/ConstantCallSite").dup();
-                                    C.ldc("java/lang/String", PoolHelper::putClass);
-                                    C.aload_1();
-                                    C.invokestatic("java/lang/invoke/MethodHandles", "constant", "(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;", false);
-                                    C.invokespecial("java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
-                                    C.areturn();
-                                    C.label("CONDY");
-                                    C.aload_1().areturn();
-                                }))
-                .withMethod("bsmIndy", bsmIndyDescriptor, M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C -> {
-                                    C.new_("java/lang/invoke/ConstantCallSite").dup();
-                                    C.ldc("java/lang/String", PoolHelper::putClass);
-                                    C.aload_1();
-                                    C.invokestatic("java/lang/invoke/MethodHandles", "constant", "(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;", false);
-                                    C.invokespecial("java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
-                                    C.areturn();
-                                }))
-                .withMethod("condy_bsm_condy_bsm", "()Ljava/lang/Object;", M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C ->
-                                        C.ldc("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
-                                              S -> S.add(null, (P, v) -> {
-                                                  return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
-                                                                              S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
-                                              }))
-                                                .areturn()))
-                .withMethod("indy_bsmIndy_condy_bsm", "()Ljava/lang/Object;", M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C ->
-                                        C.invokedynamic("name", "()Ljava/lang/String;", genClassName, "bsmIndy", bsmIndyDescriptor,
-                                                        S -> S.add(null, (P, v) -> {
-                                                            return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
-                                                                                        S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
-                                                        }))
-                                                .areturn()))
-                .withMethod("indy_bsm_condy_bsm", "()Ljava/lang/Object;", M ->
-                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
-                                .withCode(TypedCodeBuilder::new, C ->
-                                        C.invokedynamic("name", "()Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
-                                                        S -> S.add(null, (P, v) -> {
-                                                            return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
-                                                                                        S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
-                                                        }))
-                                                .areturn()))
-                .build();
-
-        File f = new File(genClassName + ".class");
-        if (f.getParentFile() != null) {
-            f.getParentFile().mkdirs();
-        }
-        new FileOutputStream(f).write(byteArray);
-        return byteArray;
-
-    }
+// Add the following annotations to the test description if uncommenting the
+// following code
+//
+// * @library /lib/testlibrary/bytecode
+// * @build jdk.experimental.bytecode.BasicClassBuilder
+//
+//    static final MethodHandles.Lookup L = MethodHandles.lookup();
+//
+//    /**
+//     * Generate class file bytes for a class named CondyNestedTest_Code
+//     * whose bytes are converted to a jcod file:
+//     *
+//     * java -jar asmtools.jar jdec CondyNestedTest_Code.class >
+//     * CondyNestedTest_Code.jcod
+//     *
+//     * which was then edited so that dynamic constant declarations are
+//     * recursive both for an ldc or invokedynamic (specifically declaring a
+//     * BSM+attributes whose static argument is a dynamic constant
+//     * that refers to the same BSM+attributes).
+//     */
+//    public static byte[] generator() throws Exception {
+//        String genClassName = L.lookupClass().getSimpleName() + "_Code";
+//        String bsmDescriptor = MethodType.methodType(Object.class, MethodHandles.Lookup.class, String.class, Object.class, Object.class).toMethodDescriptorString();
+//        String bsmIndyDescriptor = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, Object.class, Object.class).toMethodDescriptorString();
+//
+//        byte[] byteArray = new BasicClassBuilder(genClassName, 55, 0)
+//                .withSuperclass("java/lang/Object")
+//                .withMethod("<init>", "()V", M ->
+//                        M.withFlags(Flag.ACC_PUBLIC)
+//                                .withCode(TypedCodeBuilder::new, C ->
+//                                        C.aload_0().invokespecial("java/lang/Object", "<init>", "()V", false).return_()
+//                                ))
+//                .withMethod("main", "([Ljava/lang/String;)V", M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C -> {
+//                                    C.aload_0().iconst_0().aaload();
+//                                    C.invokevirtual("java/lang/String", "intern", "()Ljava/lang/String;", false);
+//                                    C.astore_1();
+//
+//                                    C.aload_1();
+//                                    C.ldc("condy_bsm_condy_bsm");
+//                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE1");
+//                                    C.invokestatic(genClassName, "condy_bsm_condy_bsm", "()Ljava/lang/Object;", false).return_();
+//
+//                                    C.label("CASE1");
+//                                    C.aload_1();
+//                                    C.ldc("indy_bsmIndy_condy_bsm");
+//                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE2");
+//                                    C.invokestatic(genClassName, "indy_bsmIndy_condy_bsm", "()Ljava/lang/Object;", false).return_();
+//
+//                                    C.label("CASE2");
+//                                    C.aload_1();
+//                                    C.ldc("indy_bsm_condy_bsm");
+//                                    C.ifcmp(TypeTag.A, MacroCodeBuilder.CondKind.NE, "CASE3");
+//                                    C.invokestatic(genClassName, "indy_bsm_condy_bsm", "()Ljava/lang/Object;", false).return_();
+//
+//                                    C.label("CASE3");
+//                                    C.return_();
+//                                }))
+//                .withMethod("bsm", bsmDescriptor, M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C -> {
+//                                    C.aload_2();
+//                                    C.instanceof_("java/lang/invoke/MethodType");
+//                                    C.iconst_0();
+//                                    C.ifcmp(TypeTag.I, MacroCodeBuilder.CondKind.EQ, "CONDY");
+//                                    C.new_("java/lang/invoke/ConstantCallSite").dup();
+//                                    C.ldc("java/lang/String", PoolHelper::putClass);
+//                                    C.aload_1();
+//                                    C.invokestatic("java/lang/invoke/MethodHandles", "constant", "(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;", false);
+//                                    C.invokespecial("java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
+//                                    C.areturn();
+//                                    C.label("CONDY");
+//                                    C.aload_1().areturn();
+//                                }))
+//                .withMethod("bsmIndy", bsmIndyDescriptor, M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C -> {
+//                                    C.new_("java/lang/invoke/ConstantCallSite").dup();
+//                                    C.ldc("java/lang/String", PoolHelper::putClass);
+//                                    C.aload_1();
+//                                    C.invokestatic("java/lang/invoke/MethodHandles", "constant", "(Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;", false);
+//                                    C.invokespecial("java/lang/invoke/ConstantCallSite", "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
+//                                    C.areturn();
+//                                }))
+//                .withMethod("condy_bsm_condy_bsm", "()Ljava/lang/Object;", M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C ->
+//                                        C.ldc("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
+//                                              S -> S.add(null, (P, v) -> {
+//                                                  return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
+//                                                                              S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
+//                                              }))
+//                                                .areturn()))
+//                .withMethod("indy_bsmIndy_condy_bsm", "()Ljava/lang/Object;", M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C ->
+//                                        C.invokedynamic("name", "()Ljava/lang/String;", genClassName, "bsmIndy", bsmIndyDescriptor,
+//                                                        S -> S.add(null, (P, v) -> {
+//                                                            return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
+//                                                                                        S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
+//                                                        }))
+//                                                .areturn()))
+//                .withMethod("indy_bsm_condy_bsm", "()Ljava/lang/Object;", M ->
+//                        M.withFlags(Flag.ACC_PUBLIC, Flag.ACC_STATIC)
+//                                .withCode(TypedCodeBuilder::new, C ->
+//                                        C.invokedynamic("name", "()Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
+//                                                        S -> S.add(null, (P, v) -> {
+//                                                            return P.putDynamicConstant("name", "Ljava/lang/String;", genClassName, "bsm", bsmDescriptor,
+//                                                                                        S2 -> S2.add("DUMMY_ARG", PoolHelper::putString));
+//                                                        }))
+//                                                .areturn()))
+//                .build();
+//
+//        File f = new File(genClassName + ".class");
+//        if (f.getParentFile() != null) {
+//            f.getParentFile().mkdirs();
+//        }
+//        new FileOutputStream(f).write(byteArray);
+//        return byteArray;
+//
+//    }
 
     static void test(Method m, Class<? extends Throwable>... ts) {
         Throwable caught = null;
@@ -231,19 +189,8 @@
     }
 
     @BeforeClass
-    public void generateClass() throws Exception {
-        byte[] ba = Base64.getDecoder().decode(CLASS_CondyNestedTest_Code);
-        ClassLoader l = new ClassLoader(CondyReturnPrimitiveTest.class.getClassLoader()) {
-            @Override
-            protected Class<?> findClass(String name) throws ClassNotFoundException {
-                if (name == "CondyNestedTest_Code") {
-                    return defineClass(name, ba, 0, ba.length);
-                }
-                return null;
-            }
-        };
-
-        c = l.loadClass("CondyNestedTest_Code");
+    public void findClass() throws Exception {
+        c = Class.forName("CondyNestedTest_Code");
     }
 
     /**