Path: blob/master/test/hotspot/jtreg/compiler/cha/DefaultRootMethod.java
64474 views
/*1* Copyright (c) 2021, 2022, 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* @requires !vm.graal.enabled & vm.opt.final.UseVtableBasedCHA == true26* @modules java.base/jdk.internal.org.objectweb.asm27* java.base/jdk.internal.misc28* java.base/jdk.internal.vm.annotation29* @library /test/lib /30* @compile Utils.java31* @build sun.hotspot.WhiteBox32* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox33*34* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions35* -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet36* -XX:CompileCommand=compileonly,*::m37* -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test38* -Xbatch -Xmixed -XX:+WhiteBoxAPI39* -XX:-TieredCompilation40* compiler.cha.DefaultRootMethod41*42* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions43* -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet44* -XX:CompileCommand=compileonly,*::m45* -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test46* -Xbatch -Xmixed -XX:+WhiteBoxAPI47* -XX:+TieredCompilation -XX:TieredStopAtLevel=148* compiler.cha.DefaultRootMethod49*/50package compiler.cha;5152import java.lang.invoke.MethodHandle;53import java.lang.invoke.MethodHandles;5455import static compiler.cha.Utils.*;5657public class DefaultRootMethod {58public static void main(String[] args) {59run(DefaultRoot.class);60run(InheritedDefault.class);6162// Implementation limitation: CHA is not performed by C1 during inlining through MH linkers.63if (!sun.hotspot.code.Compiler.isC1Enabled()) {64run(DefaultRoot.TestMH.class, DefaultRoot.class);65run(InheritedDefault.TestMH.class, InheritedDefault.class);66}6768System.out.println("TEST PASSED");69}7071public static class DefaultRoot extends ATest<DefaultRoot.C> {72public DefaultRoot() {73super(C.class, D.class);74}7576interface I { default Object m() { return CORRECT; } }7778static class C implements I { /* inherited I.m */}7980static class D extends C { /* inherited I.m */ }8182static abstract class E1 extends C { /* empty */ }83static abstract class E2 extends C { public abstract Object m(); }84static abstract class E3 extends C { public Object m() { return "E3.m"; } }8586interface I1 extends I { Object m(); }87interface I2 extends I { default Object m() { return "I2.m"; } }8889static abstract class F1 extends C implements I1 { }90static abstract class F2 extends C implements I2 { }9192static class G extends C { public Object m() { return CORRECT; } }9394@Override95public Object test(C obj) throws Throwable {96return obj.m(); // invokevirtual C.m()97}9899@Override100public void checkInvalidReceiver() {101// nothing to do: concrete class types are enforced by the verifier102}103104@TestCase105public void test() {106// 0. Trigger compilation of a megamorphic call site107compile(megamorphic()); // Dn <: D.m <: C <: I.m DEFAULT108assertCompiled();109110// Dependency: type = unique_concrete_method, context = C, method = D.m111112// 1. No invalidation: abstract classes don't participate in CHA.113initialize(E1.class, // ABSTRACT E1 <: C <: I.m DEFAULT114E2.class, // ABSTRACT E2.m ABSTRACT <: C <: I.m DEFAULT115E3.class, // ABSTRACT E3.m <: C <: I.m DEFAULT116F1.class, // ABSTRACT F1 <: C <: I.m DEFAULT, I1.m ABSTRACT117F2.class); // ABSTRACT F2 <: C <: I.m DEFAULT, I2.m DEFAULT118assertCompiled();119120// 2. Dependency invalidation: G.m <: C <: I.m DEFAULT121load(G.class);122assertCompiled();123124// 3. Dependency invalidation: G.m <: C <: I.m DEFAULT125initialize(G.class);126assertNotCompiled();127128// 4. Recompilation: no inlining, no dependencies129compile(megamorphic());130call(new C() { public Object m() { return CORRECT; } }); // Cn.m <: C <: I.m DEFAULT131call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C <: I.m DEFAULT132assertCompiled();133}134135public static class TestMH extends DefaultRoot {136static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup());137138@Override139public Object test(C obj) throws Throwable {140return TEST_MH.invokeExact(obj); // invokevirtual C.m()141}142}143}144145public static class InheritedDefault extends ATest<InheritedDefault.C> {146public InheritedDefault() {147super(C.class, D.class);148}149150interface I { Object m(); }151interface J extends I { default Object m() { return CORRECT; } }152153static abstract class C implements I { /* inherits I.m ABSTRACT */}154155// NB! The class is marked abstract to avoid abstract_with_unique_concrete_subtype dependency156static abstract class D extends C implements J { /* inherits J.m DEFAULT*/ }157158static abstract class E1 extends C { /* empty */ }159static abstract class E2 extends C { public abstract Object m(); }160static abstract class E3 extends C { public Object m() { return "E3.m"; } }161162interface I1 extends I { Object m(); }163interface I2 extends I { default Object m() { return "I2.m"; } }164165static abstract class F1 extends C implements I1 { }166static abstract class F2 extends C implements I2 { }167168interface K extends I { default Object m() { return CORRECT; } }169static class G extends C implements K { /* inherits K.m DEFAULT */ }170171@Override172public Object test(C obj) throws Throwable {173return obj.m(); // invokevirtual C.m()174}175176@Override177public void checkInvalidReceiver() {178// nothing to do: concrete class types are enforced by the verifier179}180181@TestCase182public void test() {183// 0. Trigger compilation of a megamorphic call site184compile(megamorphic()); // Dn <: D.m <: C <: I.m ABSTRACT, J.m DEFAULT185assertCompiled();186187// Dependency: type = unique_concrete_method, context = C, method = D.m188189// 1. No invalidation: abstract classes don't participate in CHA.190initialize(E1.class, // ABSTRACT E1 <: C <: I.m ABSTRACT191E2.class, // ABSTRACT E2.m ABSTRACT <: C <: I.m ABSTRACT192E3.class, // ABSTRACT E3.m <: C <: I.m ABSTRACT193F1.class, // ABSTRACT F1 <: C <: I.m ABSTRACT, I1.m ABSTRACT194F2.class); // ABSTRACT F2 <: C <: I.m ABSTRACT, I2.m DEFAULT195assertCompiled();196197// 2. No invalidation: not yet linked classes don't participate in CHA.198load(G.class);199assertCompiled();200201// 3. Dependency invalidation: G.m <: C <: I.m DEFAULT202initialize(G.class);203assertNotCompiled();204205// 4. Recompilation: no inlining, no dependencies206compile(megamorphic());207call(new C() { public Object m() { return CORRECT; } }); // Cn.m <: C <: I.m DEFAULT208call(new G() { public Object m() { return CORRECT; } }); // Gn <: G.m <: C <: I.m DEFAULT209assertCompiled();210}211212public static class TestMH extends InheritedDefault {213static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup());214215@Override216public Object test(C obj) throws Throwable {217return TEST_MH.invokeExact(obj); // invokevirtual C.m()218}219}220}221}222223224