From 35fd969d663f8f89ecdbdb14e52e4f03e37d3f86 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Wed, 2 Mar 2016 12:52:37 -0800 Subject: [PATCH] Delete alloc tracking map outside of critical section There can be lock order violations otherwise due to runtime shutdown lock that may get acquired in the condition variable destructor. Bug: 27506909 (cherry picked from commit 0b8b4a609120b90081d898dbf3c26f68fe80de96) Change-Id: I6972c450db8856e30c13e27aea94b01943618f64 --- runtime/gc/allocation_record.cc | 5 ++++- runtime/gc/heap.cc | 4 ++++ runtime/gc/heap.h | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/runtime/gc/allocation_record.cc b/runtime/gc/allocation_record.cc index 4de5388d8..467248330 100644 --- a/runtime/gc/allocation_record.cc +++ b/runtime/gc/allocation_record.cc @@ -245,6 +245,9 @@ void AllocRecordObjectMap::SetAllocTrackingEnabled(bool enable) { heap->SetAllocTrackingEnabled(true); } } else { + // Delete outside of the critical section to avoid possible lock violations like the runtime + // shutdown lock. + std::unique_ptr map; { MutexLock mu(self, *Locks::alloc_tracker_lock_); if (!heap->IsAllocTrackingEnabled()) { @@ -252,7 +255,7 @@ void AllocRecordObjectMap::SetAllocTrackingEnabled(bool enable) { } heap->SetAllocTrackingEnabled(false); LOG(INFO) << "Disabling alloc tracker"; - heap->SetAllocationRecords(nullptr); + map = heap->ReleaseAllocationRecords(); } // If an allocation comes in before we uninstrument, we will safely drop it on the floor. Runtime::Current()->GetInstrumentation()->UninstrumentQuickAllocEntryPoints(); diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 836bbf40a..7e242d5bb 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -3932,6 +3932,10 @@ void Heap::SetAllocationRecords(AllocRecordObjectMap* records) { allocation_records_.reset(records); } +std::unique_ptr Heap::ReleaseAllocationRecords() { + return std::move(allocation_records_); +} + void Heap::VisitAllocationRecords(RootVisitor* visitor) const { if (IsAllocTrackingEnabled()) { MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_); diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 9e1a4077c..37aa82d68 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -763,6 +763,10 @@ class Heap { return allocation_records_.get(); } + // Release ownership of the allocation records. + std::unique_ptr ReleaseAllocationRecords() + REQUIRES(Locks::alloc_tracker_lock_); + void SetAllocationRecords(AllocRecordObjectMap* records) REQUIRES(Locks::alloc_tracker_lock_); -- 2.11.0