--- 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");
}
/**