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

interface Base {
  void foo(int i);
  void $noinline$bar();
}

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

  // Test rewriting invoke-interface into invoke-virtual when inlining fails.
  public void $noinline$bar() {
    System.out.print("");
    System.out.print("");
    System.out.print("");
    System.out.print("");
    System.out.print("");
    System.out.print("");
    System.out.print("");
    System.out.print("");
  }

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

class Main2 extends Main1 {
  public 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 testImplement() on stack
  // should be deoptimized.
  static void testImplement(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);
    sMain1.$noinline$bar();

    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, "testImplement");
    testImplement(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() {
        testImplement(false, true, false);
      }
    }.start();

    // This will create Main2 instance in the middle of testImplement().
    testImplement(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();
  }
}
