Bug 1550924 - Fix race condition in memory tracking assertion r=sfink?
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 13 May 2019 17:10:19 +0000
changeset 532457 46ad1099db88415ea5af702bfd4986a5957b9d6f
parent 532456 027695189d656e036946b9774921fb8e2e09a1f8
child 532458 e153188e2d93b251c16a6a1d74fd1e2d952fe2eb
push id11268
push usercsabou@mozilla.com
push dateTue, 14 May 2019 15:24:22 +0000
treeherdermozilla-beta@5fb7fcd568d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1550924
milestone68.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 1550924 - Fix race condition in memory tracking assertion r=sfink? Fix possible race condition where an atomic field that may be concurrently modified is referenced twice in an assertion expression. Differential Revision: https://phabricator.services.mozilla.com/D30891
js/src/gc/Scheduling.h
--- a/js/src/gc/Scheduling.h
+++ b/js/src/gc/Scheduling.h
@@ -303,16 +303,17 @@
  *          Assumptions:
  *            -> size[retained] < size[available_memory]
  */
 
 #ifndef gc_Scheduling_h
 #define gc_Scheduling_h
 
 #include "mozilla/Atomics.h"
+#include "mozilla/DebugOnly.h"
 
 #include "js/HashTable.h"
 
 namespace js {
 
 #define JS_FOR_EACH_INTERNAL_MEMORY_USE(_)      \
   _(ArrayBufferContents)                        \
   _(StringContents)
@@ -670,30 +671,35 @@ class MemoryTracker {
   MemoryTracker();
   ~MemoryTracker();
   void fixupAfterMovingGC();
 #endif
 
   void addMemory(Cell* cell, size_t nbytes, MemoryUse use) {
     MOZ_ASSERT(cell);
     MOZ_ASSERT(nbytes);
+    mozilla::DebugOnly<size_t> initialBytes(bytes_);
+    MOZ_ASSERT(initialBytes + nbytes > initialBytes);
+
+    bytes_ += nbytes;
+
 #ifdef DEBUG
     trackMemory(cell, nbytes, use);
 #endif
-    MOZ_ASSERT(bytes_ + nbytes >= bytes_);
-    bytes_ += nbytes;
   }
   void removeMemory(Cell* cell, size_t nbytes, MemoryUse use) {
     MOZ_ASSERT(cell);
     MOZ_ASSERT(nbytes);
+    MOZ_ASSERT(bytes_ >= nbytes);
+
+    bytes_ -= nbytes;
+
 #ifdef DEBUG
     untrackMemory(cell, nbytes, use);
 #endif
-    MOZ_ASSERT(bytes_ >= nbytes);
-    bytes_ -= nbytes;
   }
 
   size_t bytes() const { return bytes_; }
 
   void adopt(MemoryTracker& other);
 
  private:
   mozilla::Atomic<size_t, mozilla::Relaxed,