8151516: test/tools/javac/TestIndyStringConcat depends on runtime JDK details
authorshade
Wed, 09 Mar 2016 18:31:49 +0300
changeset 36496 f21702a00d31
parent 36495 dd9141ca331a
child 36497 9c4840131512
8151516: test/tools/javac/TestIndyStringConcat depends on runtime JDK details Reviewed-by: mcimadamore
langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java
langtools/test/tools/javac/StringConcat/access/Test.java
langtools/test/tools/javac/TestIndyStringConcat.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java	Wed Mar 09 18:31:49 2016 +0300
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * 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.
+ */
+
+import com.sun.tools.classfile.*;
+import com.sun.tools.classfile.BootstrapMethods_attribute.BootstrapMethodSpecifier;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info;
+
+import java.io.File;
+
+/*
+ * @test
+ * @bug     8148483 8151516 8151223
+ * @summary Test that StringConcat is working for JDK >= 9
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -source 6 -target 6 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat false
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -source 7 -target 7 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat false
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -source 8 -target 8 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat false
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -XDstringConcat=inline -source 9 -target 9 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat false
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -XDstringConcat=indy -source 9 -target 9 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat true
+ *
+ * @clean TestIndyStringConcat*
+ * @compile -XDstringConcat=indyWithConstants -source 9 -target 9 TestIndyStringConcat.java
+ * @run main TestIndyStringConcat true
+ */
+public class TestIndyStringConcat {
+
+    static String other;
+
+    public static String test() {
+        return "Foo" + other;
+    }
+
+    public static void main(String[] args) throws Exception {
+        boolean expected = Boolean.valueOf(args[0]);
+        boolean actual = hasStringConcatFactoryCall("test");
+        if (expected != actual) {
+            throw new AssertionError("expected = " + expected + ", actual = " + actual);
+        }
+    }
+
+    public static boolean hasStringConcatFactoryCall(String methodName) throws Exception {
+        ClassFile classFile = ClassFile.read(new File(System.getProperty("test.classes", "."),
+                TestIndyStringConcat.class.getName() + ".class"));
+        ConstantPool constantPool = classFile.constant_pool;
+
+        BootstrapMethods_attribute bsm_attr =
+                (BootstrapMethods_attribute)classFile
+                        .getAttribute(Attribute.BootstrapMethods);
+
+        for (Method method : classFile.methods) {
+            if (method.getName(constantPool).equals(methodName)) {
+                Code_attribute code = (Code_attribute) method.attributes
+                        .get(Attribute.Code);
+                for (Instruction i : code.getInstructions()) {
+                    if (i.getOpcode() == Opcode.INVOKEDYNAMIC) {
+                        CONSTANT_InvokeDynamic_info indyInfo =
+                                (CONSTANT_InvokeDynamic_info) constantPool.get(i.getUnsignedShort(1));
+
+                        BootstrapMethodSpecifier bsmSpec =
+                                bsm_attr.bootstrap_method_specifiers[indyInfo.bootstrap_method_attr_index];
+
+                        CONSTANT_MethodHandle_info bsmInfo =
+                                (CONSTANT_MethodHandle_info) constantPool.get(bsmSpec.bootstrap_method_ref);
+
+                        if (bsmInfo.getCPRefInfo().getClassName().equals("java/lang/invoke/StringConcatFactory")) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+}
--- a/langtools/test/tools/javac/StringConcat/access/Test.java	Wed Mar 09 12:52:14 2016 +0300
+++ b/langtools/test/tools/javac/StringConcat/access/Test.java	Wed Mar 09 18:31:49 2016 +0300
@@ -21,17 +21,6 @@
  * questions.
  */
 
-/*
- * @test
- * @bug     8151223
- * @summary String concatenation fails with implicit toString() on package-private class
- * @modules jdk.jdeps/com.sun.tools.classfile
- * @compile -XDstringConcat=indy              Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java
- * @run main Test
- * @compile -XDstringConcat=indyWithConstants Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java
- * @run main Test
- */
-
 import com.sun.tools.classfile.*;
 import com.sun.tools.classfile.ConstantPool.*;
 
@@ -39,6 +28,21 @@
 import java.util.ArrayList;
 import java.util.List;
 
+/*
+ * @test
+ * @bug     8151223
+ * @summary String concatenation fails with implicit toString() on package-private class
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ *
+ * @clean *
+ * @compile -XDstringConcat=indy              Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java
+ * @run main Test
+ *
+ * @clean *
+ * @compile -XDstringConcat=indyWithConstants Holder.java PublicClass.java PublicInterface.java Public_PublicClass.java Public_PublicInterface.java Public_PrivateInterface1.java Public_PrivateInterface2.java Test.java
+ * @run main Test
+ */
+
 public class Test {
     static List<String> actualTypes;
 
--- a/langtools/test/tools/javac/TestIndyStringConcat.java	Wed Mar 09 12:52:14 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2015, 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.
- *
- * 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
- * @summary Test that StringConcat is working for JDK >= 9
- * @compile -source 6 -target 6 TestIndyStringConcat.java
- * @run main TestIndyStringConcat false
- * @clean TestIndyStringConcat*
- * @compile -source 7 -target 7 TestIndyStringConcat.java
- * @run main TestIndyStringConcat false
- * @clean TestIndyStringConcat*
- * @compile -source 8 -target 8 TestIndyStringConcat.java
- * @run main TestIndyStringConcat false
- * @clean TestIndyStringConcat*
- * @compile -XDstringConcat=inline -source 9 -target 9 TestIndyStringConcat.java
- * @run main TestIndyStringConcat false
- * @clean TestIndyStringConcat*
- * @compile -XDstringConcat=indy -source 9 -target 9 TestIndyStringConcat.java
- * @run main TestIndyStringConcat true
- * @clean TestIndyStringConcat*
- * @compile -XDstringConcat=indyWithConstants -source 9 -target 9 TestIndyStringConcat.java
- * @run main TestIndyStringConcat true
- */
-public class TestIndyStringConcat {
-
-    private static class MyObject {
-        public String toString() {
-            throw new RuntimeException("Boyyaa");
-        }
-    }
-
-    class Inner { }
-
-    public static void main(String[] args) {
-        boolean useIndyConcat = Boolean.valueOf(args[0]);
-        try {
-            String s = "Foo" + new MyObject();
-        } catch (RuntimeException ex) {
-            boolean indifiedStringConcat = false;
-            ex.printStackTrace();
-            for (StackTraceElement e : ex.getStackTrace()) {
-                if (e.getClassName().contains("$$StringConcat") &&
-                        e.getMethodName().equals("concat")) {
-                    indifiedStringConcat = true;
-                    break;
-                }
-            }
-            if (indifiedStringConcat != useIndyConcat) {
-                throw new AssertionError();
-            }
-        }
-    }
-}