/*
 * Copyright (C) 2016 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.
 */

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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

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

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

class Proxied implements Runnable {
  public void run() {
    synchronized(Main.class) {
      Main.sOtherThreadStarted = true;
      // Wait for Main2 to be linked and deoptimization is triggered.
      try {
        Main.class.wait();
      } catch (Exception e) {
      }
    }
  }
}

class MyInvocationHandler implements InvocationHandler {
  private final Proxied proxied;

  public MyInvocationHandler(Proxied proxied) {
    this.proxied = proxied;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    return method.invoke(proxied, args);
  }
}

public class Main {
  static Main1 sMain1;
  static Main1 sMain2;
  static volatile boolean sOtherThreadStarted;

  // 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() {
    sMain1.foo(sMain1.getClass() == Main1.class ? 1 : 2);

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

    // 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 (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.
  // Also create a proxy method such that a proxy method's frame is visited
  // during stack walking.
  public static void main(String[] args) {
    System.loadLibrary(args[0]);
    // sMain1 is an instance of Main1. Main2 hasn't bee loaded yet.
    sMain1 = new Main1();

    // Create another thread that calls a proxy method.
    new Thread() {
      public void run() {
        Runnable proxy = (Runnable)Proxy.newProxyInstance(
            Proxied.class.getClassLoader(),
            new Class[] { Runnable.class },
            new MyInvocationHandler(new Proxied()));
        proxy.run();
      }
    }.start();

    ensureJitCompiled(Main.class, "testOverride");
    // This will create Main2 instance in the middle of testOverride().
    testOverride();
  }

  private static native void ensureJitCompiled(Class<?> itf, String method_name);
}

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