Bug 1322380 - Print major / minor GC profiling headers together if both enabled r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Wed, 07 Dec 2016 10:36:06 -1000
changeset 325392 d01ac7a95ee4a3e90280ef94551d9b70f5fc511b
parent 325391 928bb2ef0ef68cef61aa2e15d4d0d1861bcd0c73
child 325393 c2626a3d815c38b0308e4957292f5e723d323772
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerssfink
bugs1322380
milestone53.0a1
Bug 1322380 - Print major / minor GC profiling headers together if both enabled r=sfink
js/src/gc/Nursery.cpp
js/src/gc/Nursery.h
js/src/gc/Statistics.cpp
js/src/gc/Statistics.h
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -483,19 +483,23 @@ js::TenuringTracer::TenuringTracer(JSRun
   : JSTracer(rt, JSTracer::TracerKindTag::Tenuring, TraceWeakMapKeysValues)
   , nursery_(*nursery)
   , tenuredSize(0)
   , head(nullptr)
   , tail(&head)
 {
 }
 
-/* static */ void
+void
 js::Nursery::printProfileHeader()
 {
+    if (!enableProfiling_)
+        return;
+
+    fprintf(stderr, "MinorGC:               Reason  PRate Size ");
 #define PRINT_HEADER(name, text)                                              \
     fprintf(stderr, " %6s", text);
 FOR_EACH_NURSERY_PROFILE_TIME(PRINT_HEADER)
 #undef PRINT_HEADER
     fprintf(stderr, "\n");
 }
 
 /* static */ void
@@ -625,21 +629,17 @@ js::Nursery::collect(JSRuntime* rt, JS::
         rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason);
     rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, sizeOfHeapCommitted());
     rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount);
 
     rt->gc.stats.endNurseryCollection(reason);
     TraceMinorGCEnd();
 
     if (enableProfiling_ && totalTime >= profileThreshold_) {
-        static int printedHeader = 0;
-        if ((printedHeader++ % 200) == 0) {
-            fprintf(stderr, "MinorGC:               Reason  PRate Size ");
-            printProfileHeader();
-        }
+        rt->gc.stats.maybePrintProfileHeaders();
 
         fprintf(stderr, "MinorGC: %20s %5.1f%% %4u ",
                 JS::gcreason::ExplainReason(reason),
                 promotionRate * 100,
                 numChunks());
         printProfileTimes(profileTimes_);
 
         if (reportTenurings_) {
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -252,16 +252,19 @@ class Nursery
                (numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize;
     }
 
 #ifdef JS_GC_ZEAL
     void enterZealMode();
     void leaveZealMode();
 #endif
 
+    /* Print header line for profile times. */
+    void printProfileHeader();
+
     /* Print total profile times on shutdown. */
     void printTotalProfileTimes();
 
   private:
     /* The amount of space in the mapped nursery available to allocations. */
     static const size_t NurseryChunkUsableSize = gc::ChunkSize - sizeof(gc::ChunkTrailer);
 
     struct NurseryChunk {
@@ -453,17 +456,16 @@ class Nursery
     void shrinkAllocableSpace();
     void minimizeAllocableSpace();
 
     /* Profile recording and printing. */
     void startProfile(ProfileKey key);
     void endProfile(ProfileKey key);
     void maybeStartProfile(ProfileKey key);
     void maybeEndProfile(ProfileKey key);
-    static void printProfileHeader();
     static void printProfileTimes(const ProfileTimes& times);
 
     friend class TenuringTracer;
     friend class gc::MinorCollectionTracer;
     friend class jit::MacroAssembler;
 };
 
 } /* namespace js */
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -1321,19 +1321,33 @@ Statistics::computeMMU(int64_t window) c
             cur -= (slices[endIndex].end - slices[startIndex].start - window);
         if (cur > gcMax)
             gcMax = cur;
     }
 
     return double(window - gcMax) / window;
 }
 
-/* static */ void
+void
+Statistics::maybePrintProfileHeaders()
+{
+    static int printedHeader = 0;
+    if ((printedHeader++ % 200) == 0) {
+        printProfileHeader();
+        runtime->gc.nursery.printProfileHeader();
+    }
+}
+
+void
 Statistics::printProfileHeader()
 {
+    if (!enableProfiling_)
+        return;
+
+    fprintf(stderr, "MajorGC:               Reason States      ");
     fprintf(stderr, " %6s", "total");
 #define PRINT_PROFILE_HEADER(name, text, phase)                               \
     fprintf(stderr, " %6s", text);
 FOR_EACH_GC_PROFILE_TIME(PRINT_PROFILE_HEADER)
 #undef PRINT_PROFILE_HEADER
     fprintf(stderr, "\n");
 }
 
@@ -1345,21 +1359,17 @@ Statistics::printProfileTimes(const Prof
     fprintf(stderr, "\n");
 }
 
 void
 Statistics::printSliceProfile()
 {
     const SliceData& slice = slices.back();
 
-    static int printedHeader = 0;
-    if ((printedHeader++ % 200) == 0) {
-        fprintf(stderr, "MajorGC:               Reason States      ");
-        printProfileHeader();
-    }
+    maybePrintProfileHeaders();
 
     fprintf(stderr, "MajorGC: %20s %1d -> %1d      ",
             ExplainReason(slice.reason), int(slice.initialState), int(slice.finalState));
 
     ProfileTimes times;
     times[ProfileKey::Total] = slice.duration();
     totalTimes_[ProfileKey::Total] += times[ProfileKey::Total];
 
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -308,16 +308,22 @@ struct Statistics
     };
 
     typedef Vector<SliceData, 8, SystemAllocPolicy> SliceDataVector;
     typedef SliceDataVector::ConstRange SliceRange;
 
     SliceRange sliceRange() const { return slices.all(); }
     size_t slicesLength() const { return slices.length(); }
 
+    /* Occasionally print header lines for profiling information. */
+    void maybePrintProfileHeaders();
+
+    /* Print header line for profile times. */
+    void printProfileHeader();
+
     /* Print total profile times on shutdown. */
     void printTotalProfileTimes();
 
   private:
     JSRuntime* runtime;
 
     int64_t startupTime;
 
@@ -424,17 +430,16 @@ FOR_EACH_GC_PROFILE_TIME(DEFINE_TIME_KEY
 
     UniqueChars formatJsonDescription(uint64_t timestamp);
     UniqueChars formatJsonSliceDescription(unsigned i, const SliceData& slice);
     UniqueChars formatJsonPhaseTimes(const PhaseTimeTable phaseTimes);
 
     double computeMMU(int64_t resolution) const;
 
     void printSliceProfile();
-    static void printProfileHeader();
     static void printProfileTimes(const ProfileTimes& times);
 };
 
 struct MOZ_RAII AutoGCSlice
 {
     AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
                 SliceBudget budget, JS::gcreason::Reason reason)
       : stats(stats)