OSDN Git Service

Delete alloc tracking map outside of critical section
authorMathieu Chartier <mathieuc@google.com>
Wed, 2 Mar 2016 20:52:37 +0000 (12:52 -0800)
committerMathieu Chartier <mathieuc@google.com>
Wed, 2 Mar 2016 21:53:16 +0000 (13:53 -0800)
There can be lock order violations otherwise due to runtime shutdown
lock that may get acquired in the condition variable destructor.

Change-Id: I23cb2dfe241f5cc6c42bf6766e89042cf06069b6

runtime/gc/allocation_record.cc
runtime/gc/heap.cc
runtime/gc/heap.h

index 4de5388..4672483 100644 (file)
@@ -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<AllocRecordObjectMap> 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();
index 1b4cbec..bebff0f 100644 (file)
@@ -3947,6 +3947,10 @@ void Heap::SetAllocationRecords(AllocRecordObjectMap* records) {
   allocation_records_.reset(records);
 }
 
+std::unique_ptr<AllocRecordObjectMap> Heap::ReleaseAllocationRecords() {
+  return std::move(allocation_records_);
+}
+
 void Heap::VisitAllocationRecords(RootVisitor* visitor) const {
   if (IsAllocTrackingEnabled()) {
     MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_);
index 46dce04..889069d 100644 (file)
@@ -766,6 +766,10 @@ class Heap {
     return allocation_records_.get();
   }
 
+  // Release ownership of the allocation records.
+  std::unique_ptr<AllocRecordObjectMap> ReleaseAllocationRecords()
+      REQUIRES(Locks::alloc_tracker_lock_);
+
   void SetAllocationRecords(AllocRecordObjectMap* records)
       REQUIRES(Locks::alloc_tracker_lock_);