Fix pending exception failure for encoded statics

ReadValueToField may allocate a string and cause OOME, we were
not checking this each loop iteration. Throwing an exception
with a pending exception causes an abort.

Bug: 30690988

Test: test-art-host

Change-Id: I2c9751bf0544cf115d9d8e914e58ebccc81bcbf4
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 46722ec..4d48da6 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4630,18 +4630,23 @@
         } else {
           value_it.ReadValueToField<false>(field);
         }
+        if (self->IsExceptionPending()) {
+          break;
+        }
         DCHECK(!value_it.HasNext() || field_it.HasNextStaticField());
       }
     }
   }
 
-  ArtMethod* clinit = klass->FindClassInitializer(image_pointer_size_);
-  if (clinit != nullptr) {
-    CHECK(can_init_statics);
-    JValue result;
-    clinit->Invoke(self, nullptr, 0, &result, "V");
-  }
 
+  if (!self->IsExceptionPending()) {
+    ArtMethod* clinit = klass->FindClassInitializer(image_pointer_size_);
+    if (clinit != nullptr) {
+      CHECK(can_init_statics);
+      JValue result;
+      clinit->Invoke(self, nullptr, 0, &result, "V");
+    }
+  }
   self->AllowThreadSuspension();
   uint64_t t1 = NanoTime();
 
diff --git a/test/617-clinit-oome/expected.txt b/test/617-clinit-oome/expected.txt
new file mode 100644
index 0000000..c1d33ff
--- /dev/null
+++ b/test/617-clinit-oome/expected.txt
@@ -0,0 +1 @@
+Filling heap
diff --git a/test/617-clinit-oome/info.txt b/test/617-clinit-oome/info.txt
new file mode 100644
index 0000000..ece35b2
--- /dev/null
+++ b/test/617-clinit-oome/info.txt
@@ -0,0 +1 @@
+Regression test for encoded static strings caussing OOME b/30690988
diff --git a/test/617-clinit-oome/src/Main.java b/test/617-clinit-oome/src/Main.java
new file mode 100644
index 0000000..749a232
--- /dev/null
+++ b/test/617-clinit-oome/src/Main.java
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+public class Main {
+  public static void main(String[] args) {
+    Class klass = Other.class;
+    Object[] data = new Object[100000];
+    try {
+        System.out.println("Filling heap");
+        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;
+                }
+            }
+        }
+        // Initialize now that the heap is full.
+        Other.print();
+    } catch (OutOfMemoryError e) {
+    } catch (Exception e) {
+        System.err.println(e);
+    }
+  }
+}
diff --git a/test/617-clinit-oome/src/Other.java b/test/617-clinit-oome/src/Other.java
new file mode 100644
index 0000000..20306ee
--- /dev/null
+++ b/test/617-clinit-oome/src/Other.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+public final class Other {
+    public static final String string1 = "ABCDEFG1";
+    public static final String string2 = "ABCDEFG2";
+    public static final String string3 = "ABCDEFG3";
+    public static final String string4 = "ABCDEFG4";
+    public static final String string5 = "ABCDEFG5";
+    public static final int int1 = 12;
+
+    public static void print() {
+        System.out.println(string2);
+    }
+}