# HG changeset patch # User psandoz # Date 1517449426 28800 # Node ID 11920d5d14a8216d95b45bad5053b5b6266f285d # Parent 93de07994202a5f8846726d7692fb0506f5dba3c 8196533: Update CondyNestedTest.java to compile jcod file Reviewed-by: mchung diff -r 93de07994202 -r 11920d5d14a8 test/jdk/java/lang/invoke/condy/CondyNestedTest.java --- 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("", "()V", M -> - M.withFlags(Flag.ACC_PUBLIC) - .withCode(TypedCodeBuilder::new, C -> - C.aload_0().invokespecial("java/lang/Object", "", "()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", "", "(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", "", "(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("", "()V", M -> +// M.withFlags(Flag.ACC_PUBLIC) +// .withCode(TypedCodeBuilder::new, C -> +// C.aload_0().invokespecial("java/lang/Object", "", "()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", "", "(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", "", "(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... 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"); } /** diff -r 93de07994202 -r 11920d5d14a8 test/jdk/java/lang/invoke/condy/CondyNestedTest_Code.jcod --- a/test/jdk/java/lang/invoke/condy/CondyNestedTest_Code.jcod Thu Feb 01 02:05:35 2018 +0100 +++ b/test/jdk/java/lang/invoke/condy/CondyNestedTest_Code.jcod Wed Jan 31 17:43:46 2018 -0800 @@ -1,3 +1,26 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + */ + class CondyNestedTest_Code { 0xCAFEBABE; 0; // minor version @@ -33,7 +56,7 @@ NameAndType #25 #18; // #27 Method #17 #27; // #28 Utf8 "StackMapTable"; // #29 - Utf8 "main"; // #30 + Utf8 "main"; // #30 Utf8 "([Ljava/lang/String;)V"; // #31 Utf8 "java/lang/invoke/MethodType"; // #32 class #32; // #33 @@ -60,8 +83,8 @@ Utf8 "name"; // #54 Utf8 "Ljava/lang/String;"; // #55 NameAndType #54 #55; // #56 - ConstantDynamic 0s #56; // #57 - ConstantDynamic 1s #56; // #58 + Dynamic 0s #56; // #57 + Dynamic 1s #56; // #58 NameAndType #47 #48; // #59 Method #17 #59; // #60 MethodHandle 6b #60; // #61