Make heap exhaustion more robust in art-tests

Repeat heap exhaustion loop a couple of times to make sure there is no
space left on the Java heap. This is essential as we now report OOME
even when 1% of the heap is available for allocation. Repetition ensures
that even the 1% available heap is also consumed.

Test: art/test/testrunner/testrunner.py
Bug: 144525957
Change-Id: Iec5e6ae59c95f7ae5e8c13dc47bcc43a76795447
diff --git a/test/044-proxy/src/OOMEOnDispatch.java b/test/044-proxy/src/OOMEOnDispatch.java
index b6fb3e8..0f58bc4 100644
--- a/test/044-proxy/src/OOMEOnDispatch.java
+++ b/test/044-proxy/src/OOMEOnDispatch.java
@@ -26,6 +26,16 @@
 
     static ArrayList<Object> storage = new ArrayList<>(100000);
 
+    private static void exhaustJavaHeap(int size) {
+      while (size > 8) {
+        try {
+          storage.add(new byte[size]);
+        } catch (OutOfMemoryError e) {
+          size = size/2;
+        }
+      }
+    }
+
     public static void main(String[] args) {
         InvocationHandler handler = new OOMEOnDispatch();
         OOMEInterface inf = (OOMEInterface)Proxy.newProxyInstance(
@@ -43,14 +53,11 @@
         System.runFinalization();
         Runtime.getRuntime().gc();
 
-        int l = 1024 * 1024;
-        while (l > 8) {
-          try {
-            storage.add(new byte[l]);
-          } catch (OutOfMemoryError e) {
-            l = l/2;
-          }
-        }
+        int initial_size = 1024 * 1024;
+        // Repeat to ensure there is no space left on the heap.
+        exhaustJavaHeap(initial_size);
+        exhaustJavaHeap(/*size*/ 8);
+        exhaustJavaHeap(/*size*/ 8);
 
         try {
             inf.foo();
diff --git a/test/064-field-access/src/OOMEOnNullAccess.java b/test/064-field-access/src/OOMEOnNullAccess.java
index 9960241..b464170 100644
--- a/test/064-field-access/src/OOMEOnNullAccess.java
+++ b/test/064-field-access/src/OOMEOnNullAccess.java
@@ -36,6 +36,16 @@
 
     static ArrayList<Object> storage = new ArrayList<>(100000);
 
+    private static void exhaustJavaHeap(int size) {
+      while (size > 8) {
+        try {
+          storage.add(new byte[size]);
+        } catch (OutOfMemoryError e) {
+          size = size/2;
+        }
+      }
+    }
+
     public static void main(String[] args) {
         // Stop the JIT to be sure nothing is running that could be resolving classes or causing
         // verification.
@@ -48,14 +58,12 @@
         System.runFinalization();
         Runtime.getRuntime().gc();
 
-        int l = 1024 * 1024;
-        while (l > 8) {
-          try {
-            storage.add(new byte[l]);
-          } catch (OutOfMemoryError e) {
-            l = l/2;
-          }
-        }
+        int initial_size = 1024 * 1024;
+        // Repeat to ensure there is no space left on the heap.
+        exhaustJavaHeap(initial_size);
+        exhaustJavaHeap(/*size*/ 8);
+        exhaustJavaHeap(/*size*/ 8);
+
 
         try {
             nullAccess(null);
diff --git a/test/080-oom-throw/src/Main.java b/test/080-oom-throw/src/Main.java
index 4750119..a579c21 100644
--- a/test/080-oom-throw/src/Main.java
+++ b/test/080-oom-throw/src/Main.java
@@ -53,6 +53,18 @@
         }
     }
 
+    private static int exhaustJavaHeap(Object[] data, int index, int size) {
+        while (index != data.length && size != 0) {
+            try {
+                data[index] = new byte[size];
+                ++index;
+            } catch (OutOfMemoryError oome) {
+                size /= 2;
+            }
+        }
+        return index;
+    }
+
     public static Object eatAllMemory() {
         Object[] result = null;
         int size = 1000000;
@@ -70,14 +82,10 @@
         }
         if (result != null) {
             int index = 0;
-            while (index != result.length && size != 0) {
-                try {
-                    result[index] = new byte[size];
-                    ++index;
-                } catch (OutOfMemoryError oome) {
-                    size /= 2;
-                }
-            }
+            // Repeat to ensure there is no space left on the heap.
+            index = exhaustJavaHeap(result, index, size);
+            index = exhaustJavaHeap(result, index, /*size*/ 8);
+            index = exhaustJavaHeap(result, index, /*size*/ 8);
         }
         return result;
     }
diff --git a/test/617-clinit-oome/src/Main.java b/test/617-clinit-oome/src/Main.java
index bee6e01..eeeea5e 100644
--- a/test/617-clinit-oome/src/Main.java
+++ b/test/617-clinit-oome/src/Main.java
@@ -15,6 +15,21 @@
  */
 
 public class Main {
+  private static int exhaustJavaHeap(Object[] data, int index, int size) {
+    while (true) {
+        try {
+            data[index] = new byte[size];
+            index++;
+        } catch (OutOfMemoryError e) {
+            size /= 2;
+            if (size == 0) {
+                break;
+            }
+        }
+    }
+    return index;
+  }
+
   public static void main(String[] args) {
     Class klass = Other.class;
     Object[] data = new Object[100000];
@@ -27,19 +42,13 @@
         System.runFinalization();
         Runtime.getRuntime().gc();
 
-        int size = 256 * 1024 * 1024;
         int index = 0;
-        while (true) {
-            try {
-                data[index] = new byte[size];
-                index++;
-            } catch (OutOfMemoryError e) {
-                size /= 2;
-                if (size == 0) {
-                    break;
-                }
-            }
-        }
+        int initial_size = 256 * 1024 * 1024;
+        // Repeat to ensure there is no space left on the heap.
+        index = exhaustJavaHeap(data, index, initial_size);
+        index = exhaustJavaHeap(data, index, /*size*/ 8);
+        index = exhaustJavaHeap(data, index, /*size*/ 8);
+
         // Initialize now that the heap is full.
         Other.print();
     } catch (OutOfMemoryError e) {