Redesign implementation of RegisterNativeAllocation.

Improve the performance and remove the issue with GCing apps to death when
they reach the growth_limit_.

This implements the REDESIGN approach described in detail in the
document at go/understanding-register-native-allocation.

Bug: 29156652
Bug: 32576211
Test: m test-art-host
Test: vogar libcore/luni/src/test/java/libcore/util/NativeAllocationRegistryTest.java
Test: Device boots.
Test: adb bugreport and look for "Registered native bytes allocated"

Change-Id: I09176b2b0e4f0c401fe1947830fa5271060f4e61
diff --git a/test/004-NativeAllocations/src/Main.java b/test/004-NativeAllocations/src/Main.java
index 92f4e21..8712755 100644
--- a/test/004-NativeAllocations/src/Main.java
+++ b/test/004-NativeAllocations/src/Main.java
@@ -16,6 +16,7 @@
 
 import java.lang.reflect.*;
 import java.lang.Runtime;
+import dalvik.system.VMRuntime;
 
 public class Main {
     static Object nativeLock = new Object();
@@ -33,10 +34,19 @@
         NativeAllocation(int bytes, boolean testingDeadlock) throws Exception {
             this.bytes = bytes;
             register_native_allocation.invoke(runtime, bytes);
+
+            // Register native allocation can only provide guarantees bounding
+            // the maximum outstanding allocations if finalizers don't time
+            // out. In case finalizers have timed out, wait longer for them
+            // now to complete so we can test the guarantees.
+            if (!testingDeadlock) {
+              VMRuntime.runFinalization(0);
+            }
+
             synchronized (nativeLock) {
                 if (!testingDeadlock) {
                     nativeBytes += bytes;
-                    if (nativeBytes > maxMem) {
+                    if (nativeBytes > 2 * maxMem) {
                         throw new OutOfMemoryError();
                     }
                 }