/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

abstract class Base {
    abstract void foo(int i);

    void printError(String msg) {
        System.out.println(msg);
    }
}

class Main1 extends Base {
    void foo(int i) {
        if (i != 1) {
            printError("error1");
        }
    }
}

class Main2 extends Main1 {
    void foo(int i) {
        if (i != 2) {
            printError("error2");
        }
    }
}

public class Main {
    static Base sMain1;
    static Base sMain2;

    static boolean sIsOptimizing = true;
    static boolean sHasJIT = true;
    static volatile boolean sOtherThreadStarted;

    private static void assertSingleImplementation(Class<?> clazz, String method_name, boolean b) {
        if (hasSingleImplementation(clazz, method_name) != b) {
            System.out.println(clazz + "." + method_name +
                    " doesn't have single implementation value of " + b);
        }
    }

    // sMain1.foo() will be always be Main1.foo() before Main2 is loaded/linked.
    // So sMain1.foo() can be devirtualized to Main1.foo() and be inlined.
    // After Helper.createMain2() which links in Main2, live testOverride() on stack
    // should be deoptimized.
    static void testOverride(boolean createMain2, boolean wait, boolean setHasJIT) {
        if (setHasJIT) {
            if (isInterpreted()) {
                sHasJIT = false;
            }
            return;
        }

        if (createMain2 && (sIsOptimizing || sHasJIT)) {
            assertIsManaged();
        }

        sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);

        if (createMain2) {
            // Wait for the other thread to start.
            while (!sOtherThreadStarted);
            // Create an Main2 instance and assign it to sMain2.
            // sMain1 is kept the same.
            sMain2 = Helper.createMain2();
            // Wake up the other thread.
            synchronized(Main.class) {
                Main.class.notify();
            }
        } else if (wait) {
            // This is the other thread.
            synchronized(Main.class) {
                sOtherThreadStarted = true;
                // Wait for Main2 to be linked and deoptimization is triggered.
                try {
                    Main.class.wait();
                } catch (Exception e) {
                }
            }
        }

        // There should be a deoptimization here right after Main2 is linked by
        // calling Helper.createMain2(), even though sMain1 didn't change.
        // The behavior here would be different if inline-cache is used, which
        // doesn't deoptimize since sMain1 still hits the type cache.
        sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);
        if ((createMain2 || wait) && sHasJIT && !sIsOptimizing) {
            // This method should be deoptimized right after Main2 is created.
            assertIsInterpreted();
        }

        if (sMain2 != null) {
            sMain2.foo(sMain2.getClass() == Main1.class ? 1 : 2);
        }
    }

    // Test scenarios under which CHA-based devirtualization happens,
    // and class loading that overrides a method can invalidate compiled code.
    public static void main(String[] args) {
        System.loadLibrary(args[0]);

        if (isInterpreted()) {
            sIsOptimizing = false;
        }

        // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
        sMain1 = new Main1();

        ensureJitCompiled(Main.class, "testOverride");
        testOverride(false, false, true);

        if (sHasJIT && !sIsOptimizing) {
            assertSingleImplementation(Base.class, "foo", true);
            assertSingleImplementation(Main1.class, "foo", true);
        } else {
            // Main2 is verified ahead-of-time so it's linked in already.
        }

        // Create another thread that also calls sMain1.foo().
        // Try to test suspend and deopt another thread.
        new Thread() {
            public void run() {
                testOverride(false, true, false);
            }
        }.start();

        // This will create Main2 instance in the middle of testOverride().
        testOverride(true, false, false);
        assertSingleImplementation(Base.class, "foo", false);
        assertSingleImplementation(Main1.class, "foo", false);
    }

    private static native void ensureJitCompiled(Class<?> itf, String method_name);
    private static native void assertIsInterpreted();
    private static native void assertIsManaged();
    private static native boolean isInterpreted();
    private static native boolean hasSingleImplementation(Class<?> clazz, String method_name);
}

// Put createMain2() in another class to avoid class loading due to verifier.
class Helper {
    static Main1 createMain2() {
        return new Main2();
    }
}
