Bug 1088831 - Count storebuffer compactions, r=jonco
authorSteve Fink <sfink@mozilla.com>
Tue, 04 Nov 2014 08:34:56 -0800
changeset 213916 7a9f3b3b30068a6bc78ce1d25dc14af2a79ba90c
parent 213915 69bcf4fef10328df08319d78659888777e820066
child 213917 d6aceb31282a45692389874e0c1d3678f140da60
push id51374
push usersfink@mozilla.com
push dateTue, 04 Nov 2014 21:28:18 +0000
treeherdermozilla-inbound@5cbe9fc3c2ff [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1088831
milestone36.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 1088831 - Count storebuffer compactions, r=jonco
js/src/gc/Statistics.cpp
js/src/gc/Statistics.h
js/src/gc/StoreBuffer.cpp
js/src/gc/StoreBuffer.h
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -380,16 +380,17 @@ Statistics::formatData(StatisticsSeriali
         ss.appendDecimal("Max Pause", "ms", t(longest));
     else
         ss.appendString("Reason", ExplainReason(slices[0].reason));
     ss.appendDecimal("Total Time", "ms", t(total));
     ss.appendNumber("Zones Collected", "%d", "", zoneStats.collectedZoneCount);
     ss.appendNumber("Total Zones", "%d", "", zoneStats.zoneCount);
     ss.appendNumber("Total Compartments", "%d", "", zoneStats.compartmentCount);
     ss.appendNumber("Minor GCs", "%d", "", counts[STAT_MINOR_GC]);
+    ss.appendNumber("Store Buffer Compactions", "%d", "", counts[STAT_COMPACT_STOREBUFFER]);
     ss.appendNumber("MMU (20ms)", "%d", "%", int(mmu20 * 100));
     ss.appendNumber("MMU (50ms)", "%d", "%", int(mmu50 * 100));
     ss.appendDecimal("SCC Sweep Total", "ms", t(sccTotal));
     ss.appendDecimal("SCC Sweep Max Pause", "ms", t(sccLongest));
     if (nonincrementalReason || ss.isJSON()) {
         ss.appendString("Nonincremental Reason",
                         nonincrementalReason ? nonincrementalReason : "none");
     }
@@ -471,31 +472,33 @@ Statistics::formatDescription()
     const char *format =
 "=================================================================\n\
   Invocation Kind: %s\n\
   Reason: %s\n\
   Incremental: %s%s\n\
   Zones Collected: %d of %d\n\
   Compartments Collected: %d of %d\n\
   MinorGCs since last GC: %d\n\
+  Store Buffer Compactions: %d\n\
   MMU 20ms:%.1f%%; 50ms:%.1f%%\n\
   SCC Sweep Total (MaxPause): %.3fms (%.3fms)\n\
   HeapSize: %.3f MiB\n\
   Chunk Delta (magnitude): %+d  (%d)\n\
 ";
     char buffer[1024];
     memset(buffer, 0, sizeof(buffer));
     JS_snprintf(buffer, sizeof(buffer), format,
                 ExplainInvocationKind(gckind),
                 ExplainReason(slices[0].reason),
                 nonincrementalReason ? "no - " : "yes",
                                                   nonincrementalReason ? nonincrementalReason : "",
                 zoneStats.collectedZoneCount, zoneStats.zoneCount,
                 zoneStats.collectedCompartmentCount, zoneStats.compartmentCount,
                 counts[STAT_MINOR_GC],
+                counts[STAT_COMPACT_STOREBUFFER],
                 mmu20 * 100., mmu50 * 100.,
                 t(sccTotal), t(sccLongest),
                 double(preBytes) / 1024. / 1024.,
                 counts[STAT_NEW_CHUNK] - counts[STAT_DESTROY_CHUNK], counts[STAT_NEW_CHUNK] +
                                                                   counts[STAT_DESTROY_CHUNK]);
     return make_string_copy(buffer);
 }
 
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -73,16 +73,17 @@ enum Phase {
 
     PHASE_LIMIT
 };
 
 enum Stat {
     STAT_NEW_CHUNK,
     STAT_DESTROY_CHUNK,
     STAT_MINOR_GC,
+    STAT_COMPACT_STOREBUFFER,
 
     STAT_LIMIT
 };
 
 class StatisticsSerializer;
 
 struct ZoneGCStats
 {
--- a/js/src/gc/StoreBuffer.cpp
+++ b/js/src/gc/StoreBuffer.cpp
@@ -14,16 +14,22 @@
 #include "vm/ForkJoin.h"
 
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
 using mozilla::ReentrancyGuard;
 
+gcstats::Statistics&
+StoreBuffer::stats()
+{
+    return runtime_->gc.stats;
+}
+
 /*** Edges ***/
 
 void
 StoreBuffer::SlotsEdge::mark(JSTracer *trc)
 {
     NativeObject *obj = object();
 
     // Beware JSObject::swap exchanging a native object for a non-native one.
@@ -105,16 +111,18 @@ StoreBuffer::MonoTypeBuffer<T>::handleOv
             maybeCompact(owner);
     }
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::compactRemoveDuplicates(StoreBuffer *owner)
 {
+    Statistics& stats = owner->stats();
+
     typedef HashSet<T, typename T::Hasher, SystemAllocPolicy> DedupSet;
 
     DedupSet duplicates;
     if (!duplicates.init())
         return; /* Failure to de-dup is acceptable. */
 
     LifoAlloc::Enum insert(*storage_);
     for (LifoAlloc::Enum e(*storage_); !e.empty(); e.popFront<T>()) {
@@ -125,16 +133,17 @@ StoreBuffer::MonoTypeBuffer<T>::compactR
 
             /* Failure to insert will leave the set with duplicates. Oh well. */
             duplicates.put(*edge);
         }
     }
     storage_->release(insert.mark());
 
     duplicates.clear();
+    stats.count(gcstats::STAT_COMPACT_STOREBUFFER);
 }
 
 template <typename T>
 void
 StoreBuffer::MonoTypeBuffer<T>::compact(StoreBuffer *owner)
 {
     MOZ_ASSERT(storage_);
     compactRemoveDuplicates(owner);
--- a/js/src/gc/StoreBuffer.h
+++ b/js/src/gc/StoreBuffer.h
@@ -17,16 +17,20 @@
 
 #include "ds/LifoAlloc.h"
 #include "gc/Nursery.h"
 #include "gc/Tracer.h"
 #include "js/MemoryMetrics.h"
 
 namespace js {
 
+namespace gcstats {
+struct Statistics;
+}
+
 MOZ_NORETURN void
 CrashAtUnhandlableOOM(const char *reason);
 
 namespace gc {
 
 /*
  * BufferableRef represents an abstract reference for use in the generational
  * GC's remembered set. Entries in the store buffer that cannot be represented
@@ -484,16 +488,18 @@ class StoreBuffer
     void putGeneric(const T &t) { putFromAnyThread(bufferGeneric, t);}
 
     /* Insert or update a callback entry. */
     template <typename Key>
     void putCallback(void (*callback)(JSTracer *trc, Key *key, void *data), Key *key, void *data) {
         putFromAnyThread(bufferGeneric, CallbackRef<Key>(callback, key, data));
     }
 
+    gcstats::Statistics& stats();
+
     /* Methods to mark the source of all edges in the store buffer. */
     void markAll(JSTracer *trc);
     void markValues(JSTracer *trc)            { bufferVal.mark(this, trc); }
     void markCells(JSTracer *trc)             { bufferCell.mark(this, trc); }
     void markSlots(JSTracer *trc)             { bufferSlot.mark(this, trc); }
     void markWholeCells(JSTracer *trc)        { bufferWholeCell.mark(this, trc); }
     void markRelocatableValues(JSTracer *trc) { bufferRelocVal.mark(this, trc); }
     void markRelocatableCells(JSTracer *trc)  { bufferRelocCell.mark(this, trc); }