From ddac42329314587f6f188bacf101b3cb15175b3c Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Thu, 2 Apr 2015 10:08:03 -0700 Subject: [PATCH] Fix race with Heap::ClampGrowthLimit and GC Aded logic for handling the temp bitmap if the GC is running and the live bitmap is clamped to the mark bitmap. This fixes the SIGABRT from ClampGrowthLimit if the GC clamped the bitmaps at this point. Also added locking of the heap_bitmap_lock_ so that added a lock so that the temp bitmap doesn't change from underneath us. Bug: 20043461 Change-Id: Ib427e40bcdf149de0408b4b53e6524f51463f0af --- runtime/gc/heap.cc | 2 ++ runtime/gc/heap.h | 2 +- runtime/gc/space/malloc_space.cc | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 7e967f986..be7344a13 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -3145,6 +3145,8 @@ void Heap::GrowForUtilization(collector::GarbageCollector* collector_ran, } void Heap::ClampGrowthLimit() { + // Use heap bitmap lock to guard against races with BindLiveToMarkBitmap. + WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_); capacity_ = growth_limit_; for (const auto& space : continuous_spaces_) { if (space->IsMallocSpace()) { diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 959ff1851..603cbfd42 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -309,7 +309,7 @@ class Heap { // Make the current growth limit the new maximum capacity, unmaps pages at the end of spaces // which will never be used. Used to implement dalvik.system.VMRuntime.clampGrowthLimit. - void ClampGrowthLimit(); + void ClampGrowthLimit() LOCKS_EXCLUDED(Locks::heap_bitmap_lock_); // Target ideal heap utilization ratio, implements // dalvik.system.VMRuntime.getTargetHeapUtilization. diff --git a/runtime/gc/space/malloc_space.cc b/runtime/gc/space/malloc_space.cc index 67e8847ac..b09de6fa4 100644 --- a/runtime/gc/space/malloc_space.cc +++ b/runtime/gc/space/malloc_space.cc @@ -253,6 +253,10 @@ void MallocSpace::ClampGrowthLimit() { CHECK_LE(new_capacity, NonGrowthLimitCapacity()); GetLiveBitmap()->SetHeapSize(new_capacity); GetMarkBitmap()->SetHeapSize(new_capacity); + if (temp_bitmap_.get() != nullptr) { + // If the bitmaps are clamped, then the temp bitmap is actually the mark bitmap. + temp_bitmap_->SetHeapSize(new_capacity); + } GetMemMap()->SetSize(new_capacity); limit_ = Begin() + new_capacity; CHECK(temp_bitmap_.get() == nullptr); -- 2.11.0