hotspot/test/compiler/jsr292/NonInlinedCall/InvokeTest.java
changeset 35086 bbf32241d851
child 35099 982950884444
equal deleted inserted replaced
35085:839c8ba29724 35086:bbf32241d851
       
     1 /*
       
     2  * Copyright (c) 2015, 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 8072008
       
    27  * @library /testlibrary /../../test/lib
       
    28  * @build InvokeTest NonInlinedReinvoker
       
    29  * @run main ClassFileInstaller sun.hotspot.WhiteBox
       
    30  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
       
    31  *                              java.lang.invoke.InvokeTest
       
    32  *                              java.lang.invoke.InvokeTest$T
       
    33  *                              java.lang.invoke.InvokeTest$P1
       
    34  *                              java.lang.invoke.InvokeTest$P2
       
    35  *                              java.lang.invoke.InvokeTest$I
       
    36  *                              java.lang.invoke.NonInlinedReinvoker
       
    37  *                              jdk.test.lib.Asserts
       
    38  * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions
       
    39  *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
       
    40  *                   -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1
       
    41  *                      java.lang.invoke.InvokeTest
       
    42  */
       
    43 package java.lang.invoke;
       
    44 
       
    45 import sun.hotspot.WhiteBox;
       
    46 import static jdk.test.lib.Asserts.*;
       
    47 
       
    48 public class InvokeTest {
       
    49     static MethodHandles.Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
       
    50 
       
    51     static final MethodHandle virtualMH;  // invokevirtual   T.f1
       
    52     static final MethodHandle staticMH;   // invokestatic    T.f2
       
    53     static final MethodHandle intfMH;     // invokeinterface I.f1
       
    54     static final MethodHandle specialMH;  // invokespecial   T.f4 T
       
    55     static final MethodHandle basicMH;
       
    56 
       
    57     static final WhiteBox WB = WhiteBox.getWhiteBox();
       
    58 
       
    59     static volatile boolean doDeopt = false;
       
    60 
       
    61     static {
       
    62         try {
       
    63             MethodType mtype = MethodType.methodType(Class.class);
       
    64 
       
    65             virtualMH  = LOOKUP.findVirtual(T.class, "f1", mtype);
       
    66             staticMH   = LOOKUP.findStatic (T.class, "f2", mtype);
       
    67             intfMH     = LOOKUP.findVirtual(I.class, "f3", mtype);
       
    68             specialMH  = LOOKUP.findSpecial(T.class, "f4", mtype, T.class);
       
    69             basicMH    = NonInlinedReinvoker.make(staticMH);
       
    70         } catch (Exception e) {
       
    71             throw new Error(e);
       
    72         }
       
    73     }
       
    74 
       
    75     static class T implements I {
       
    76         @DontInline public        Class<?> f1() { if (doDeopt) WB.deoptimize(); return T.class; }
       
    77         @DontInline public static Class<?> f2() { if (doDeopt) WB.deoptimize(); return T.class; }
       
    78         @DontInline private       Class<?> f4() { if (doDeopt) WB.deoptimize(); return T.class; }
       
    79     }
       
    80 
       
    81     static class P1 extends T {
       
    82         @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimize(); return P1.class; }
       
    83         @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimize(); return P1.class; }
       
    84     }
       
    85 
       
    86     static class P2 extends T {
       
    87         @DontInline public Class<?> f1() { if (doDeopt) WB.deoptimize(); return P2.class; }
       
    88         @DontInline public Class<?> f3() { if (doDeopt) WB.deoptimize(); return P2.class; }
       
    89     }
       
    90 
       
    91     static interface I {
       
    92         @DontInline default Class<?> f3() { if (doDeopt) WB.deoptimize(); return I.class; }
       
    93     }
       
    94 
       
    95     @DontInline
       
    96     static void linkToVirtual(Object obj, Class<?> extecpted) {
       
    97         try {
       
    98             Class<?> cls = (Class<?>)virtualMH.invokeExact((T)obj);
       
    99             assertEquals(cls, obj.getClass());
       
   100         } catch (Throwable e) {
       
   101             throw new Error(e);
       
   102         }
       
   103     }
       
   104 
       
   105     @DontInline
       
   106     static void linkToInterface(Object obj, Class<?> expected) {
       
   107         try {
       
   108             Class<?> cls = (Class<?>)intfMH.invokeExact((I)obj);
       
   109             assertEquals(cls, expected);
       
   110         } catch (Throwable e) {
       
   111             throw new Error(e);
       
   112         }
       
   113     }
       
   114 
       
   115     @DontInline
       
   116     static void linkToStatic() {
       
   117         try {
       
   118             Class<?> cls = (Class<?>)staticMH.invokeExact();
       
   119             assertEquals(cls, T.class);
       
   120         } catch (Throwable e) {
       
   121             throw new Error(e);
       
   122         }
       
   123     }
       
   124 
       
   125     @DontInline
       
   126     static void linkToSpecial(Object obj, Class<?> expected) {
       
   127         try {
       
   128             Class<?> cls = (Class<?>)specialMH.invokeExact((T)obj);
       
   129             assertEquals(cls, expected);
       
   130         } catch (Throwable e) {
       
   131             throw new Error(e);
       
   132         }
       
   133     }
       
   134 
       
   135     @DontInline
       
   136     static void invokeBasic() {
       
   137         try {
       
   138             Class<?> cls = (Class<?>)basicMH.invokeBasic();
       
   139             assertEquals(cls, T.class);
       
   140         } catch (Throwable e) {
       
   141             throw new Error(e);
       
   142         }
       
   143     }
       
   144 
       
   145     static void run(Runnable r) {
       
   146         for (int i = 0; i < 20_000; i++) {
       
   147             r.run();
       
   148         }
       
   149 
       
   150         doDeopt = true;
       
   151         r.run();
       
   152         doDeopt = false;
       
   153 
       
   154         WB.clearInlineCaches();
       
   155 
       
   156         for (int i = 0; i < 20_000; i++) {
       
   157             r.run();
       
   158         }
       
   159 
       
   160         doDeopt = true;
       
   161         r.run();
       
   162         doDeopt = false;
       
   163     }
       
   164 
       
   165     static void testVirtual() {
       
   166         System.out.println("linkToVirtual");
       
   167 
       
   168         // Monomorphic case (optimized virtual call)
       
   169         run(() -> linkToVirtual(new T(), T.class));
       
   170 
       
   171         // Megamorphic case (virtual call)
       
   172         Object[] recv = new Object[] { new T(), new P1(), new P2() };
       
   173         run(() -> {
       
   174             for (Object r : recv) {
       
   175                 linkToVirtual(r, r.getClass());
       
   176             }});
       
   177     }
       
   178 
       
   179     static void testInterface() {
       
   180         System.out.println("linkToInterface");
       
   181 
       
   182         // Monomorphic case (optimized virtual call)
       
   183         run(() -> linkToInterface(new T(), I.class));
       
   184 
       
   185         // Megamorphic case (virtual call)
       
   186         Object[][] recv = new Object[][] {{new T(), I.class}, {new P1(), P1.class}, {new P2(), P2.class}};
       
   187         run(() -> {
       
   188             for (Object[] r : recv) {
       
   189                 linkToInterface(r[0], (Class<?>)r[1]);
       
   190             }});
       
   191     }
       
   192 
       
   193     static void testSpecial() {
       
   194         System.out.println("linkToSpecial");
       
   195         // Monomorphic case (optimized virtual call)
       
   196         run(() -> linkToSpecial(new T(), T.class));
       
   197     }
       
   198 
       
   199     static void testStatic() {
       
   200         System.out.println("linkToStatic");
       
   201         // static call
       
   202         run(() -> linkToStatic());
       
   203     }
       
   204 
       
   205     static void testBasic() {
       
   206         System.out.println("invokeBasic");
       
   207         // static call
       
   208         run(() -> invokeBasic());
       
   209     }
       
   210 
       
   211     public static void main(String[] args) {
       
   212         testVirtual();
       
   213         testInterface();
       
   214         testSpecial();
       
   215         testStatic();
       
   216         testBasic();
       
   217     }
       
   218 }