author | Steve Fink <sfink@mozilla.com> |
Tue, 04 Nov 2014 08:34:56 -0800 | |
changeset 214011 | 7a9f3b3b30068a6bc78ce1d25dc14af2a79ba90c |
parent 213956 | 69bcf4fef10328df08319d78659888777e820066 |
child 214012 | d6aceb31282a45692389874e0c1d3678f140da60 |
push id | 27771 |
push user | ryanvm@gmail.com |
push date | Wed, 05 Nov 2014 19:04:24 +0000 |
treeherder | mozilla-central@305b4fecce99 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jonco |
bugs | 1088831 |
milestone | 36.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
|
--- 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); }