From 0a352526f390f8d204ccdeace3b3fdddcd47b017 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 9 Mar 2016 18:31:49 +0300 Subject: [PATCH] 8151516: test/tools/javac/TestIndyStringConcat depends on runtime JDK details Reviewed-by: mcimadamore --- .../StringConcat/TestIndyStringConcat.java | 111 ++++++++++++++++++ .../tools/javac/StringConcat/access/Test.java | 26 ++-- .../tools/javac/TestIndyStringConcat.java | 74 ------------ 3 files changed, 126 insertions(+), 85 deletions(-) create mode 100644 langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java delete mode 100644 langtools/test/tools/javac/TestIndyStringConcat.java diff --git a/langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java b/langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java new file mode 100644 index 00000000000..4c8917bbbf9 --- /dev/null +++ b/langtools/test/tools/javac/StringConcat/TestIndyStringConcat.java @@ -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; + } + +} diff --git a/langtools/test/tools/javac/StringConcat/access/Test.java b/langtools/test/tools/javac/StringConcat/access/Test.java index fc9e78c0e31..72237e8b4ef 100644 --- a/langtools/test/tools/javac/StringConcat/access/Test.java +++ b/langtools/test/tools/javac/StringConcat/access/Test.java @@ -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.io.File; 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 actualTypes; diff --git a/langtools/test/tools/javac/TestIndyStringConcat.java b/langtools/test/tools/javac/TestIndyStringConcat.java deleted file mode 100644 index b799f70015b..00000000000 --- a/langtools/test/tools/javac/TestIndyStringConcat.java +++ /dev/null @@ -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(); - } - } - } -}