Bug 1233401 - Do Statistics static initialization from JS_Init; r=jandem
authorMs2ger <Ms2ger@gmail.com>
Fri, 18 Dec 2015 11:12:49 +0100
changeset 276927 c91751d92150a1f8d696a77d8b82a053497ea909
parent 276926 8c1b2e53da07d57aefa9265eec377273fb9d4d7e
child 276928 0be855d09b8e9877a18bb68eee52c015512458e2
push id16708
push usercbook@mozilla.com
push dateFri, 18 Dec 2015 14:27:21 +0000
treeherderfx-team@ce75ab3d79c6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1233401
milestone46.0a1
Bug 1233401 - Do Statistics static initialization from JS_Init; r=jandem
js/src/gc/Statistics.cpp
js/src/gc/Statistics.h
js/src/vm/Initialization.cpp
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -758,65 +758,16 @@ Statistics::Statistics(JSRuntime* rt)
     aborted(false)
 {
     PodArrayZero(phaseTotals);
     PodArrayZero(counts);
     PodArrayZero(phaseStartTimes);
     for (auto d : MakeRange(NumTimingArrays))
         PodArrayZero(phaseTimes[d]);
 
-    static bool initialized = false;
-    if (!initialized) {
-        initialized = true;
-
-        for (size_t i = 0; i < PHASE_LIMIT; i++) {
-            MOZ_ASSERT(phases[i].index == i);
-            for (size_t j = 0; j < PHASE_LIMIT; j++)
-                MOZ_ASSERT_IF(i != j, phases[i].telemetryBucket != phases[j].telemetryBucket);
-        }
-
-        // Create a static table of descendants for every phase with multiple
-        // children. This assumes that all descendants come linearly in the
-        // list, which is reasonable since full dags are not supported; any
-        // path from the leaf to the root must encounter at most one node with
-        // multiple parents.
-        size_t dagSlot = 0;
-        for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
-            Phase parent = dagChildEdges[i].parent;
-            if (!phaseExtra[parent].dagSlot)
-                phaseExtra[parent].dagSlot = ++dagSlot;
-
-            Phase child = dagChildEdges[i].child;
-            MOZ_ASSERT(phases[child].parent == PHASE_MULTI_PARENTS);
-            int j = child;
-            do {
-                dagDescendants[phaseExtra[parent].dagSlot].append(Phase(j));
-                j++;
-            } while (j != PHASE_LIMIT && phases[j].parent != PHASE_MULTI_PARENTS);
-        }
-        MOZ_ASSERT(dagSlot <= MaxMultiparentPhases - 1);
-
-        // Fill in the depth of each node in the tree. Multi-parented nodes
-        // have depth 0.
-        mozilla::Vector<Phase> stack;
-        stack.append(PHASE_LIMIT); // Dummy entry to avoid special-casing the first node
-        for (int i = 0; i < PHASE_LIMIT; i++) {
-            if (phases[i].parent == PHASE_NO_PARENT ||
-                phases[i].parent == PHASE_MULTI_PARENTS)
-            {
-                stack.clear();
-            } else {
-                while (stack.back() != phases[i].parent)
-                    stack.popBack();
-            }
-            phaseExtra[i].depth = stack.length();
-            stack.append(Phase(i));
-        }
-    }
-
     char* env = getenv("MOZ_GCTIMER");
     if (env) {
         if (strcmp(env, "none") == 0) {
             fp = nullptr;
         } else if (strcmp(env, "stdout") == 0) {
             fp = stdout;
         } else if (strcmp(env, "stderr") == 0) {
             fp = stderr;
@@ -829,16 +780,65 @@ Statistics::Statistics(JSRuntime* rt)
 }
 
 Statistics::~Statistics()
 {
     if (fp && fp != stdout && fp != stderr)
         fclose(fp);
 }
 
+/* static */ void
+Statistics::initialize()
+{
+    for (size_t i = 0; i < PHASE_LIMIT; i++) {
+        MOZ_ASSERT(phases[i].index == i);
+        for (size_t j = 0; j < PHASE_LIMIT; j++)
+            MOZ_ASSERT_IF(i != j, phases[i].telemetryBucket != phases[j].telemetryBucket);
+    }
+
+    // Create a static table of descendants for every phase with multiple
+    // children. This assumes that all descendants come linearly in the
+    // list, which is reasonable since full dags are not supported; any
+    // path from the leaf to the root must encounter at most one node with
+    // multiple parents.
+    size_t dagSlot = 0;
+    for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
+        Phase parent = dagChildEdges[i].parent;
+        if (!phaseExtra[parent].dagSlot)
+            phaseExtra[parent].dagSlot = ++dagSlot;
+
+        Phase child = dagChildEdges[i].child;
+        MOZ_ASSERT(phases[child].parent == PHASE_MULTI_PARENTS);
+        int j = child;
+        do {
+            dagDescendants[phaseExtra[parent].dagSlot].append(Phase(j));
+            j++;
+        } while (j != PHASE_LIMIT && phases[j].parent != PHASE_MULTI_PARENTS);
+    }
+    MOZ_ASSERT(dagSlot <= MaxMultiparentPhases - 1);
+
+    // Fill in the depth of each node in the tree. Multi-parented nodes
+    // have depth 0.
+    mozilla::Vector<Phase> stack;
+    stack.append(PHASE_LIMIT); // Dummy entry to avoid special-casing the first node
+    for (int i = 0; i < PHASE_LIMIT; i++) {
+        if (phases[i].parent == PHASE_NO_PARENT ||
+            phases[i].parent == PHASE_MULTI_PARENTS)
+        {
+            stack.clear();
+        } else {
+            while (stack.back() != phases[i].parent)
+                stack.popBack();
+        }
+        phaseExtra[i].depth = stack.length();
+        stack.append(Phase(i));
+    }
+
+}
+
 JS::GCSliceCallback
 Statistics::setSliceCallback(JS::GCSliceCallback newCallback)
 {
     JS::GCSliceCallback oldCallback = sliceCallback;
     sliceCallback = newCallback;
     return oldCallback;
 }
 
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -157,16 +157,18 @@ struct Statistics
      * DAGs, this decision should be reconsidered.
      */
     static const size_t MaxMultiparentPhases = 6;
     static const size_t NumTimingArrays = MaxMultiparentPhases + 1;
 
     /* Create a convenient type for referring to tables of phase times. */
     using PhaseTimeTable = int64_t[NumTimingArrays][PHASE_LIMIT];
 
+    static void initialize();
+
     explicit Statistics(JSRuntime* rt);
     ~Statistics();
 
     void beginPhase(Phase phase);
     void endPhase(Phase phase);
     void endParallelPhase(Phase phase, const GCParallelTask* task);
 
     void beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
--- a/js/src/vm/Initialization.cpp
+++ b/js/src/vm/Initialization.cpp
@@ -10,16 +10,17 @@
 
 #include "mozilla/Assertions.h"
 
 #include <ctype.h>
 
 #include "jstypes.h"
 
 #include "builtin/AtomicsObject.h"
+#include "gc/Statistics.h"
 #include "jit/ExecutableAllocator.h"
 #include "jit/Ion.h"
 #include "js/Utility.h"
 #if ENABLE_INTL_API
 #include "unicode/uclean.h"
 #include "unicode/utypes.h"
 #endif // ENABLE_INTL_API
 #include "vm/DateTime.h"
@@ -98,16 +99,18 @@ JS_Init(void)
 #endif // EXPOSE_INTL_API
 
     if (!js::CreateHelperThreadsState())
         return false;
 
     if (!FutexRuntime::initialize())
         return false;
 
+    js::gcstats::Statistics::initialize();
+
     libraryInitState = InitState::Running;
     return true;
 }
 
 JS_PUBLIC_API(void)
 JS_ShutDown(void)
 {
     MOZ_ASSERT(libraryInitState == InitState::Running,