/*
 * Copyright (c) 2021, 2023, 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
 * @requires !vm.graal.enabled & vm.opt.final.UseVtableBasedCHA == true
 * @modules java.base/jdk.internal.org.objectweb.asm
 *          java.base/jdk.internal.misc
 *          java.base/jdk.internal.vm.annotation
 * @library /test/lib /
 * @compile Utils.java
 * @build jdk.test.whitebox.WhiteBox
 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 *
 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
 *                   -XX:+PrintCompilation -XX:+PrintInlining -Xlog:dependencies=debug -verbose:class -XX:CompileCommand=quiet
 *                   -XX:CompileCommand=compileonly,*::m
 *                   -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test
 *                   -Xbatch -Xmixed -XX:+WhiteBoxAPI
 *                   -XX:-TieredCompilation
 *                   -XX:-StressMethodHandleLinkerInlining
 *                      compiler.cha.DefaultRootMethod
 *
 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
 *                   -XX:+PrintCompilation -XX:+PrintInlining -Xlog:dependencies=debug -verbose:class -XX:CompileCommand=quiet
 *                   -XX:CompileCommand=compileonly,*::m
 *                   -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=dontinline,*::test
 *                   -Xbatch -Xmixed -XX:+WhiteBoxAPI
 *                   -XX:+TieredCompilation -XX:TieredStopAtLevel=1
 *                   -XX:-StressMethodHandleLinkerInlining
 *                      compiler.cha.DefaultRootMethod
 */
package compiler.cha;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

import static compiler.cha.Utils.*;

public class DefaultRootMethod {
    public static void main(String[] args) {
        run(DefaultRoot.class);
        run(InheritedDefault.class);

        // Implementation limitation: CHA is not performed by C1 during inlining through MH linkers.
        if (!jdk.test.whitebox.code.Compiler.isC1Enabled()) {
            run(DefaultRoot.TestMH.class, DefaultRoot.class);
            run(InheritedDefault.TestMH.class, InheritedDefault.class);
        }

        System.out.println("TEST PASSED");
    }

    public static class DefaultRoot extends ATest<DefaultRoot.C> {
        public DefaultRoot() {
            super(C.class, D.class);
        }

        interface I { default Object m() { return CORRECT; } }

        static class C implements I { /* inherited I.m */}

        static class D extends C { /* inherited I.m */ }

        static abstract class E1 extends C { /* empty */ }
        static abstract class E2 extends C { public abstract Object m(); }
        static abstract class E3 extends C { public Object m() { return "E3.m"; } }

        interface I1 extends I { Object m(); }
        interface I2 extends I { default Object m() { return "I2.m"; } }

        static abstract class F1 extends C implements I1 { }
        static abstract class F2 extends C implements I2 { }

        static          class G  extends C { public Object m() { return CORRECT; } }

        @Override
        public Object test(C obj) throws Throwable {
            return obj.m(); // invokevirtual C.m()
        }

        @Override
        public void checkInvalidReceiver() {
            // nothing to do: concrete class types are enforced by the verifier
        }

        @TestCase
        public void test() {
            // 0. Trigger compilation of a megamorphic call site
            compile(megamorphic()); // Dn <: D.m <: C <: I.m DEFAULT
            assertCompiled();

            // Dependency: type = unique_concrete_method, context = C, method = D.m

            // 1. No invalidation: abstract classes don't participate in CHA.
            initialize(E1.class,  // ABSTRACT E1            <: C <: I.m DEFAULT
                       E2.class,  // ABSTRACT E2.m ABSTRACT <: C <: I.m DEFAULT
                       E3.class,  // ABSTRACT E3.m          <: C <: I.m DEFAULT
                       F1.class,  // ABSTRACT F1            <: C <: I.m DEFAULT, I1.m ABSTRACT
                       F2.class); // ABSTRACT F2            <: C <: I.m DEFAULT, I2.m DEFAULT
            assertCompiled();

            // 2. Dependency invalidation: G.m <: C <: I.m DEFAULT
            load(G.class);
            assertCompiled();

            // 3. Dependency invalidation: G.m <: C <: I.m DEFAULT
            initialize(G.class);
            assertNotCompiled();

            // 4. Recompilation: no inlining, no dependencies
            compile(megamorphic());
            call(new C() { public Object m() { return CORRECT; } }); //  Cn.m <: C <: I.m DEFAULT
            call(new G() { public Object m() { return CORRECT; } }); //  Gn <: G.m <: C <: I.m DEFAULT
            assertCompiled();
        }

        public static class TestMH extends DefaultRoot {
            static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup());

            @Override
            public Object test(C obj) throws Throwable {
                return TEST_MH.invokeExact(obj); // invokevirtual C.m()
            }
        }
    }

    public static class InheritedDefault extends ATest<InheritedDefault.C> {
        public InheritedDefault() {
            super(C.class, D.class);
        }

        interface I           { Object m(); }
        interface J extends I { default Object m() { return CORRECT; } }

        static abstract class C implements I { /* inherits I.m ABSTRACT */}

        // NB! The class is marked abstract to avoid abstract_with_unique_concrete_subtype dependency
        static abstract class D extends C implements J { /* inherits J.m DEFAULT*/ }

        static abstract class E1 extends C { /* empty */ }
        static abstract class E2 extends C { public abstract Object m(); }
        static abstract class E3 extends C { public Object m() { return "E3.m"; } }

        interface I1 extends I { Object m(); }
        interface I2 extends I { default Object m() { return "I2.m"; } }

        static abstract class F1 extends C implements I1 { }
        static abstract class F2 extends C implements I2 { }

        interface K extends I { default Object m() { return CORRECT; } }
        static class G extends C implements K { /* inherits K.m DEFAULT */ }

        @Override
        public Object test(C obj) throws Throwable {
            return obj.m(); // invokevirtual C.m()
        }

        @Override
        public void checkInvalidReceiver() {
            // nothing to do: concrete class types are enforced by the verifier
        }

        @TestCase
        public void test() {
            // 0. Trigger compilation of a megamorphic call site
            compile(megamorphic()); // Dn <: D.m <: C <: I.m ABSTRACT, J.m DEFAULT
            assertCompiled();

            // Dependency: type = unique_concrete_method, context = C, method = D.m

            // 1. No invalidation: abstract classes don't participate in CHA.
            initialize(E1.class,  // ABSTRACT E1            <: C <: I.m ABSTRACT
                       E2.class,  // ABSTRACT E2.m ABSTRACT <: C <: I.m ABSTRACT
                       E3.class,  // ABSTRACT E3.m          <: C <: I.m ABSTRACT
                       F1.class,  // ABSTRACT F1            <: C <: I.m ABSTRACT, I1.m ABSTRACT
                       F2.class); // ABSTRACT F2            <: C <: I.m ABSTRACT, I2.m DEFAULT
            assertCompiled();

            // 2. No invalidation: not yet linked classes don't participate in CHA.
            load(G.class);
            assertCompiled();

            // 3. Dependency invalidation: G.m <: C <: I.m DEFAULT
            initialize(G.class);
            assertNotCompiled();

            // 4. Recompilation: no inlining, no dependencies
            compile(megamorphic());
            call(new C() { public Object m() { return CORRECT; } }); //  Cn.m <: C <: I.m DEFAULT
            call(new G() { public Object m() { return CORRECT; } }); //  Gn <: G.m <: C <: I.m DEFAULT
            assertCompiled();
        }

        public static class TestMH extends InheritedDefault {
            static final MethodHandle TEST_MH = findVirtualHelper(C.class, "m", Object.class, MethodHandles.lookup());

            @Override
            public Object test(C obj) throws Throwable {
                return TEST_MH.invokeExact(obj); // invokevirtual C.m()
            }
        }
    }
}
