1/*
2 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 8062280
27 * @summary C2: inlining failure due to access checks being too strict
28 * @modules java.base/jdk.internal.misc
29 * @library /test/lib /
30 *
31 * @run main/othervm compiler.jsr292.MHInlineTest
32 */
33
34package compiler.jsr292;
35
36import jdk.test.lib.process.OutputAnalyzer;
37import jdk.test.lib.process.ProcessTools;
38
39import java.lang.invoke.MethodHandle;
40import java.lang.invoke.MethodHandles;
41import java.lang.invoke.MethodType;
42
43import static jdk.test.lib.Asserts.assertEquals;
44
45public class MHInlineTest {
46    public static void main(String[] args) throws Exception {
47        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
48                "-XX:+IgnoreUnrecognizedVMOptions", "-showversion",
49                "-XX:-TieredCompilation", "-Xbatch",
50                "-XX:+PrintCompilation", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining",
51                "-XX:CompileCommand=dontinline,compiler.jsr292.MHInlineTest::test*",
52                    Launcher.class.getName());
53
54        OutputAnalyzer analyzer = new OutputAnalyzer(pb.start());
55
56        analyzer.shouldHaveExitValue(0);
57
58        // The test is applicable only to C2 (present in Server VM).
59        if (analyzer.getStderr().contains("Server VM")) {
60            analyzer.shouldContain("compiler.jsr292.MHInlineTest$B::public_x (3 bytes)   inline (hot)");
61            analyzer.shouldContain("compiler.jsr292.MHInlineTest$B::protected_x (3 bytes)   inline (hot)");
62            analyzer.shouldContain("compiler.jsr292.MHInlineTest$B::package_x (3 bytes)   inline (hot)");
63            analyzer.shouldContain("compiler.jsr292.MHInlineTest$A::package_final_x (3 bytes)   inline (hot)");
64            analyzer.shouldContain("compiler.jsr292.MHInlineTest$B::private_x (3 bytes)   inline (hot)");
65            analyzer.shouldContain("compiler.jsr292.MHInlineTest$B::private_static_x (3 bytes)   inline (hot)");
66            analyzer.shouldContain("compiler.jsr292.MHInlineTest$A::package_static_x (3 bytes)   inline (hot)");
67        }
68    }
69
70    static class A {
71        public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
72
73        public Class<?>         public_x() { return A.class; }
74        protected Class<?>   protected_x() { return A.class; }
75        Class<?>               package_x() { return A.class; }
76        final Class<?>   package_final_x() { return A.class; }
77
78        static Class<?> package_static_x() { return A.class; }
79    }
80
81    static class B extends A {
82        public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
83
84        @Override public    Class<?>    public_x() { return B.class; }
85        @Override protected Class<?> protected_x() { return B.class; }
86        @Override Class<?>             package_x() { return B.class; }
87
88        private   Class<?>             private_x() { return B.class; }
89        static    Class<?>      private_static_x() { return B.class; }
90    }
91
92    static final MethodHandle A_PUBLIC_X;
93    static final MethodHandle A_PROTECTED_X;
94    static final MethodHandle A_PACKAGE_X;
95    static final MethodHandle A_PACKAGE_STATIC_X;
96    static final MethodHandle A_PACKAGE_FINAL_X;
97
98    static final MethodHandle B_PRIVATE_X;
99    static final MethodHandle B_PRIVATE_STATIC_X;
100
101    static {
102        try {
103            MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
104
105            A_PUBLIC_X = LOOKUP.findVirtual(
106                    A.class, "public_x", MethodType.methodType(Class.class));
107            A_PROTECTED_X = LOOKUP.findVirtual(
108                    A.class, "protected_x", MethodType.methodType(Class.class));
109            A_PACKAGE_X = LOOKUP.findVirtual(
110                    A.class, "package_x", MethodType.methodType(Class.class));
111            A_PACKAGE_FINAL_X = LOOKUP.findVirtual(
112                    A.class, "package_final_x", MethodType.methodType(Class.class));
113            A_PACKAGE_STATIC_X = LOOKUP.findStatic(
114                    A.class, "package_static_x", MethodType.methodType(Class.class));
115
116            B_PRIVATE_X = B.LOOKUP.findVirtual(
117                    B.class, "private_x", MethodType.methodType(Class.class));
118            B_PRIVATE_STATIC_X = B.LOOKUP.findStatic(
119                    B.class, "private_static_x", MethodType.methodType(Class.class));
120        } catch (Exception e) {
121            throw new Error(e);
122        }
123    }
124
125    static final A a = new B();
126
127    private static void testPublicMH() {
128        try {
129            Class<?> r = (Class<?>)A_PUBLIC_X.invokeExact(a);
130            assertEquals(r, B.class);
131        } catch (Throwable throwable) {
132            throw new Error(throwable);
133        }
134    }
135
136    private static void testProtectedMH() {
137        try {
138            Class<?> r = (Class<?>)A_PROTECTED_X.invokeExact(a);
139            assertEquals(r, B.class);
140        } catch (Throwable throwable) {
141            throw new Error(throwable);
142        }
143    }
144
145    private static void testPackageMH() {
146        try {
147            Class<?> r = (Class<?>)A_PACKAGE_X.invokeExact(a);
148            assertEquals(r, B.class);
149        } catch (Throwable throwable) {
150            throw new Error(throwable);
151        }
152    }
153
154    private static void testPackageFinalMH() {
155        try {
156            Class<?> r = (Class<?>)A_PACKAGE_FINAL_X.invokeExact(a);
157            assertEquals(r, A.class);
158        } catch (Throwable throwable) {
159            throw new Error(throwable);
160        }
161    }
162
163    private static void testPackageStaticMH() {
164        try {
165            Class<?> r = (Class<?>)A_PACKAGE_STATIC_X.invokeExact();
166            assertEquals(r, A.class);
167        } catch (Throwable throwable) {
168            throw new Error(throwable);
169        }
170    }
171
172    private static void testPrivateMH() {
173        try {
174            Class<?> r = (Class<?>)B_PRIVATE_X.invokeExact((B)a);
175            assertEquals(r, B.class);
176        } catch (Throwable throwable) {
177            throw new Error(throwable);
178        }
179    }
180
181    private static void testPrivateStaticMH() {
182        try {
183            Class<?> r = (Class<?>)B_PRIVATE_STATIC_X.invokeExact();
184            assertEquals(r, B.class);
185        } catch (Throwable throwable) {
186            throw new Error(throwable);
187        }
188    }
189
190    static class Launcher {
191        public static void main(String[] args) throws Exception {
192            for (int i = 0; i < 20_000; i++) {
193                testPublicMH();
194            }
195            for (int i = 0; i < 20_000; i++) {
196                testProtectedMH();
197            }
198            for (int i = 0; i < 20_000; i++) {
199                testPackageMH();
200            }
201            for (int i = 0; i < 20_000; i++) {
202                testPackageFinalMH();
203            }
204            for (int i = 0; i < 20_000; i++) {
205                testPackageStaticMH();
206            }
207            for (int i = 0; i < 20_000; i++) {
208                testPrivateMH();
209            }
210            for (int i = 0; i < 20_000; i++) {
211                testPrivateStaticMH();
212            }
213        }
214    }
215}
216