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

package art;

import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.EnumSet;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;

import static art.SuspendEvents.setupTest;
import static art.SuspendEvents.setupSuspendBreakpointFor;
import static art.SuspendEvents.clearSuspendBreakpointFor;
import static art.SuspendEvents.setupSuspendSingleStepAt;
import static art.SuspendEvents.setupFieldSuspendFor;
import static art.SuspendEvents.setupSuspendMethodEvent;
import static art.SuspendEvents.setupSuspendExceptionEvent;
import static art.SuspendEvents.setupSuspendPopFrameEvent;
import static art.SuspendEvents.EVENT_TYPE_CLASS_LOAD;
import static art.SuspendEvents.EVENT_TYPE_CLASS_PREPARE;
import static art.SuspendEvents.setupSuspendClassEvent;

public class Test1953 {
  private static boolean IS_ART = System.getProperty("java.vm.name").equals("Dalvik");
  public final boolean canRunClassLoadTests;
  public static void doNothing() {}

  public interface TestRunnable extends Runnable {
    public int getBaseCallCount();
    public Method getCalledMethod() throws Exception;
    public default Method getCallingMethod() throws Exception {
      return this.getClass().getMethod("run");
    };
  }

  public static interface TestSuspender {
    public void setup(Thread thr);
    public void waitForSuspend(Thread thr);
    public void cleanup(Thread thr);
  }

  public static interface ThreadRunnable { public void run(Thread thr); }
  public static TestSuspender makeSuspend(final ThreadRunnable setup, final ThreadRunnable clean) {
    return new TestSuspender() {
      public void setup(Thread thr) { setup.run(thr); }
      public void waitForSuspend(Thread thr) { SuspendEvents.waitForSuspendHit(thr); }
      public void cleanup(Thread thr) { clean.run(thr); }
    };
  }

  public void runTestOn(TestRunnable testObj, ThreadRunnable su, ThreadRunnable cl) throws
      Exception {
    runTestOn(testObj, makeSuspend(su, cl));
  }

  private static void SafePrintStackTrace(StackTraceElement st[]) {
    for (StackTraceElement e : st) {
      System.out.println("\t" + e.getClassName() + "." + e.getMethodName() + "(" +
          (e.isNativeMethod() ? "Native Method" : e.getFileName()) + ")");
      if (e.getClassName().equals("art.Test1953") && e.getMethodName().equals("runTests")) {
        System.out.println("\t<Additional frames hidden>");
        break;
      }
    }
  }

  public void runTestOn(TestRunnable testObj, TestSuspender su) throws Exception {
    System.out.println("Single call with PopFrame on " + testObj + " base-call-count: " +
        testObj.getBaseCallCount());
    final CountDownLatch continue_latch = new CountDownLatch(1);
    final CountDownLatch startup_latch = new CountDownLatch(1);
    Runnable await = () -> {
      try {
        startup_latch.countDown();
        continue_latch.await();
      } catch (Exception e) {
        throw new Error("Failed to await latch", e);
      }
    };
    Thread thr = new Thread(() -> { await.run(); testObj.run(); });
    thr.start();

    // Wait until the other thread is started.
    startup_latch.await();

    // Do any final setup.
    preTest.accept(testObj);

    // Setup suspension method on the thread.
    su.setup(thr);

    // Let the other thread go.
    continue_latch.countDown();

    // Wait for the other thread to hit the breakpoint/watchpoint/whatever and suspend itself
    // (without re-entering java)
    su.waitForSuspend(thr);

    // Cleanup the breakpoint/watchpoint/etc.
    su.cleanup(thr);

    try {
      // Pop the frame.
      popFrame(thr);
    } catch (Exception e) {
      System.out.println("Failed to pop frame due to " + e);
      SafePrintStackTrace(e.getStackTrace());
    }

    // Start the other thread going again.
    Suspension.resume(thr);

    // Wait for the other thread to finish.
    thr.join();

    // See how many times calledFunction was called.
    System.out.println("result is " + testObj + " base-call count: " + testObj.getBaseCallCount());
  }

  public static abstract class AbstractTestObject implements TestRunnable {
    public int callerCnt;

    public AbstractTestObject() {
      callerCnt = 0;
    }

    public int getBaseCallCount() {
      return callerCnt;
    }

    public void run() {
      callerCnt++;
      // This function should be re-executed by the popFrame.
      calledFunction();
    }

    public Method getCalledMethod() throws Exception {
      return this.getClass().getMethod("calledFunction");
    }

    public abstract void calledFunction();
  }

  public static class RedefineTestObject extends AbstractTestObject implements Runnable {
    public static enum RedefineState { ORIGINAL, REDEFINED, };
    /* public static class RedefineTestObject extends AbstractTestObject implements Runnable {
     *   public static final byte[] CLASS_BYTES;
     *   public static final byte[] DEX_BYTES;
     *   static {
     *     CLASS_BYTES = null;
     *     DEX_BYTES = null;
     *   }
     *
     *   public EnumSet<RedefineState> redefine_states;
     *   public RedefineTestObject() {
     *     super();
     *     redefine_states = EnumSet.noneOf(RedefineState.class);
     *   }
     *   public String toString() {
     *     return "RedefineTestObject { states: " + redefine_states.toString()
     *                                            + " current: REDEFINED }";
     *   }
     *   public void calledFunction() {
     *     redefine_states.add(RedefineState.REDEFINED);  // line +0
     *     // We will trigger the redefinition using a breakpoint on the next line.
     *     doNothing();                                   // line +2
     *   }
     * }
     */
    public static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
      "yv66vgAAADUATQoADQAjBwAkCgAlACYJAAwAJwoAJQAoEgAAACwJAAIALQoAJQAuCgAvADAJAAwA" +
      "MQkADAAyBwAzBwA0BwA2AQASUmVkZWZpbmVUZXN0T2JqZWN0AQAMSW5uZXJDbGFzc2VzAQANUmVk" +
      "ZWZpbmVTdGF0ZQEAC0NMQVNTX0JZVEVTAQACW0IBAAlERVhfQllURVMBAA9yZWRlZmluZV9zdGF0" +
      "ZXMBABNMamF2YS91dGlsL0VudW1TZXQ7AQAJU2lnbmF0dXJlAQBETGphdmEvdXRpbC9FbnVtU2V0" +
      "PExhcnQvVGVzdDE5NTMkUmVkZWZpbmVUZXN0T2JqZWN0JFJlZGVmaW5lU3RhdGU7PjsBAAY8aW5p" +
      "dD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQAIdG9TdHJpbmcBABQoKUxqYXZhL2xh" +
      "bmcvU3RyaW5nOwEADmNhbGxlZEZ1bmN0aW9uAQAIPGNsaW5pdD4BAApTb3VyY2VGaWxlAQANVGVz" +
      "dDE5NTMuamF2YQwAGQAaAQAtYXJ0L1Rlc3QxOTUzJFJlZGVmaW5lVGVzdE9iamVjdCRSZWRlZmlu" +
      "ZVN0YXRlBwA3DAA4ADkMABUAFgwAHQAeAQAQQm9vdHN0cmFwTWV0aG9kcw8GADoIADsMADwAPQwA" +
      "PgA/DABAAEEHAEIMAEMAGgwAEgATDAAUABMBAB9hcnQvVGVzdDE5NTMkUmVkZWZpbmVUZXN0T2Jq" +
      "ZWN0AQAfYXJ0L1Rlc3QxOTUzJEFic3RyYWN0VGVzdE9iamVjdAEAEkFic3RyYWN0VGVzdE9iamVj" +
      "dAEAEmphdmEvbGFuZy9SdW5uYWJsZQEAEWphdmEvdXRpbC9FbnVtU2V0AQAGbm9uZU9mAQAmKExq" +
      "YXZhL2xhbmcvQ2xhc3M7KUxqYXZhL3V0aWwvRW51bVNldDsKAEQARQEAM1JlZGVmaW5lVGVzdE9i" +
      "amVjdCB7IHN0YXRlczogASBjdXJyZW50OiBSRURFRklORUQgfQEAF21ha2VDb25jYXRXaXRoQ29u" +
      "c3RhbnRzAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBAAlSRURFRklO" +
      "RUQBAC9MYXJ0L1Rlc3QxOTUzJFJlZGVmaW5lVGVzdE9iamVjdCRSZWRlZmluZVN0YXRlOwEAA2Fk" +
      "ZAEAFShMamF2YS9sYW5nL09iamVjdDspWgEADGFydC9UZXN0MTk1MwEACWRvTm90aGluZwcARgwA" +
      "PABJAQAkamF2YS9sYW5nL2ludm9rZS9TdHJpbmdDb25jYXRGYWN0b3J5BwBLAQAGTG9va3VwAQCY" +
      "KExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwO0xqYXZhL2xhbmcvU3RyaW5n" +
      "O0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5cGU7TGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xh" +
      "bmcvT2JqZWN0OylMamF2YS9sYW5nL2ludm9rZS9DYWxsU2l0ZTsHAEwBACVqYXZhL2xhbmcvaW52" +
      "b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwAQAeamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVz" +
      "ACEADAANAAEADgADABkAEgATAAAAGQAUABMAAAABABUAFgABABcAAAACABgABAABABkAGgABABsA" +
      "AAAuAAIAAQAAAA4qtwABKhICuAADtQAEsQAAAAEAHAAAAA4AAwAAACEABAAiAA0AIwABAB0AHgAB" +
      "ABsAAAAlAAEAAQAAAA0qtAAEtgAFugAGAACwAAAAAQAcAAAABgABAAAAJQABAB8AGgABABsAAAAv" +
      "AAIAAQAAAA8qtAAEsgAHtgAIV7gACbEAAAABABwAAAAOAAMAAAApAAsAKwAOACwACAAgABoAAQAb" +
      "AAAAKQABAAAAAAAJAbMACgGzAAuxAAAAAQAcAAAADgADAAAAGwAEABwACAAdAAMAIQAAAAIAIgAQ" +
      "AAAAIgAEAAwALwAPAAkAAgAMABFAGQANAC8ANQQJAEcASgBIABkAKQAAAAgAAQAqAAEAKw==");
    public static final byte[] DEX_BYTES = Base64.getDecoder().decode(
      "ZGV4CjAzNQAaR23N6WpunLRVX+BexSuzzNNiHNOvQpFoBwAAcAAAAHhWNBIAAAAAAAAAAKQGAAAq" +
      "AAAAcAAAABEAAAAYAQAABQAAAFwBAAAEAAAAmAEAAAwAAAC4AQAAAQAAABgCAAAwBQAAOAIAACID" +
      "AAA5AwAAQwMAAEsDAABPAwAAXAMAAGcDAABqAwAAbgMAAJEDAADCAwAA5QMAAPUDAAAZBAAAOQQA" +
      "AFwEAAB7BAAAjgQAAKIEAAC4BAAAzAQAAOcEAAD8BAAAEQUAABwFAAAwBQAATwUAAF4FAABhBQAA" +
      "ZAUAAGgFAABsBQAAeQUAAH4FAACGBQAAlgUAAKEFAACnBQAArwUAAMAFAADKBQAA0QUAAAgAAAAJ" +
      "AAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAGwAAABwA" +
      "AAAeAAAABgAAAAsAAAAAAAAABwAAAAwAAAAMAwAABwAAAA0AAAAUAwAAGwAAAA4AAAAAAAAAHQAA" +
      "AA8AAAAcAwAAAQABABcAAAACABAABAAAAAIAEAAFAAAAAgANACYAAAAAAAMAAgAAAAIAAwABAAAA" +
      "AgADAAIAAAACAAMAIgAAAAIAAAAnAAAAAwADACMAAAAMAAMAAgAAAAwAAQAhAAAADAAAACcAAAAN" +
      "AAQAIAAAAA0AAgAlAAAADQAAACcAAAACAAAAAQAAAAAAAAAEAwAAGgAAAIwGAABRBgAAAAAAAAQA" +
      "AQACAAAA+gIAAB0AAABUMAMAbhALAAAADAAiAQwAcBAGAAEAGgIZAG4gBwAhAG4gBwABABoAAABu" +
      "IAcAAQBuEAgAAQAMABEAAAABAAAAAAAAAPQCAAAGAAAAEgBpAAEAaQACAA4AAgABAAEAAADuAgAA" +
      "DAAAAHAQAAABABwAAQBxEAoAAAAMAFsQAwAOAAMAAQACAAAA/gIAAAsAAABUIAMAYgEAAG4gCQAQ" +
      "AHEABQAAAA4AIQAOPIcAGwAOPC0AJQAOACkADnk8AAEAAAAKAAAAAQAAAAsAAAABAAAACAAAAAEA" +
      "AAAJABUgY3VycmVudDogUkVERUZJTkVEIH0ACDxjbGluaXQ+AAY8aW5pdD4AAj47AAtDTEFTU19C" +
      "WVRFUwAJREVYX0JZVEVTAAFMAAJMTAAhTGFydC9UZXN0MTk1MyRBYnN0cmFjdFRlc3RPYmplY3Q7" +
      "AC9MYXJ0L1Rlc3QxOTUzJFJlZGVmaW5lVGVzdE9iamVjdCRSZWRlZmluZVN0YXRlOwAhTGFydC9U" +
      "ZXN0MTk1MyRSZWRlZmluZVRlc3RPYmplY3Q7AA5MYXJ0L1Rlc3QxOTUzOwAiTGRhbHZpay9hbm5v" +
      "dGF0aW9uL0VuY2xvc2luZ0NsYXNzOwAeTGRhbHZpay9hbm5vdGF0aW9uL0lubmVyQ2xhc3M7ACFM" +
      "ZGFsdmlrL2Fubm90YXRpb24vTWVtYmVyQ2xhc3NlczsAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWdu" +
      "YXR1cmU7ABFMamF2YS9sYW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABRMamF2YS9sYW5n" +
      "L1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7" +
      "ABNMamF2YS91dGlsL0VudW1TZXQ7ABNMamF2YS91dGlsL0VudW1TZXQ8AAlSRURFRklORUQAElJl" +
      "ZGVmaW5lVGVzdE9iamVjdAAdUmVkZWZpbmVUZXN0T2JqZWN0IHsgc3RhdGVzOiAADVRlc3QxOTUz" +
      "LmphdmEAAVYAAVoAAlpMAAJbQgALYWNjZXNzRmxhZ3MAA2FkZAAGYXBwZW5kAA5jYWxsZWRGdW5j" +
      "dGlvbgAJZG9Ob3RoaW5nAARuYW1lAAZub25lT2YAD3JlZGVmaW5lX3N0YXRlcwAIdG9TdHJpbmcA" +
      "BXZhbHVlAFt+fkQ4eyJtaW4tYXBpIjoxLCJzaGEtMSI6IjUyNzNjM2RmZWUxMDQ2NzIwYWY0MjVm" +
      "YTg1NTMxNmM5OWM4NmM4ZDIiLCJ2ZXJzaW9uIjoiMS4zLjE4LWRldiJ9AAIHASgcAxcWFwkXAwIE" +
      "ASgYAwIFAh8ECSQXGAIGASgcARgBAgECAgEZARkDAQGIgASEBQGBgASgBQMByAUBAbgEAAAAAAAB" +
      "AAAALgYAAAMAAAA6BgAAQAYAAEkGAAB8BgAAAQAAAAAAAAAAAAAAAwAAAHQGAAAQAAAAAAAAAAEA" +
      "AAAAAAAAAQAAACoAAABwAAAAAgAAABEAAAAYAQAAAwAAAAUAAABcAQAABAAAAAQAAACYAQAABQAA" +
      "AAwAAAC4AQAABgAAAAEAAAAYAgAAASAAAAQAAAA4AgAAAyAAAAQAAADuAgAAARAAAAQAAAAEAwAA" +
      "AiAAACoAAAAiAwAABCAAAAQAAAAuBgAAACAAAAEAAABRBgAAAxAAAAMAAABwBgAABiAAAAEAAACM" +
      "BgAAABAAAAEAAACkBgAA");

    public EnumSet<RedefineState> redefine_states;
    public RedefineTestObject() {
      super();
      redefine_states = EnumSet.noneOf(RedefineState.class);
    }

    public String toString() {
      return "RedefineTestObject { states: " + redefine_states.toString() + " current: ORIGINAL }";
    }

    public void calledFunction() {
      redefine_states.add(RedefineState.ORIGINAL);  // line +0
      // We will trigger the redefinition using a breakpoint on the next line.
      doNothing();                                  // line +2
    }
  }

  public static class ClassLoadObject implements TestRunnable {
    public int cnt;
    public int baseCallCnt;

    public static final String[] CLASS_NAMES = new String[] {
      "Lart/Test1953$ClassLoadObject$TC0;",
      "Lart/Test1953$ClassLoadObject$TC1;",
      "Lart/Test1953$ClassLoadObject$TC2;",
      "Lart/Test1953$ClassLoadObject$TC3;",
      "Lart/Test1953$ClassLoadObject$TC4;",
      "Lart/Test1953$ClassLoadObject$TC5;",
      "Lart/Test1953$ClassLoadObject$TC6;",
      "Lart/Test1953$ClassLoadObject$TC7;",
      "Lart/Test1953$ClassLoadObject$TC8;",
      "Lart/Test1953$ClassLoadObject$TC9;",
    };

    private static int curClass = 0;

    private static class TC0 { public static int foo; static { foo = 1; } }
    private static class TC1 { public static int foo; static { foo = 2; } }
    private static class TC2 { public static int foo; static { foo = 3; } }
    private static class TC3 { public static int foo; static { foo = 4; } }
    private static class TC4 { public static int foo; static { foo = 5; } }
    private static class TC5 { public static int foo; static { foo = 6; } }
    private static class TC6 { public static int foo; static { foo = 7; } }
    private static class TC7 { public static int foo; static { foo = 8; } }
    private static class TC8 { public static int foo; static { foo = 9; } }
    private static class TC9 { public static int foo; static { foo = 10; } }

    public ClassLoadObject() {
      super();
      cnt = 0;
      baseCallCnt = 0;
    }

    public int getBaseCallCount() {
      return baseCallCnt;
    }

    public void run() {
      baseCallCnt++;
      if (curClass == 0) {
        $noprecompile$calledFunction0();
      } else if (curClass == 1) {
        $noprecompile$calledFunction1();
      } else if (curClass == 2) {
        $noprecompile$calledFunction2();
      } else if (curClass == 3) {
        $noprecompile$calledFunction3();
      } else if (curClass == 4) {
        $noprecompile$calledFunction4();
      } else if (curClass == 5) {
        $noprecompile$calledFunction5();
      } else if (curClass == 6) {
        $noprecompile$calledFunction6();
      } else if (curClass == 7) {
        $noprecompile$calledFunction7();
      } else if (curClass == 8) {
        $noprecompile$calledFunction8();
      } else if (curClass == 9) {
        $noprecompile$calledFunction9();
      }
      curClass++;
    }

    public Method getCalledMethod() throws Exception {
      return this.getClass().getMethod("jnoprecompile$calledFunction" + curClass);
    }

    // Give these all a tag to prevent 1954 from compiling them (and loading the class as a
    // consequence).
    public void $noprecompile$calledFunction0() {
      cnt++;
      System.out.println("TC0.foo == " + TC0.foo);
    }

    public void $noprecompile$calledFunction1() {
      cnt++;
      System.out.println("TC1.foo == " + TC1.foo);
    }

    public void $noprecompile$calledFunction2() {
      cnt++;
      System.out.println("TC2.foo == " + TC2.foo);
    }

    public void $noprecompile$calledFunction3() {
      cnt++;
      System.out.println("TC3.foo == " + TC3.foo);
    }

    public void $noprecompile$calledFunction4() {
      cnt++;
      System.out.println("TC4.foo == " + TC4.foo);
    }

    public void $noprecompile$calledFunction5() {
      cnt++;
      System.out.println("TC5.foo == " + TC5.foo);
    }

    public void $noprecompile$calledFunction6() {
      cnt++;
      System.out.println("TC6.foo == " + TC6.foo);
    }

    public void $noprecompile$calledFunction7() {
      cnt++;
      System.out.println("TC7.foo == " + TC7.foo);
    }

    public void $noprecompile$calledFunction8() {
      cnt++;
      System.out.println("TC8.foo == " + TC8.foo);
    }

    public void $noprecompile$calledFunction9() {
      cnt++;
      System.out.println("TC9.foo == " + TC9.foo);
    }

    public String toString() {
      return "ClassLoadObject { cnt: " + cnt + ", curClass: " + curClass + "}";
    }
  }

  public static class FieldBasedTestObject extends AbstractTestObject implements Runnable {
    public int cnt;
    public int TARGET_FIELD;
    public FieldBasedTestObject() {
      super();
      cnt = 0;
      TARGET_FIELD = 0;
    }

    public void calledFunction() {
      cnt++;
      // We put a watchpoint here and PopFrame when we are at it.
      TARGET_FIELD += 10;
      if (cnt == 1) { System.out.println("FAILED: No pop on first call!"); }
    }

    public String toString() {
      return "FieldBasedTestObject { cnt: " + cnt + ", TARGET_FIELD: " + TARGET_FIELD + " }";
    }
  }

  public static class StandardTestObject extends AbstractTestObject implements Runnable {
    public int cnt;
    public final boolean check;

    public StandardTestObject(boolean check) {
      super();
      cnt = 0;
      this.check = check;
    }

    public StandardTestObject() {
      this(true);
    }

    public void calledFunction() {
      cnt++;       // line +0
      // We put a breakpoint here and PopFrame when we are at it.
      doNothing(); // line +2
      if (check && cnt == 1) { System.out.println("FAILED: No pop on first call!"); }
    }

    public String toString() {
      return "StandardTestObject { cnt: " + cnt + " }";
    }
  }

  public static class SynchronizedFunctionTestObject extends AbstractTestObject implements Runnable {
    public int cnt;

    public SynchronizedFunctionTestObject() {
      super();
      cnt = 0;
    }

    public synchronized void calledFunction() {
      cnt++;               // line +0
      // We put a breakpoint here and PopFrame when we are at it.
      doNothing();         // line +2
    }

    public String toString() {
      return "SynchronizedFunctionTestObject { cnt: " + cnt + " }";
    }
  }
  public static class SynchronizedTestObject extends AbstractTestObject implements Runnable {
    public int cnt;
    public final Object lock;

    public SynchronizedTestObject() {
      this(new Object());
    }

    public SynchronizedTestObject(Object l) {
      super();
      cnt = 0;
      lock = l;
    }

    public void calledFunction() {
      synchronized (lock) {  // line +0
        cnt++;               // line +1
        // We put a breakpoint here and PopFrame when we are at it.
        doNothing();         // line +3
      }
    }

    public String toString() {
      return "SynchronizedTestObject { cnt: " + cnt + " }";
    }
  }

  public static class ExceptionCatchTestObject extends AbstractTestObject implements Runnable {
    public static class TestError extends Error {}

    public int cnt;
    public ExceptionCatchTestObject() {
      super();
      cnt = 0;
    }

    public void calledFunction() {
      cnt++;
      try {
        doThrow();
      } catch (TestError e) {
        System.out.println(e.getClass().getName() + " caught in called function.");
      }
    }

    public void doThrow() {
      throw new TestError();
    }

    public String toString() {
      return "ExceptionCatchTestObject { cnt: " + cnt + " }";
    }
  }

  public static class ExceptionThrowFarTestObject implements TestRunnable {
    public static class TestError extends Error {}

    public int cnt;
    public int baseCallCnt;
    public final boolean catchInCalled;
    public ExceptionThrowFarTestObject(boolean catchInCalled) {
      super();
      cnt = 0;
      baseCallCnt = 0;
      this.catchInCalled = catchInCalled;
    }

    public int getBaseCallCount() {
      return baseCallCnt;
    }

    public void run() {
      baseCallCnt++;
      try {
        callingFunction();
      } catch (TestError e) {
        System.out.println(e.getClass().getName() + " thrown and caught!");
      }
    }

    public void callingFunction() {
      calledFunction();
    }
    public void calledFunction() {
      cnt++;
      if (catchInCalled) {
        try {
          throw new TestError(); // We put a watch here.
        } catch (TestError e) {
          System.out.println(e.getClass().getName() + " caught in same function.");
        }
      } else {
        throw new TestError(); // We put a watch here.
      }
    }

    public Method getCallingMethod() throws Exception {
      return this.getClass().getMethod("callingFunction");
    }

    public Method getCalledMethod() throws Exception {
      return this.getClass().getMethod("calledFunction");
    }

    public String toString() {
      return "ExceptionThrowFarTestObject { cnt: " + cnt + " }";
    }
  }

  public static class ExceptionOnceObject extends AbstractTestObject {
    public static final class TestError extends Error {}
    public int cnt;
    public final boolean throwInSub;
    public ExceptionOnceObject(boolean throwInSub) {
      super();
      cnt = 0;
      this.throwInSub = throwInSub;
    }

    public void calledFunction() {
      cnt++;
      if (cnt == 1) {
        if (throwInSub) {
          doThrow();
        } else {
          throw new TestError();
        }
      }
    }

    public void doThrow() {
      throw new TestError();
    }

    public String toString() {
      return "ExceptionOnceObject { cnt: " + cnt + ", throwInSub: " + throwInSub + " }";
    }
  }

  public static class ExceptionThrowTestObject implements TestRunnable {
    public static class TestError extends Error {}

    public int cnt;
    public int baseCallCnt;
    public final boolean catchInCalled;
    public ExceptionThrowTestObject(boolean catchInCalled) {
      super();
      cnt = 0;
      baseCallCnt = 0;
      this.catchInCalled = catchInCalled;
    }

    public int getBaseCallCount() {
      return baseCallCnt;
    }

    public void run() {
      baseCallCnt++;
      try {
        calledFunction();
      } catch (TestError e) {
        System.out.println(e.getClass().getName() + " thrown and caught!");
      }
    }

    public void calledFunction() {
      cnt++;
      if (catchInCalled) {
        try {
          throw new TestError(); // We put a watch here.
        } catch (TestError e) {
          System.out.println(e.getClass().getName() + " caught in same function.");
        }
      } else {
        throw new TestError(); // We put a watch here.
      }
    }

    public Method getCalledMethod() throws Exception {
      return this.getClass().getMethod("calledFunction");
    }

    public String toString() {
      return "ExceptionThrowTestObject { cnt: " + cnt + " }";
    }
  }

  public static class NativeCalledObject extends AbstractTestObject {
    public int cnt = 0;

    public native void calledFunction();

    public String toString() {
      return "NativeCalledObject { cnt: " + cnt + " }";
    }
  }

  public static class NativeCallerObject implements TestRunnable {
    public int baseCnt = 0;
    public int cnt = 0;

    public int getBaseCallCount() {
      return baseCnt;
    }

    public native void run();

    public void calledFunction() {
      cnt++;
      // We will stop using a MethodExit event.
    }

    public Method getCalledMethod() throws Exception {
      return this.getClass().getMethod("calledFunction");
    }

    public String toString() {
      return "NativeCallerObject { cnt: " + cnt + " }";
    }
  }
  public static class SuspendSuddenlyObject extends AbstractTestObject {
    public volatile boolean stop_spinning = false;
    public volatile boolean is_spinning = false;
    public int cnt = 0;

    public void calledFunction() {
      cnt++;
      while (!stop_spinning) {
        is_spinning = true;
      }
    }

    public String toString() {
      return "SuspendSuddenlyObject { cnt: " + cnt + " }";
    }
  }

  public static void run(boolean canRunClassLoadTests) throws Exception {
    new Test1953(canRunClassLoadTests, (x)-> {}).runTests();
  }

  // This entrypoint is used by CTS only. */
  public static void run() throws Exception {
    /* TODO: Due to the way that CTS tests are verified we cannot run class-load-tests since the
     *       verifier will be delayed until runtime and then load the classes all at once. This
     *       makes the test impossible to run.
     */
    run(/*canRunClassLoadTests*/ false);
  }

  public Test1953(boolean canRunClassLoadTests, Consumer<TestRunnable> preTest) {
    this.canRunClassLoadTests = canRunClassLoadTests;
    this.preTest = preTest;
  }

  private Consumer<TestRunnable> preTest;

  public void runTests() throws Exception {
    setupTest();

    final Method calledFunction = StandardTestObject.class.getDeclaredMethod("calledFunction");
    final Method doNothingMethod = Test1953.class.getDeclaredMethod("doNothing");
    // Add a breakpoint on the second line after the start of the function
    final int line = Breakpoint.locationToLine(calledFunction, 0) + 2;
    final long loc = Breakpoint.lineToLocation(calledFunction, line);
    System.out.println("Test stopped using breakpoint");
    runTestOn(new StandardTestObject(),
        (thr) -> setupSuspendBreakpointFor(calledFunction, loc, thr),
        SuspendEvents::clearSuspendBreakpointFor);

    final Method syncFunctionCalledFunction =
        SynchronizedFunctionTestObject.class.getDeclaredMethod("calledFunction");
    // Add a breakpoint on the second line after the start of the function
    // Annoyingly r8 generally has the first instruction (a monitor enter) not be marked as being
    // on any line but javac has it marked as being on the first line of the function. Just use the
    // second entry on the line-number table to get the breakpoint. This should be good for both.
    final long syncFunctionLoc =
        Breakpoint.getLineNumberTable(syncFunctionCalledFunction)[1].location;
    System.out.println("Test stopped using breakpoint with declared synchronized function");
    runTestOn(new SynchronizedFunctionTestObject(),
        (thr) -> setupSuspendBreakpointFor(syncFunctionCalledFunction, syncFunctionLoc, thr),
        SuspendEvents::clearSuspendBreakpointFor);

    final Method syncCalledFunction =
        SynchronizedTestObject.class.getDeclaredMethod("calledFunction");
    // Add a breakpoint on the second line after the start of the function
    final int syncLine = Breakpoint.locationToLine(syncCalledFunction, 0) + 3;
    final long syncLoc = Breakpoint.lineToLocation(syncCalledFunction, syncLine);
    System.out.println("Test stopped using breakpoint with synchronized block");
    Object lock = new Object();
    synchronized (lock) {}
    runTestOn(new SynchronizedTestObject(lock),
        (thr) -> setupSuspendBreakpointFor(syncCalledFunction, syncLoc, thr),
        SuspendEvents::clearSuspendBreakpointFor);
    synchronized (lock) {}

    System.out.println("Test stopped on single step");
    runTestOn(new StandardTestObject(),
        (thr) -> setupSuspendSingleStepAt(calledFunction, loc, thr),
        SuspendEvents::clearSuspendSingleStepFor);

    final Field target_field = FieldBasedTestObject.class.getDeclaredField("TARGET_FIELD");
    System.out.println("Test stopped on field access");
    runTestOn(new FieldBasedTestObject(),
        (thr) -> setupFieldSuspendFor(FieldBasedTestObject.class, target_field, true, thr),
        SuspendEvents::clearFieldSuspendFor);

    System.out.println("Test stopped on field modification");
    runTestOn(new FieldBasedTestObject(),
        (thr) -> setupFieldSuspendFor(FieldBasedTestObject.class, target_field, false, thr),
        SuspendEvents::clearFieldSuspendFor);

    System.out.println("Test stopped during Method Exit of doNothing");
    runTestOn(new StandardTestObject(false),
        (thr) -> setupSuspendMethodEvent(doNothingMethod, /*enter*/ false, thr),
        SuspendEvents::clearSuspendMethodEvent);

    // NB We need another test to make sure the MethodEntered event is triggered twice.
    System.out.println("Test stopped during Method Enter of doNothing");
    runTestOn(new StandardTestObject(false),
        (thr) -> setupSuspendMethodEvent(doNothingMethod, /*enter*/ true, thr),
        SuspendEvents::clearSuspendMethodEvent);

    System.out.println("Test stopped during Method Exit of calledFunction");
    runTestOn(new StandardTestObject(false),
        (thr) -> setupSuspendMethodEvent(calledFunction, /*enter*/ false, thr),
        SuspendEvents::clearSuspendMethodEvent);

    System.out.println("Test stopped during Method Enter of calledFunction");
    runTestOn(new StandardTestObject(false),
        (thr) -> setupSuspendMethodEvent(calledFunction, /*enter*/ true, thr),
        SuspendEvents::clearSuspendMethodEvent);

    final Method exceptionOnceCalledMethod =
        ExceptionOnceObject.class.getDeclaredMethod("calledFunction");
    System.out.println("Test stopped during Method Exit due to exception thrown in same function");
    runTestOn(new ExceptionOnceObject(/*throwInSub*/ false),
        (thr) -> setupSuspendMethodEvent(exceptionOnceCalledMethod, /*enter*/ false, thr),
        SuspendEvents::clearSuspendMethodEvent);

    System.out.println("Test stopped during Method Exit due to exception thrown in subroutine");
    runTestOn(new ExceptionOnceObject(/*throwInSub*/ true),
        (thr) -> setupSuspendMethodEvent(exceptionOnceCalledMethod, /*enter*/ false, thr),
        SuspendEvents::clearSuspendMethodEvent);

    final Method exceptionThrowCalledMethod =
        ExceptionThrowTestObject.class.getDeclaredMethod("calledFunction");
    final Method exceptionCatchThrowMethod =
        ExceptionCatchTestObject.class.getDeclaredMethod("doThrow");
    // Disable more often then we technically need to in order to avoid the need
    // for a huge number of possible results and allow the test to be easily
    // used in CTS.
    if (IS_ART && canRunClassLoadTests && CanRunClassLoadingTests()) {
      System.out.println("Test stopped during notifyFramePop without exception on pop of calledFunction");
      runTestOn(new StandardTestObject(false),
          (thr) -> setupSuspendPopFrameEvent(1, doNothingMethod, thr),
          SuspendEvents::clearSuspendPopFrameEvent);

      System.out.println("Test stopped during notifyFramePop without exception on pop of doNothing");
      runTestOn(new StandardTestObject(false),
          (thr) -> setupSuspendPopFrameEvent(0, doNothingMethod, thr),
          SuspendEvents::clearSuspendPopFrameEvent);

      System.out.println("Test stopped during notifyFramePop with exception on pop of calledFunction");
      runTestOn(new ExceptionThrowTestObject(false),
          (thr) -> setupSuspendPopFrameEvent(0, exceptionThrowCalledMethod, thr),
          SuspendEvents::clearSuspendPopFrameEvent);

      System.out.println("Test stopped during notifyFramePop with exception on pop of doThrow");
      runTestOn(new ExceptionCatchTestObject(),
          (thr) -> setupSuspendPopFrameEvent(0, exceptionCatchThrowMethod, thr),
          SuspendEvents::clearSuspendPopFrameEvent);
    }

    System.out.println("Test stopped during ExceptionCatch event of calledFunction " +
        "(catch in called function, throw in called function)");
    runTestOn(new ExceptionThrowTestObject(true),
        (thr) -> setupSuspendExceptionEvent(exceptionThrowCalledMethod, /*catch*/ true, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    final Method exceptionCatchCalledMethod =
        ExceptionCatchTestObject.class.getDeclaredMethod("calledFunction");
    System.out.println("Test stopped during ExceptionCatch event of calledFunction " +
        "(catch in called function, throw in subroutine)");
    runTestOn(new ExceptionCatchTestObject(),
        (thr) -> setupSuspendExceptionEvent(exceptionCatchCalledMethod, /*catch*/ true, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    System.out.println("Test stopped during Exception event of calledFunction " +
        "(catch in calling function)");
    runTestOn(new ExceptionThrowTestObject(false),
        (thr) -> setupSuspendExceptionEvent(exceptionThrowCalledMethod, /*catch*/ false, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    System.out.println("Test stopped during Exception event of calledFunction " +
        "(catch in called function)");
    runTestOn(new ExceptionThrowTestObject(true),
        (thr) -> setupSuspendExceptionEvent(exceptionThrowCalledMethod, /*catch*/ false, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    final Method exceptionThrowFarCalledMethod =
        ExceptionThrowFarTestObject.class.getDeclaredMethod("calledFunction");
    System.out.println("Test stopped during Exception event of calledFunction " +
        "(catch in parent of calling function)");
    runTestOn(new ExceptionThrowFarTestObject(false),
        (thr) -> setupSuspendExceptionEvent(exceptionThrowFarCalledMethod, /*catch*/ false, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    System.out.println("Test stopped during Exception event of calledFunction " +
        "(catch in called function)");
    runTestOn(new ExceptionThrowFarTestObject(true),
        (thr) -> setupSuspendExceptionEvent(exceptionThrowFarCalledMethod, /*catch*/ false, thr),
        SuspendEvents::clearSuspendExceptionEvent);

    // These tests are disabled for either the RI (b/116003018) or for jvmti-stress. For the
    // later it is due to the additional agent causing classes to be loaded earlier as it forces
    // deeper verification during class redefinition, causing failures.
    // NB the agent is prevented from popping frames in either of these events in ART. See
    // b/117615146 for more information about this restriction.
    if (canRunClassLoadTests && CanRunClassLoadingTests()) {
      // This test doesn't work on RI since the RI disallows use of PopFrame during a ClassLoad
      // event. See b/116003018 for more information.
      System.out.println("Test stopped during a ClassLoad event.");
      runTestOn(new ClassLoadObject(),
          (thr) -> setupSuspendClassEvent(EVENT_TYPE_CLASS_LOAD, ClassLoadObject.CLASS_NAMES, thr),
          SuspendEvents::clearSuspendClassEvent);

      // The RI handles a PopFrame during a ClassPrepare event incorrectly. See b/116003018 for
      // more information.
      System.out.println("Test stopped during a ClassPrepare event.");
      runTestOn(new ClassLoadObject(),
          (thr) -> setupSuspendClassEvent(EVENT_TYPE_CLASS_PREPARE,
                                          ClassLoadObject.CLASS_NAMES,
                                          thr),
          SuspendEvents::clearSuspendClassEvent);
    }
    System.out.println("Test stopped during random Suspend.");
    final SuspendSuddenlyObject sso = new SuspendSuddenlyObject();
    runTestOn(
        sso,
        new TestSuspender() {
          public void setup(Thread thr) { }
          public void waitForSuspend(Thread thr) {
            while (!sso.is_spinning) {}
            Suspension.suspend(thr);
          }
          public void cleanup(Thread thr) {
            sso.stop_spinning = true;
          }
        });

    final Method redefineCalledFunction =
       RedefineTestObject.class.getDeclaredMethod("calledFunction");
    final int redefLine = Breakpoint.locationToLine(redefineCalledFunction, 0) + 2;
    final long redefLoc = Breakpoint.lineToLocation(redefineCalledFunction, redefLine);
    System.out.println("Test redefining frame being popped.");
    runTestOn(new RedefineTestObject(),
        (thr) -> setupSuspendBreakpointFor(redefineCalledFunction, redefLoc, thr),
        (thr) -> {
          clearSuspendBreakpointFor(thr);
          Redefinition.doCommonClassRedefinition(RedefineTestObject.class,
                                                 RedefineTestObject.CLASS_BYTES,
                                                 RedefineTestObject.DEX_BYTES);
        });

    System.out.println("Test stopped during a native method fails");
    runTestOn(new NativeCalledObject(),
        SuspendEvents::setupWaitForNativeCall,
        SuspendEvents::clearWaitForNativeCall);

    System.out.println("Test stopped in a method called by native fails");
    final Method nativeCallerMethod = NativeCallerObject.class.getDeclaredMethod("calledFunction");
    runTestOn(new NativeCallerObject(),
        (thr) -> setupSuspendMethodEvent(nativeCallerMethod, /*enter*/ false, thr),
        SuspendEvents::clearSuspendMethodEvent);


    final Object lock2 = new Object();
    synchronized (lock2) {}
    System.out.println("Test stopped with monitor in enclosing frame.");
    runTestOn(new StandardTestObject() {
          @Override
          public void run() {
            synchronized (lock2) {
              super.run();
            }
          }
        },
        (thr) -> setupSuspendBreakpointFor(calledFunction, loc, thr),
        SuspendEvents::clearSuspendBreakpointFor);
    synchronized (lock2) {}
  }

  // Volatile is to prevent any future optimizations that could invalidate this test by doing
  // constant propagation and eliminating the failing paths before the verifier is able to load the
  // class.
  static volatile boolean ranClassLoadTest = false;
  static boolean classesPreverified = false;
  private static final class RCLT0 { public void foo() {} }
  private static final class RCLT1 { public void foo() {} }
  // If classes are not preverified for some reason (interp-ac, no-image, etc) the verifier will
  // actually load classes as it runs. This means that we cannot use the class-load tests as they
  // are written. TODO Support this.
  public boolean CanRunClassLoadingTests() {
    if (ranClassLoadTest) {
      return classesPreverified;
    }
    if (!ranClassLoadTest) {
      // Only this will ever be executed.
      new RCLT0().foo();
    } else {
      // This will never be executed. If classes are not preverified the verifier will load RCLT1
      // when the enclosing method is run. This behavior makes the class-load/prepare test cases
      // impossible to successfully run (they will deadlock).
      new RCLT1().foo();
      System.out.println("FAILURE: UNREACHABLE Location!");
    }
    classesPreverified = !isClassLoaded("Lart/Test1953$RCLT1;");
    ranClassLoadTest = true;
    return classesPreverified;
  }

  public static native boolean isClassLoaded(String name);
  public static native void popFrame(Thread thr);
}
