Fix a test to avoid races when adding method entry records

Adding method entry records could lead to strange cases when more
methods are executed when adding a record to check for sufficient
capacity in the array list. As more methods are executed when checking
for available capacity we would end up using the available space.

Bug: 206029744
Test: art/testrunner.py -t 988
Change-Id: I9dde44094599f9042195b84327d679d614d75692
diff --git a/test/988-method-trace/expected-stdout.txt b/test/988-method-trace/expected-stdout.txt
index 59077b9..c5ab4ed 100644
--- a/test/988-method-trace/expected-stdout.txt
+++ b/test/988-method-trace/expected-stdout.txt
@@ -13,13 +13,19 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibResult(java.lang.String,int,int) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(30)=832040
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => art.Test988$RecurOp()
 .=> public java.lang.Object()
@@ -62,13 +68,19 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibResult(java.lang.String,int,int) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(5)=5
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => art.Test988$NativeOp()
 .=> public java.lang.Object()
@@ -83,13 +95,19 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibResult(java.lang.String,int,int) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(5)=5
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => art.Test988$IterOp()
 .=> public java.lang.Object()
@@ -170,10 +188,10 @@
 ......=> private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace()
 ......<= private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace() -> <class [Ljava.lang.Object;: <non-deterministic>>
 .....<= public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace() -> <class java.lang.Error: java.lang.Error: Bad argument: -19 < 0
-	art.Test988.iter_fibonacci(Test988.java:269)
-	art.Test988$IterOp.applyAsInt(Test988.java:264)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:358)
+	art.Test988.iter_fibonacci(Test988.java:280)
+	art.Test988$IterOp.applyAsInt(Test988.java:275)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:369)
 	<additional hidden frames>
 >
 ....<= public java.lang.Throwable(java.lang.String) -> <null: null>
@@ -184,19 +202,25 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibThrow(java.lang.String,int,java.lang.Throwable) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(-19) -> java.lang.Error: Bad argument: -19 < 0
-	art.Test988.iter_fibonacci(Test988.java:269)
-	art.Test988$IterOp.applyAsInt(Test988.java:264)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:358)
+	art.Test988.iter_fibonacci(Test988.java:280)
+	art.Test988$IterOp.applyAsInt(Test988.java:275)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:369)
 	<additional hidden frames>
 
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => art.Test988$RecurOp()
 .=> public java.lang.Object()
@@ -277,10 +301,10 @@
 ......=> private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace()
 ......<= private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace() -> <class [Ljava.lang.Object;: <non-deterministic>>
 .....<= public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace() -> <class java.lang.Error: java.lang.Error: Bad argument: -19 < 0
-	art.Test988.fibonacci(Test988.java:291)
-	art.Test988$RecurOp.applyAsInt(Test988.java:286)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:359)
+	art.Test988.fibonacci(Test988.java:302)
+	art.Test988$RecurOp.applyAsInt(Test988.java:297)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:370)
 	<additional hidden frames>
 >
 ....<= public java.lang.Throwable(java.lang.String) -> <null: null>
@@ -291,19 +315,25 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibThrow(java.lang.String,int,java.lang.Throwable) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(-19) -> java.lang.Error: Bad argument: -19 < 0
-	art.Test988.fibonacci(Test988.java:291)
-	art.Test988$RecurOp.applyAsInt(Test988.java:286)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:359)
+	art.Test988.fibonacci(Test988.java:302)
+	art.Test988$RecurOp.applyAsInt(Test988.java:297)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:370)
 	<additional hidden frames>
 
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => art.Test988$NativeOp()
 .=> public java.lang.Object()
@@ -323,9 +353,9 @@
 ......<= private static java.lang.Object java.lang.Throwable.nativeFillInStackTrace() -> <class [Ljava.lang.Object;: <non-deterministic>>
 .....<= public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace() -> <class java.lang.Error: java.lang.Error: bad argument
 	art.Test988.nativeFibonacci(Native Method)
-	art.Test988$NativeOp.applyAsInt(Test988.java:301)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:360)
+	art.Test988$NativeOp.applyAsInt(Test988.java:312)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:371)
 	<additional hidden frames>
 >
 ....<= public java.lang.Throwable(java.lang.String) -> <null: null>
@@ -336,19 +366,25 @@
 ..=> public java.lang.Object()
 ..<= public java.lang.Object() -> <null: null>
 .<= public art.Test988$FibThrow(java.lang.String,int,java.lang.Throwable) -> <null: null>
-.=> public boolean java.util.ArrayList.add(java.lang.Object)
-..=> private void java.util.ArrayList.ensureCapacityInternal(int)
+.=> static void art.Test988.addToResults(art.Test988$Printable)
+..=> public void java.util.ArrayList.ensureCapacity(int)
 ...=> private void java.util.ArrayList.ensureExplicitCapacity(int)
 ...<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
-..<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
+..<= public void java.util.ArrayList.ensureCapacity(int) -> <null: null>
+..=> public boolean java.util.ArrayList.add(java.lang.Object)
+...=> private void java.util.ArrayList.ensureCapacityInternal(int)
+....=> private void java.util.ArrayList.ensureExplicitCapacity(int)
+....<= private void java.util.ArrayList.ensureExplicitCapacity(int) -> <null: null>
+...<= private void java.util.ArrayList.ensureCapacityInternal(int) -> <null: null>
 fibonacci(-19) -> java.lang.Error: bad argument
 	art.Test988.nativeFibonacci(Native Method)
-	art.Test988$NativeOp.applyAsInt(Test988.java:301)
-	art.Test988.doFibTest(Test988.java:402)
-	art.Test988.run(Test988.java:360)
+	art.Test988$NativeOp.applyAsInt(Test988.java:312)
+	art.Test988.doFibTest(Test988.java:413)
+	art.Test988.run(Test988.java:371)
 	<additional hidden frames>
 
-.<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+..<= public boolean java.util.ArrayList.add(java.lang.Object) -> <class java.lang.Boolean: true>
+.<= static void art.Test988.addToResults(art.Test988$Printable) -> <null: null>
 <= public static void art.Test988.doFibTest(int,java.util.function.IntUnaryOperator) -> <null: null>
 => public final void <non-deterministic-type 0>.run()
 .=> private static java.lang.Object java.lang.reflect.Proxy.invoke(java.lang.reflect.Proxy,java.lang.reflect.Method,java.lang.Object[]) throws java.lang.Throwable
diff --git a/test/988-method-trace/src/art/Test988.java b/test/988-method-trace/src/art/Test988.java
index 9c8ce4a..227ce62 100644
--- a/test/988-method-trace/src/art/Test988.java
+++ b/test/988-method-trace/src/art/Test988.java
@@ -253,11 +253,22 @@
         }
     }
 
-    private static List<Printable> results = new ArrayList<>();
+    private static ArrayList<Printable> results = new ArrayList<>();
+    private static int results_index = 0;
     // Starts with => enableMethodTracing
     //             .=> enableTracing
     private static int cnt = 2;
 
+    static void addToResults(Printable obj) {
+      // Reserve space for the current object. If any other method entry callbacks are called they
+      // will reserve more space. Without this we may get into strange problems where ArrayList::add
+      // cecks there is enough space (which involves a couple of method calls) which then use up the
+      // space and by the time we actually add this record there is no capacity left.
+      results_index++;
+      results.ensureCapacity(results_index + 1);
+      results.add(obj);
+    }
+
     // Iterative version
     static final class IterOp implements IntUnaryOperator {
       public int applyAsInt(int x) {
@@ -319,7 +330,7 @@
         if ((cnt - 1) > METHOD_TRACING_IGNORE_DEPTH && sMethodTracingIgnore) {
           return;
         }
-        results.add(new MethodEntry(m, cnt - 1));
+        addToResults(new MethodEntry(m, cnt - 1));
     }
 
     public static void notifyMethodExit(Executable m, boolean exception, Object result) {
@@ -330,9 +341,9 @@
         }
 
         if (exception) {
-            results.add(new MethodThrownThrough(m, cnt));
+            addToResults(new MethodThrownThrough(m, cnt));
         } else {
-            results.add(new MethodReturn(m, result, cnt));
+            addToResults(new MethodReturn(m, result, cnt));
         }
     }
 
@@ -400,9 +411,9 @@
     public static void doFibTest(int x, IntUnaryOperator op) {
       try {
         int y = op.applyAsInt(x);
-        results.add(new FibResult("fibonacci(%d)=%d\n", x, y));
+        addToResults(new FibResult("fibonacci(%d)=%d\n", x, y));
       } catch (Throwable t) {
-        results.add(new FibThrow("fibonacci(%d) -> %s\n", x, t));
+        addToResults(new FibThrow("fibonacci(%d) -> %s\n", x, t));
       }
     }