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 473640 46ad1099db88415ea5af702bfd4986a5957b9d6f
parent 473632 027695189d656e036946b9774921fb8e2e09a1f8
child 473641 e153188e2d93b251c16a6a1d74fd1e2d952fe2eb
push id36009
push userapavel@mozilla.com
push dateTue, 14 May 2019 04:07:34 +0000
treeherdermozilla-central@96563508f9fe [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,