Path: blob/master/test/hotspot/jtreg/compiler/jsr292/NonInlinedCall/InvokeTest.java
41153 views
/*1* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 807200826* @library /test/lib / ../patches27* @modules java.base/jdk.internal.misc28* java.base/jdk.internal.vm.annotation29*30* @build java.base/java.lang.invoke.MethodHandleHelper31* sun.hotspot.WhiteBox32* @run main/bootclasspath/othervm -XX:+IgnoreUnrecognizedVMOptions33* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI34* -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=135* compiler.jsr292.NonInlinedCall.InvokeTest36*/3738package compiler.jsr292.NonInlinedCall;3940import jdk.internal.vm.annotation.DontInline;41import sun.hotspot.WhiteBox;4243import java.lang.invoke.MethodHandle;44import java.lang.invoke.MethodHandleHelper;45import java.lang.invoke.MethodHandles;46import java.lang.invoke.MethodType;4748import static jdk.test.lib.Asserts.assertEquals;4950public class InvokeTest {51static MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP;5253static final MethodHandle virtualMH; // invokevirtual T.f154static final MethodHandle staticMH; // invokestatic T.f255static final MethodHandle intfMH; // invokeinterface I.f356static final MethodHandle defaultMH; // invokevirtual T.f357static final MethodHandle specialMH; // invokespecial T.f4 T58static final MethodHandle privateMH; // invokespecial I.f4 T5960static final MethodHandle intrinsicMH; // invokevirtual Object.hashCode6162static final WhiteBox WB = WhiteBox.getWhiteBox();6364static volatile boolean doDeopt = false;6566static {67try {68MethodType mtype = MethodType.methodType(Class.class);6970virtualMH = LOOKUP.findVirtual(T.class, "f1", mtype);71staticMH = LOOKUP.findStatic (T.class, "f2", mtype);72intfMH = LOOKUP.findVirtual(I.class, "f3", mtype);73defaultMH = LOOKUP.findVirtual(T.class, "f3", mtype);74specialMH = LOOKUP.findSpecial(T.class, "f4", mtype, T.class);75privateMH = LOOKUP.findSpecial(I.class, "f4", mtype, I.class);76intrinsicMH = LOOKUP.findVirtual(Object.class, "hashCode", MethodType.methodType(int.class));77} catch (Exception e) {78throw new Error(e);79}80}8182static class T implements I {83@DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return T.class; }84@DontInline public static Class<?> f2() { if (doDeopt) WB.deoptimizeAll(); return T.class; }85@DontInline private Class<?> f4() { if (doDeopt) WB.deoptimizeAll(); return T.class; }86}8788static class P1 extends T {89@DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return P1.class; }90@DontInline public Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return P1.class; }91}9293static class P2 extends T {94@DontInline public Class<?> f1() { if (doDeopt) WB.deoptimizeAll(); return P2.class; }95@DontInline public Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return P2.class; }96}9798interface I {99@DontInline default Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return I.class; }100@DontInline private Class<?> f4() { if (doDeopt) WB.deoptimizeAll(); return I.class; }101}102103interface J1 extends I {104@DontInline default Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return J1.class; }105}106107interface J2 extends I {108@DontInline default Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return J2.class; }109}110111interface J3 extends I {112@DontInline default Class<?> f3() { if (doDeopt) WB.deoptimizeAll(); return J3.class; }113}114115static class Q1 extends T implements J1 {}116static class Q2 extends T implements J2 {}117static class Q3 extends T implements J3 {}118119static class H {120public int hashCode() { return 0; }121}122123@DontInline124static void linkToVirtual(T recv, Class<?> expected) {125try {126Class<?> cls = (Class<?>)virtualMH.invokeExact(recv);127assertEquals(cls, expected);128} catch (Throwable e) {129throw new Error(e);130}131}132133@DontInline134static void linkToVirtualDefault(T recv, Class<?> expected) {135try {136Class<?> cls = (Class<?>)defaultMH.invokeExact(recv);137assertEquals(cls, expected);138} catch (Throwable e) {139throw new Error(e);140}141}142143@DontInline144static void linkToVirtualIntrinsic(Object recv, int expected) {145try {146int v = (int)intrinsicMH.invokeExact(recv);147assertEquals(v, expected);148} catch (Throwable e) {149throw new Error(e);150}151}152153@DontInline154static void linkToInterface(I recv, Class<?> expected) {155try {156Class<?> cls = (Class<?>)intfMH.invokeExact(recv);157assertEquals(cls, expected);158} catch (Throwable e) {159throw new Error(e);160}161}162163@DontInline164static void linkToStatic() {165try {166Class<?> cls = (Class<?>)staticMH.invokeExact();167assertEquals(cls, T.class);168} catch (Throwable e) {169throw new Error(e);170}171}172173@DontInline174static void linkToSpecial(T recv, Class<?> expected) {175try {176Class<?> cls = (Class<?>)specialMH.invokeExact(recv);177assertEquals(cls, expected);178} catch (Throwable e) {179throw new Error(e);180}181}182183@DontInline184static void linkToSpecialIntf(I recv, Class<?> expected) {185try {186Class<?> cls = (Class<?>)privateMH.invokeExact(recv);187assertEquals(cls, expected);188} catch (Throwable e) {189throw new Error(e);190}191}192193static void run(Runnable r) {194for (int i = 0; i < 20_000; i++) {195r.run();196}197198doDeopt = true;199r.run();200doDeopt = false;201202WB.clearInlineCaches();203204for (int i = 0; i < 20_000; i++) {205r.run();206}207208doDeopt = true;209r.run();210doDeopt = false;211}212213static void testVirtual() {214System.out.println("linkToVirtual");215216// Monomorphic case (optimized virtual call)217run(() -> linkToVirtual(new T(), T.class));218run(() -> linkToVirtualDefault(new T(), I.class));219220run(() -> linkToVirtualIntrinsic(new H(), 0));221222// Megamorphic case (optimized virtual call)223run(() -> {224linkToVirtual(new T() {}, T.class);225linkToVirtual(new T() {}, T.class);226linkToVirtual(new T() {}, T.class);227});228229run(() -> {230linkToVirtualDefault(new T(){}, I.class);231linkToVirtualDefault(new T(){}, I.class);232linkToVirtualDefault(new T(){}, I.class);233});234235// Megamorphic case (virtual call), multiple implementations236run(() -> {237linkToVirtual(new T(), T.class);238linkToVirtual(new P1(), P1.class);239linkToVirtual(new P2(), P2.class);240});241242run(() -> {243linkToVirtualDefault(new Q1(), J1.class);244linkToVirtualDefault(new Q2(), J2.class);245linkToVirtualDefault(new Q3(), J3.class);246});247}248249static void testInterface() {250System.out.println("linkToInterface");251252// Monomorphic case (optimized virtual call), concrete target method253run(() -> linkToInterface(new P1(), P1.class));254255// Monomorphic case (optimized virtual call), default target method256run(() -> linkToInterface(new T(), I.class));257258// Megamorphic case (virtual call)259run(() -> {260linkToInterface(new T(), I.class);261linkToInterface(new P1(), P1.class);262linkToInterface(new P2(), P2.class);263});264}265266static void testSpecial() {267System.out.println("linkToSpecial");268// Monomorphic case (optimized virtual call)269run(() -> linkToSpecial(new T(), T.class));270run(() -> linkToSpecialIntf(new T(), I.class));271}272273static void testStatic() {274System.out.println("linkToStatic");275// static call276run(() -> linkToStatic());277}278279public static void main(String[] args) {280testVirtual();281testInterface();282testSpecial();283testStatic();284}285}286287288