/*
 * 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.
 */

class Main1 implements Base {
}

class Main2 extends Main1 {
  public void foobar() {}
}

class Main3 implements Base {
  public int foo(int i) {
    if (i != 3) {
      printError("error3");
    }
    return -(i + 10);
  }
}

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

  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);
    }
  }

  static int getValue(Class<?> cls) {
    if (cls == Main1.class || cls == Main2.class) {
      return 1;
    }
    return 3;
  }

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

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

    if (sMain1.foo(getValue(sMain1.getClass())) != 11) {
      System.out.println("11 expected.");
    }
    if (sMain1.$noinline$bar() != -1) {
      System.out.println("-1 expected.");
    }
    if (sMain2.foo(getValue(sMain2.getClass())) != 11) {
      System.out.println("11 expected.");
    }

    if (createMain3) {
      // Wait for the other thread to start.
      while (!sOtherThreadStarted);
      // Create an Main2 instance and assign it to sMain2.
      // sMain1 is kept the same.
      sMain3 = Helper.createMain3();
      // 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 Main3 is linked by
    // calling Helper.createMain3(), 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.
    if (sMain1.foo(getValue(sMain1.getClass())) != 11) {
      System.out.println("11 expected.");
    }
    if ((createMain3 || wait) && sHasJIT && !sIsOptimizing) {
      // This method should be deoptimized right after Main3 is created.
      assertIsInterpreted();
    }

    if (sMain3 != null) {
      if (sMain3.foo(getValue(sMain3.getClass())) != -13) {
        System.out.println("-13 expected.");
      }
    }
  }

  // Test scenarios under which CHA-based devirtualization happens,
  // and class loading that implements 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.
    // sMain2 is an instance of Main2.
    // Neither Main1 nor Main2 override default method Base.foo().
    // Main3 hasn't bee loaded yet.
    sMain1 = new Main1();
    sMain2 = new Main2();

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

    if (sHasJIT && !sIsOptimizing) {
      assertSingleImplementation(Base.class, "foo", true);
      assertSingleImplementation(Main1.class, "foo", true);
    } else {
      // Main3 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() {
        testImplement(false, true, false);
      }
    }.start();

    // This will create Main3 instance in the middle of testImplement().
    testImplement(true, false, false);
    assertSingleImplementation(Base.class, "foo", false);
    assertSingleImplementation(Main1.class, "foo", true);
    assertSingleImplementation(sMain3.getClass(), "foo", true);
  }

  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 createMain3() in another class to avoid class loading due to verifier.
class Helper {
  static Base createMain3() {
    return new Main3();
  }
}
