Backed out changeset 46f6705f9c0c (bug 1533240) for xpcshell failures at /test/test_dmd.js on a CLOSED TREE.
authorGurzau Raul <rgurzau@mozilla.com>
Thu, 14 Mar 2019 07:03:38 +0200
changeset 521830 bc61185b6f57
parent 521829 e4a6f915841a
child 521837 d322d19da585
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1533240
milestone67.0a1
backs out46f6705f9c0c
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
Backed out changeset 46f6705f9c0c (bug 1533240) for xpcshell failures at /test/test_dmd.js on a CLOSED TREE.
memory/replace/dmd/DMD.cpp
--- a/memory/replace/dmd/DMD.cpp
+++ b/memory/replace/dmd/DMD.cpp
@@ -36,17 +36,16 @@
 #include "mozilla/HashFunctions.h"
 #include "mozilla/HashTable.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/JSONWriter.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/StackWalk.h"
-#include "mozilla/ThreadLocal.h"
 
 // CodeAddressService is defined entirely in the header, so this does not make
 // DMD depend on XPCOM's object file.
 #include "CodeAddressService.h"
 
 // replace_malloc.h needs to be included before replace_malloc_bridge.h,
 // which DMD.h includes, so DMD.h needs to be included after replace_malloc.h.
 #include "replace_malloc.h"
@@ -431,68 +430,85 @@ class AutoUnlockState {
   DISALLOW_COPY_AND_ASSIGN(AutoUnlockState);
 
  public:
   AutoUnlockState() { gStateLock->Unlock(); }
   ~AutoUnlockState() { gStateLock->Lock(); }
 };
 
 //---------------------------------------------------------------------------
-// Per-thread blocking of intercepts
+// Thread-local storage and blocking of intercepts
 //---------------------------------------------------------------------------
 
+#ifdef XP_WIN
+
+#  define DMD_TLS_INDEX_TYPE DWORD
+#  define DMD_CREATE_TLS_INDEX(i_) \
+    do {                           \
+      (i_) = TlsAlloc();           \
+    } while (0)
+#  define DMD_DESTROY_TLS_INDEX(i_) TlsFree((i_))
+#  define DMD_GET_TLS_DATA(i_) TlsGetValue((i_))
+#  define DMD_SET_TLS_DATA(i_, v_) TlsSetValue((i_), (v_))
+
+#else
+
+#  define DMD_TLS_INDEX_TYPE pthread_key_t
+#  define DMD_CREATE_TLS_INDEX(i_) pthread_key_create(&(i_), nullptr)
+#  define DMD_DESTROY_TLS_INDEX(i_) pthread_key_delete((i_))
+#  define DMD_GET_TLS_DATA(i_) pthread_getspecific((i_))
+#  define DMD_SET_TLS_DATA(i_, v_) pthread_setspecific((i_), (v_))
+
+#endif
+
+static DMD_TLS_INDEX_TYPE gTlsIndex;
+
 class Thread {
   // Required for allocation via InfallibleAllocPolicy::new_.
   friend class InfallibleAllocPolicy;
 
   // When true, this blocks intercepts, which allows malloc interception
   // functions to themselves call malloc.  (Nb: for direct calls to malloc we
   // can just use InfallibleAllocPolicy::{malloc_,new_}, but we sometimes
   // indirectly call vanilla malloc via functions like MozStackWalk.)
   bool mBlockIntercepts;
 
   Thread() : mBlockIntercepts(false) {}
 
   DISALLOW_COPY_AND_ASSIGN(Thread);
 
-  static MOZ_THREAD_LOCAL(Thread*) tlsThread;
-
  public:
-  static void Init() {
-    if (!tlsThread.init()) {
-      MOZ_CRASH();
-    }
-  }
-
-  static Thread* Fetch() {
-    Thread* t = tlsThread.get();
-    if (MOZ_UNLIKELY(!t)) {
-      // This memory is never freed, even if the thread dies. It's a leak, but
-      // only a tiny one.
-      t = InfallibleAllocPolicy::new_<Thread>();
-      tlsThread.set(t);
-    }
-
-    return t;
-  }
+  static Thread* Fetch();
 
   bool BlockIntercepts() {
     MOZ_ASSERT(!mBlockIntercepts);
     return mBlockIntercepts = true;
   }
 
   bool UnblockIntercepts() {
     MOZ_ASSERT(mBlockIntercepts);
     return mBlockIntercepts = false;
   }
 
   bool InterceptsAreBlocked() const { return mBlockIntercepts; }
 };
 
-MOZ_THREAD_LOCAL(Thread*) Thread::tlsThread;
+/* static */
+Thread* Thread::Fetch() {
+  Thread* t = static_cast<Thread*>(DMD_GET_TLS_DATA(gTlsIndex));
+
+  if (MOZ_UNLIKELY(!t)) {
+    // This memory is never freed, even if the thread dies.  It's a leak, but
+    // only a tiny one.
+    t = InfallibleAllocPolicy::new_<Thread>();
+    DMD_SET_TLS_DATA(gTlsIndex, t);
+  }
+
+  return t;
+}
 
 // An object of this class must be created (on the stack) before running any
 // code that might allocate.
 class AutoBlockIntercepts {
   Thread* const mT;
 
   DISALLOW_COPY_AND_ASSIGN(AutoBlockIntercepts);
 
@@ -1389,17 +1405,17 @@ static bool Init(malloc_table_t* aMalloc
   gOptions = InfallibleAllocPolicy::new_<Options>(e);
 
   gStateLock = InfallibleAllocPolicy::new_<Mutex>();
 
   gBernoulli = (FastBernoulliTrial*)InfallibleAllocPolicy::malloc_(
       sizeof(FastBernoulliTrial));
   ResetBernoulli();
 
-  Thread::Init();
+  DMD_CREATE_TLS_INDEX(gTlsIndex);
 
   {
     AutoLockState lock;
 
     gStackTraceTable = InfallibleAllocPolicy::new_<StackTraceTable>(8192);
     gLiveBlockTable = InfallibleAllocPolicy::new_<LiveBlockTable>(8192);
 
     // Create this even if the mode isn't Cumulative (albeit with a small