Bug 968956 - DMD: Acquire state lock before clearing reports. r=njn.
authorEric Rahm <erahm@mozilla.com>
Fri, 07 Feb 2014 15:23:50 -0800
changeset 184974 b667bd72d90978516a1b686a280208639a50f799
parent 184973 136a8198b5e98d67f4553a1209c2b5030e03d506
child 184975 ce819018434bb72961b9c764e9de8b1c9a29930b
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs968956
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 968956 - DMD: Acquire state lock before clearing reports. r=njn. DONTBUILD because DMD is NPOTB.
memory/replace/dmd/DMD.cpp
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -1830,21 +1830,25 @@ Init(const malloc_table_t* aMallocTable)
 #endif
 
   gStateLock = InfallibleAllocPolicy::new_<Mutex>();
 
   gSmallBlockActualSizeCounter = 0;
 
   DMD_CREATE_TLS_INDEX(gTlsIndex);
 
-  gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
-  gStackTraceTable->init(8192);
-
-  gBlockTable = InfallibleAllocPolicy::new_<BlockTable>();
-  gBlockTable->init(8192);
+  {
+    AutoLockState lock;
+
+    gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>();
+    gStackTraceTable->init(8192);
+
+    gBlockTable = InfallibleAllocPolicy::new_<BlockTable>();
+    gBlockTable->init(8192);
+  }
 
   if (gOptions->IsTestMode()) {
     // OpenOutputFile() can allocate.  So do this before setting
     // gIsDMDRunning so those allocations don't show up in our results.  Once
     // gIsDMDRunning is set we are intercepting malloc et al. in earnest.
     FILE* fp = OpenOutputFile("test.dmd");
     gIsDMDRunning = true;
 
@@ -2007,22 +2011,23 @@ PrintSortedTraceAndFrameRecords(const Wr
     }
   }
 
   PrintSortedRecords(aWriter, aLocService, aStr, astr, frameRecordTable,
                      aCategoryUsableSize, aTotalUsableSize);
 }
 
 // Note that, unlike most SizeOf* functions, this function does not take a
-// |mozilla::MallocSizeOf| argument.  That's because those arguments are primarily
-// to aid DMD track heap blocks... but DMD deliberately doesn't track heap
-// blocks it allocated for itself!
+// |mozilla::MallocSizeOf| argument.  That's because those arguments are
+// primarily to aid DMD track heap blocks... but DMD deliberately doesn't track
+// heap blocks it allocated for itself!
 //
-// SizeOfInternal should be called while you're holding the state lock and while
-// intercepts are blocked; SizeOf acquires the lock and blocks intercepts.
+// SizeOfInternal should be called while you're holding the state lock and
+// while intercepts are blocked; SizeOf acquires the lock and blocks
+// intercepts.
 
 static void
 SizeOfInternal(Sizes* aSizes)
 {
   MOZ_ASSERT(gStateLock->IsLocked());
   MOZ_ASSERT(Thread::Fetch()->InterceptsAreBlocked());
 
   aSizes->Clear();
@@ -2061,32 +2066,41 @@ SizeOf(Sizes* aSizes)
     return;
   }
 
   AutoBlockIntercepts block(Thread::Fetch());
   AutoLockState lock;
   SizeOfInternal(aSizes);
 }
 
-MOZ_EXPORT void
-ClearReports()
+void
+ClearReportsInternal()
 {
-  if (!gIsDMDRunning) {
-    return;
-  }
+  MOZ_ASSERT(gStateLock->IsLocked());
 
   // Unreport all blocks that were marked reported by a memory reporter.  This
   // excludes those that were reported on allocation, because they need to keep
   // their reported marking.
   for (BlockTable::Range r = gBlockTable->all(); !r.empty(); r.popFront()) {
     r.front().UnreportIfNotReportedOnAlloc();
   }
 }
 
 MOZ_EXPORT void
+ClearReports()
+{
+  if (!gIsDMDRunning) {
+    return;
+  }
+
+  AutoLockState lock;
+  ClearReportsInternal();
+}
+
+MOZ_EXPORT void
 Dump(Writer aWriter)
 {
   if (!gIsDMDRunning) {
     const char* msg = "cannot Dump();  DMD was not enabled at startup\n";
     StatusMsg("%s", msg);
     W("%s", msg);
     return;
   }
@@ -2265,17 +2279,17 @@ Dump(Writer aWriter)
     W("  Location service cache:  %4.1f%% hit rate, %.1f%% occupancy at end\n",
       Percent(hits, requests), Percent(count, capacity));
 
     W("\n");
   }
 
   InfallibleAllocPolicy::delete_(locService);
 
-  ClearReports();
+  ClearReportsInternal(); // Use internal version, we already have the lock.
 
   StatusMsg("}\n");
 }
 
 //---------------------------------------------------------------------------
 // Testing
 //---------------------------------------------------------------------------