Bug 1334129 - TraceLogger - On destruction remove the logger from the mainlogger list. r=bbouvier, a=jcristau
authorHannes Verschore <hv1989@gmail.com>
Fri, 27 Jan 2017 18:01:36 +0100
changeset 375769 e5f851a668419416d2328143ecb08783d21697f8
parent 375768 27fed9b44e87b15f4fd76bc1c3db5f954e4a3e55
child 375770 7d746d214c73fe9b43cd9c7f02466d0db802a3d6
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier, jcristau
bugs1334129
milestone53.0a2
Bug 1334129 - TraceLogger - On destruction remove the logger from the mainlogger list. r=bbouvier, a=jcristau
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
js/src/vm/TraceLogging.cpp
js/src/vm/TraceLogging.h
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -446,16 +446,20 @@ JSRuntime::destroyRuntime()
 
 #ifdef JS_SIMULATOR
     js::jit::Simulator::Destroy(simulator_);
 #endif
 
     DebugOnly<size_t> oldCount = liveRuntimesCount--;
     MOZ_ASSERT(oldCount > 0);
 
+#ifdef JS_TRACE_LOGGING
+    DestroyTraceLoggerMainThread(this);
+#endif
+
     js::TlsPerThreadData.set(nullptr);
 
 #ifdef XP_WIN
     if (ownerThreadNative_)
         CloseHandle((HANDLE)ownerThreadNative_);
 #endif
 }
 
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -270,17 +270,17 @@ class PerThreadData
      * fields of this runtime can provoke race conditions, so the
      * intention is that access will be mediated through safe
      * functions like |runtimeFromMainThread| and |associatedWith()| below.
      */
     JSRuntime* runtime_;
 
   public:
 #ifdef JS_TRACE_LOGGING
-    TraceLoggerThread*  traceLogger;
+    TraceLoggerMainThread*  traceLogger;
 #endif
 
     /* Pointer to the current AutoFlushICache. */
     js::jit::AutoFlushICache* autoFlushICache_;
 
   public:
     /* State used by jsdtoa.cpp. */
     DtoaState*          dtoaState;
--- a/js/src/vm/TraceLogging.cpp
+++ b/js/src/vm/TraceLogging.cpp
@@ -107,16 +107,24 @@ void
 js::DestroyTraceLoggerThreadState()
 {
     if (traceLoggerState) {
         js_delete(traceLoggerState);
         traceLoggerState = nullptr;
     }
 }
 
+void
+js::DestroyTraceLoggerMainThread(JSRuntime* runtime)
+{
+    if (!EnsureTraceLoggerState())
+        return;
+    traceLoggerState->destroyMainThread(runtime);
+}
+
 bool
 TraceLoggerThread::init()
 {
     if (!pointerMap.init())
         return false;
     if (!textIdPayloads.init())
         return false;
     if (!events.init())
@@ -664,20 +672,18 @@ TraceLoggerThread::log(uint32_t id)
 
     EventEntry& entry = events.pushUninitialized();
     entry.time = time;
     entry.textId = id;
 }
 
 TraceLoggerThreadState::~TraceLoggerThreadState()
 {
-    for (size_t i = 0; i < mainThreadLoggers.length(); i++)
-        js_delete(mainThreadLoggers[i]);
-
-    mainThreadLoggers.clear();
+    while (TraceLoggerMainThread* logger = traceLoggerMainThreadList.popFirst())
+        js_delete(logger);
 
     if (threadLoggers.initialized()) {
         for (ThreadLoggerHashMap::Range r = threadLoggers.all(); !r.empty(); r.popFront())
             js_delete(r.front().value());
 
         threadLoggers.finish();
     }
 
@@ -936,37 +942,52 @@ TraceLoggerThreadState::forMainThread(JS
 
 TraceLoggerThread*
 TraceLoggerThreadState::forMainThread(PerThreadData* mainThread)
 {
     MOZ_ASSERT(initialized);
     if (!mainThread->traceLogger) {
         LockGuard<Mutex> guard(lock);
 
-        TraceLoggerThread* logger = create();
+        TraceLoggerMainThread* logger = js_new<TraceLoggerMainThread>();
         if (!logger)
             return nullptr;
 
-        if (!mainThreadLoggers.append(logger)) {
+        if (!logger->init()) {
             js_delete(logger);
             return nullptr;
         }
 
+        traceLoggerMainThreadList.insertFront(logger);
         mainThread->traceLogger = logger;
 
         if (graphSpewingEnabled)
             logger->initGraph();
 
         if (mainThreadEnabled)
             logger->enable();
     }
 
     return mainThread->traceLogger;
 }
 
+void
+TraceLoggerThreadState::destroyMainThread(JSRuntime* runtime)
+{
+    MOZ_ASSERT(initialized);
+    PerThreadData* mainThread = &runtime->mainThread;
+    if (mainThread->traceLogger) {
+        LockGuard<Mutex> guard(lock);
+
+        mainThread->traceLogger->remove();
+        js_delete(mainThread->traceLogger);
+        mainThread->traceLogger = nullptr;
+    }
+}
+
 TraceLoggerThread*
 js::TraceLoggerForCurrentThread()
 {
     if (!EnsureTraceLoggerState())
         return nullptr;
     return traceLoggerState->forThread(ThisThread::GetId());
 }
 
@@ -976,49 +997,39 @@ TraceLoggerThreadState::forThread(const 
     MOZ_ASSERT(initialized);
 
     LockGuard<Mutex> guard(lock);
 
     ThreadLoggerHashMap::AddPtr p = threadLoggers.lookupForAdd(thread);
     if (p)
         return p->value();
 
-    TraceLoggerThread* logger = create();
+    TraceLoggerThread* logger = js_new<TraceLoggerThread>();
     if (!logger)
         return nullptr;
 
+    if (!logger->init()) {
+        js_delete(logger);
+        return nullptr;
+    }
+
     if (!threadLoggers.add(p, thread, logger)) {
         js_delete(logger);
         return nullptr;
     }
 
     if (graphSpewingEnabled)
         logger->initGraph();
 
     if (offThreadEnabled)
         logger->enable();
 
     return logger;
 }
 
-TraceLoggerThread*
-TraceLoggerThreadState::create()
-{
-    TraceLoggerThread* logger = js_new<TraceLoggerThread>();
-    if (!logger)
-        return nullptr;
-
-    if (!logger->init()) {
-        js_delete(logger);
-        return nullptr;
-    }
-
-    return logger;
-}
-
 bool
 js::TraceLogTextIdEnabled(uint32_t textId)
 {
     if (!EnsureTraceLoggerState())
         return false;
     return traceLoggerState->isTextIdEnabled(textId);
 }
 
--- a/js/src/vm/TraceLogging.h
+++ b/js/src/vm/TraceLogging.h
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef TraceLogging_h
 #define TraceLogging_h
 
 #include "mozilla/GuardObjects.h"
+#include "mozilla/LinkedList.h"
 
 #include "jsalloc.h"
 
 #include "js/HashTable.h"
 #include "js/TypeDecls.h"
 #include "js/Vector.h"
 #include "threading/Thread.h"
 #include "vm/MutexIDs.h"
@@ -304,36 +305,44 @@ class TraceLoggerThread
 
   public:
     static unsigned offsetOfEnabled() {
         return offsetof(TraceLoggerThread, enabled_);
     }
 #endif
 };
 
+#ifdef JS_TRACE_LOGGING
+class TraceLoggerMainThread
+  : public TraceLoggerThread,
+    public mozilla::LinkedListElement<TraceLoggerMainThread>
+{
+
+};
+#endif
+
 class TraceLoggerThreadState
 {
 #ifdef JS_TRACE_LOGGING
     typedef HashMap<Thread::Id,
                     TraceLoggerThread*,
                     Thread::Hasher,
                     SystemAllocPolicy> ThreadLoggerHashMap;
-    typedef Vector<TraceLoggerThread*, 1, js::SystemAllocPolicy > MainThreadLoggers;
 
 #ifdef DEBUG
     bool initialized;
 #endif
 
     bool enabledTextIds[TraceLogger_Last];
     bool mainThreadEnabled;
     bool offThreadEnabled;
     bool graphSpewingEnabled;
     bool spewErrors;
     ThreadLoggerHashMap threadLoggers;
-    MainThreadLoggers mainThreadLoggers;
+    mozilla::LinkedList<TraceLoggerMainThread> traceLoggerMainThreadList;
 
   public:
     uint64_t startupTime;
     Mutex lock;
 
     TraceLoggerThreadState()
       :
 #ifdef DEBUG
@@ -347,37 +356,38 @@ class TraceLoggerThreadState
     { }
 
     bool init();
     ~TraceLoggerThreadState();
 
     TraceLoggerThread* forMainThread(JSRuntime* runtime);
     TraceLoggerThread* forMainThread(jit::CompileRuntime* runtime);
     TraceLoggerThread* forThread(const Thread::Id& thread);
+    void destroyMainThread(JSRuntime* runtime);
 
     bool isTextIdEnabled(uint32_t textId) {
         if (textId < TraceLogger_Last)
             return enabledTextIds[textId];
         return true;
     }
     void enableTextId(JSContext* cx, uint32_t textId);
     void disableTextId(JSContext* cx, uint32_t textId);
     void maybeSpewError(const char* text) {
         if (spewErrors)
             fprintf(stderr, "%s\n", text);
     }
 
   private:
     TraceLoggerThread* forMainThread(PerThreadData* mainThread);
-    TraceLoggerThread* create();
 #endif
 };
 
 #ifdef JS_TRACE_LOGGING
 void DestroyTraceLoggerThreadState();
+void DestroyTraceLoggerMainThread(JSRuntime* runtime);
 
 TraceLoggerThread* TraceLoggerForMainThread(JSRuntime* runtime);
 TraceLoggerThread* TraceLoggerForMainThread(jit::CompileRuntime* runtime);
 TraceLoggerThread* TraceLoggerForCurrentThread();
 #else
 inline TraceLoggerThread* TraceLoggerForMainThread(JSRuntime* runtime) {
     return nullptr;
 };