OSDN Git Service

Fix native allocation watermark clamping.
authorMathieu Chartier <mathieuc@google.com>
Wed, 3 Sep 2014 17:30:11 +0000 (10:30 -0700)
committerMathieu Chartier <mathieuc@google.com>
Thu, 4 Sep 2014 04:35:32 +0000 (21:35 -0700)
The main issue causing the test to fail is that
native_footprint_gc_watermark_ becoming > growth_limit_ due to no
clamping.

Temporary runFinalization fix is calling runFinalization 2x.

Bug: 17371542

(cherry picked from commit 4c7fc5950853b0c368e2148db77ced7c4d3c303c)

Change-Id: I05b85e95560c32c33d53bc96abf87d5262007395

runtime/gc/heap.cc
runtime/gc/heap.h
runtime/native/dalvik_system_VMRuntime.cc

index 78ef7ac..5d0d8d2 100644 (file)
@@ -2829,7 +2829,7 @@ void Heap::UpdateMaxNativeFootprint() {
   } else if (target_size < native_size + min_free_) {
     target_size = native_size + min_free_;
   }
-  native_footprint_gc_watermark_ = target_size;
+  native_footprint_gc_watermark_ = std::min(growth_limit_, target_size);
 }
 
 collector::GarbageCollector* Heap::FindCollectorByGcType(collector::GcType gc_type) {
@@ -3083,9 +3083,11 @@ void Heap::RunFinalization(JNIEnv* env) {
   }
   env->CallStaticVoidMethod(WellKnownClasses::java_lang_System,
                             WellKnownClasses::java_lang_System_runFinalization);
+  env->CallStaticVoidMethod(WellKnownClasses::java_lang_System,
+                            WellKnownClasses::java_lang_System_runFinalization);
 }
 
-void Heap::RegisterNativeAllocation(JNIEnv* env, int bytes) {
+void Heap::RegisterNativeAllocation(JNIEnv* env, size_t bytes) {
   Thread* self = ThreadForEnv(env);
   if (native_need_to_run_finalization_) {
     RunFinalization(env);
@@ -3127,19 +3129,19 @@ void Heap::RegisterNativeAllocation(JNIEnv* env, int bytes) {
   }
 }
 
-void Heap::RegisterNativeFree(JNIEnv* env, int bytes) {
-  int expected_size, new_size;
+void Heap::RegisterNativeFree(JNIEnv* env, size_t bytes) {
+  size_t expected_size;
   do {
     expected_size = native_bytes_allocated_.LoadRelaxed();
-    new_size = expected_size - bytes;
-    if (UNLIKELY(new_size < 0)) {
+    if (UNLIKELY(bytes > expected_size)) {
       ScopedObjectAccess soa(env);
       env->ThrowNew(WellKnownClasses::java_lang_RuntimeException,
-                    StringPrintf("Attempted to free %d native bytes with only %d native bytes "
+                    StringPrintf("Attempted to free %zd native bytes with only %zd native bytes "
                                  "registered as allocated", bytes, expected_size).c_str());
       break;
     }
-  } while (!native_bytes_allocated_.CompareExchangeWeakRelaxed(expected_size, new_size));
+  } while (!native_bytes_allocated_.CompareExchangeWeakRelaxed(expected_size,
+                                                               expected_size - bytes));
 }
 
 size_t Heap::GetTotalMemory() const {
index a230f44..9742277 100644 (file)
@@ -212,8 +212,8 @@ class Heap {
   void CheckPreconditionsForAllocObject(mirror::Class* c, size_t byte_count)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void RegisterNativeAllocation(JNIEnv* env, int bytes);
-  void RegisterNativeFree(JNIEnv* env, int bytes);
+  void RegisterNativeAllocation(JNIEnv* env, size_t bytes);
+  void RegisterNativeFree(JNIEnv* env, size_t bytes);
 
   // Change the allocator, updates entrypoints.
   void ChangeAllocator(AllocatorType allocator)
index a9ef8fc..db0a5c5 100644 (file)
@@ -184,7 +184,7 @@ static void VMRuntime_registerNativeAllocation(JNIEnv* env, jobject, jint bytes)
     ThrowRuntimeException("allocation size negative %d", bytes);
     return;
   }
-  Runtime::Current()->GetHeap()->RegisterNativeAllocation(env, bytes);
+  Runtime::Current()->GetHeap()->RegisterNativeAllocation(env, static_cast<size_t>(bytes));
 }
 
 static void VMRuntime_registerNativeFree(JNIEnv* env, jobject, jint bytes) {
@@ -193,7 +193,7 @@ static void VMRuntime_registerNativeFree(JNIEnv* env, jobject, jint bytes) {
     ThrowRuntimeException("allocation size negative %d", bytes);
     return;
   }
-  Runtime::Current()->GetHeap()->RegisterNativeFree(env, bytes);
+  Runtime::Current()->GetHeap()->RegisterNativeFree(env, static_cast<size_t>(bytes));
 }
 
 static void VMRuntime_updateProcessState(JNIEnv* env, jobject, jint process_state) {