diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index bc897c8bc469..af9602d1a232 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -27,7 +27,6 @@ using namespace js::gc; using namespace js::gcstats; using mozilla::PodArrayZero; -using mozilla::PodZero; /* Except for the first and last, slices of less than 10ms are not reported. */ static const int64_t SLICE_MIN_REPORT_TIME = 10 * PRMJ_USEC_PER_MSEC; @@ -284,7 +283,6 @@ struct PhaseInfo static const Phase PHASE_NO_PARENT = PHASE_LIMIT; static const PhaseInfo phases[] = { - { PHASE_MUTATOR, "Mutator Running", PHASE_NO_PARENT }, { PHASE_GC_BEGIN, "Begin Callback", PHASE_NO_PARENT }, { PHASE_WAIT_BACKGROUND_THREAD, "Wait Background Thread", PHASE_NO_PARENT }, { PHASE_MARK_DISCARD_CODE, "Mark Discard Code", PHASE_NO_PARENT }, @@ -328,9 +326,6 @@ static const PhaseInfo phases[] = { { PHASE_COMPACT_UPDATE, "Compact Update", PHASE_COMPACT, }, { PHASE_COMPACT_UPDATE_GRAY, "Compact Update Gray", PHASE_COMPACT_UPDATE, }, { PHASE_GC_END, "End Callback", PHASE_NO_PARENT }, - { PHASE_MINOR_GC, "Minor GC", PHASE_NO_PARENT }, - { PHASE_COMPACT_STOREBUFFER_IN_MINOR_GC, "Compact Store Buffers", PHASE_MINOR_GC }, - { PHASE_COMPACT_STOREBUFFER_NO_PARENT, "Compact Store Buffers (toplevel)", PHASE_NO_PARENT }, { PHASE_LIMIT, nullptr, PHASE_NO_PARENT } }; @@ -390,8 +385,6 @@ Statistics::formatData(StatisticsSerializer &ss, uint64_t timestamp) 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("Store Buffer Overflows", "%d", "", counts[STAT_STOREBUFFER_OVERFLOW]); ss.appendNumber("MMU (20ms)", "%d", "%", int(mmu20 * 100)); ss.appendNumber("MMU (50ms)", "%d", "%", int(mmu50 * 100)); ss.appendDecimal("SCC Sweep Total", "ms", t(sccTotal)); @@ -483,8 +476,6 @@ Statistics::formatDescription() Zones Collected: %d of %d\n\ Compartments Collected: %d of %d\n\ MinorGCs since last GC: %d\n\ - Store Buffer Compactions: %d\n\ - Store Buffer Overflows: %d\n\ MMU 20ms:%.1f%%; 50ms:%.1f%%\n\ SCC Sweep Total (MaxPause): %.3fms (%.3fms)\n\ HeapSize: %.3f MiB\n\ @@ -500,8 +491,6 @@ Statistics::formatDescription() zoneStats.collectedZoneCount, zoneStats.zoneCount, zoneStats.collectedCompartmentCount, zoneStats.compartmentCount, counts[STAT_MINOR_GC], - counts[STAT_COMPACT_STOREBUFFER], - counts[STAT_STOREBUFFER_OVERFLOW], mmu20 * 100., mmu50 * 100., t(sccTotal), t(sccLongest), double(preBytes) / 1024. / 1024., @@ -644,8 +633,6 @@ Statistics::Statistics(JSRuntime *rt) fullFormat(false), gcDepth(0), nonincrementalReason(nullptr), - timingMutator(false), - timedGCStart(0), preBytes(0), maxPauseInInterval(0), phaseNestingDepth(0), @@ -653,8 +640,6 @@ Statistics::Statistics(JSRuntime *rt) { PodArrayZero(phaseTotals); PodArrayZero(counts); - PodArrayZero(phaseStartTimes); - PodArrayZero(phaseTimes); char *env = getenv("MOZ_GCTIMER"); if (!env || strcmp(env, "none") == 0) { @@ -738,6 +723,9 @@ Statistics::printStats() void Statistics::beginGC(JSGCInvocationKind kind) { + PodArrayZero(phaseStartTimes); + PodArrayZero(phaseTimes); + slices.clearAndFree(); sccTimes.clearAndFree(); gckind = kind; @@ -779,11 +767,6 @@ Statistics::endGC() if (fp) printStats(); - - // Clear the timers at the end of a GC because we accumulate time for some - // phases (eg storebuffer compaction) during the mutator's run. - PodZero(&phaseStartTimes[PHASE_GC_BEGIN], PHASE_LIMIT - PHASE_GC_BEGIN); - PodZero(&phaseTimes[PHASE_GC_BEGIN], PHASE_LIMIT - PHASE_GC_BEGIN); } void @@ -840,58 +823,17 @@ Statistics::endSlice() PodArrayZero(counts); } -void -Statistics::startTimingMutator() -{ - MOZ_ASSERT(!timingMutator); - - // Should only be called from outside of GC - MOZ_ASSERT(phaseNestingDepth == 0); - - timingMutator = true; - timedGCTime = 0; - phaseStartTimes[PHASE_MUTATOR] = 0; - phaseTimes[PHASE_MUTATOR] = 0; - timedGCStart = 0; - - beginPhase(PHASE_MUTATOR); -} - -void -Statistics::stopTimingMutator(double &mutator_ms, double &gc_ms) -{ - MOZ_ASSERT(timingMutator); - - // Should only be called from outside of GC - MOZ_ASSERT(phaseNestingDepth == 1 && phaseNesting[0] == PHASE_MUTATOR); - - endPhase(PHASE_MUTATOR); - mutator_ms = t(phaseTimes[PHASE_MUTATOR]); - gc_ms = t(timedGCTime); - timingMutator = false; -} - void Statistics::beginPhase(Phase phase) { /* Guard against re-entry */ MOZ_ASSERT(!phaseStartTimes[phase]); - if (timingMutator) { - if (phaseNestingDepth == 1 && phaseNesting[0] == PHASE_MUTATOR) { - endPhase(PHASE_MUTATOR); - timedGCStart = PRMJ_Now(); - } - } - #ifdef DEBUG MOZ_ASSERT(phases[phase].index == phase); Phase parent = phaseNestingDepth ? phaseNesting[phaseNestingDepth - 1] : PHASE_NO_PARENT; MOZ_ASSERT(phaseNestingDepth < MAX_NESTING); MOZ_ASSERT_IF(gcDepth == 1, phases[phase].parent == parent); - MOZ_ASSERT_IF(phase == PHASE_COMPACT_STOREBUFFER_IN_MINOR_GC, parent == PHASE_MINOR_GC); - MOZ_ASSERT_IF(phase == PHASE_COMPACT_STOREBUFFER_NO_PARENT, parent == PHASE_NO_PARENT); - phaseNesting[phaseNestingDepth] = phase; phaseNestingDepth++; #endif @@ -904,19 +846,10 @@ Statistics::endPhase(Phase phase) { phaseNestingDepth--; - int64_t now = PRMJ_Now(); - int64_t t = now - phaseStartTimes[phase]; - if (!slices.empty()) - slices.back().phaseTimes[phase] += t; + int64_t t = PRMJ_Now() - phaseStartTimes[phase]; + slices.back().phaseTimes[phase] += t; phaseTimes[phase] += t; phaseStartTimes[phase] = 0; - - if (timingMutator) { - if (phaseNestingDepth == 0 && phase != PHASE_MUTATOR) { - timedGCTime += now - timedGCStart; - beginPhase(PHASE_MUTATOR); - } - } } void diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index cffc33a2b58b..933d449aefe3 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -27,7 +27,6 @@ class GCParallelTask; namespace gcstats { enum Phase { - PHASE_MUTATOR, PHASE_GC_BEGIN, PHASE_WAIT_BACKGROUND_THREAD, PHASE_MARK_DISCARD_CODE, @@ -71,9 +70,6 @@ enum Phase { PHASE_COMPACT_UPDATE, PHASE_COMPACT_UPDATE_GRAY, PHASE_GC_END, - PHASE_MINOR_GC, - PHASE_COMPACT_STOREBUFFER_IN_MINOR_GC, - PHASE_COMPACT_STOREBUFFER_NO_PARENT, PHASE_LIMIT }; @@ -83,13 +79,6 @@ enum Stat { STAT_DESTROY_CHUNK, STAT_MINOR_GC, - // Number of times the storebuffers were compacted - STAT_COMPACT_STOREBUFFER, - - // Number of times a 'put' into a storebuffer overflowed, triggering a - // compaction - STAT_STOREBUFFER_OVERFLOW, - STAT_LIMIT }; @@ -129,9 +118,6 @@ struct Statistics JS::gcreason::Reason reason); void endSlice(); - void startTimingMutator(); - void stopTimingMutator(double &mutator_ms, double &gc_ms); - void reset(const char *reason) { slices.back().resetReason = reason; } void nonincremental(const char *reason) { nonincrementalReason = reason; } @@ -193,13 +179,6 @@ struct Statistics /* Most recent time when the given phase started. */ int64_t phaseStartTimes[PHASE_LIMIT]; - /* Are we currently timing mutator vs GC time? */ - bool timingMutator; - - /* Bookkeeping for GC timings when timingMutator is true */ - int64_t timedGCStart; - int64_t timedGCTime; - /* Total time in a given phase for this GC. */ int64_t phaseTimes[PHASE_LIMIT]; @@ -215,10 +194,12 @@ struct Statistics /* Records the maximum GC pause in an API-controlled interval (in us). */ int64_t maxPauseInInterval; +#ifdef DEBUG /* Phases that are currently on stack. */ static const size_t MAX_NESTING = 8; Phase phaseNesting[MAX_NESTING]; - size_t phaseNestingDepth; +#endif + mozilla::DebugOnly phaseNestingDepth; /* Sweep times for SCCs of compartments. */ Vector sccTimes; diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index 23efde944266..0587e434f032 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -10,7 +10,6 @@ #include "mozilla/Assertions.h" -#include "gc/Statistics.h" #include "vm/ArgumentsObject.h" #include "vm/ForkJoin.h" @@ -20,12 +19,6 @@ using namespace js; using namespace js::gc; using mozilla::ReentrancyGuard; -gcstats::Statistics& -StoreBuffer::stats() -{ - return runtime_->gc.stats; -} - /*** Edges ***/ void @@ -100,8 +93,6 @@ StoreBuffer::MonoTypeBuffer::handleOverflow(StoreBuffer *owner) * Compact the buffer now, and if that fails to free enough space then * trigger a minor collection. */ - gcstats::AutoPhase ap(owner->stats(), gcstats::PHASE_COMPACT_STOREBUFFER_NO_PARENT); - owner->stats().count(gcstats::STAT_STOREBUFFER_OVERFLOW); compact(owner); if (isLowOnSpace()) owner->setAboutToOverflow(); @@ -110,10 +101,8 @@ StoreBuffer::MonoTypeBuffer::handleOverflow(StoreBuffer *owner) * A minor GC has already been triggered, so there's no point * compacting unless the buffer is totally full. */ - if (storage_->availableInCurrentChunk() < sizeof(T)) { - owner->stats().count(gcstats::STAT_STOREBUFFER_OVERFLOW); - maybeCompact(owner, gcstats::PHASE_COMPACT_STOREBUFFER_NO_PARENT); - } + if (storage_->availableInCurrentChunk() < sizeof(T)) + maybeCompact(owner); } } @@ -141,7 +130,6 @@ StoreBuffer::MonoTypeBuffer::compactRemoveDuplicates(StoreBuffer *owner) storage_->release(insert.mark()); duplicates.clear(); - owner->stats().count(gcstats::STAT_COMPACT_STOREBUFFER); } template @@ -155,13 +143,11 @@ StoreBuffer::MonoTypeBuffer::compact(StoreBuffer *owner) template void -StoreBuffer::MonoTypeBuffer::maybeCompact(StoreBuffer *owner, int phase) +StoreBuffer::MonoTypeBuffer::maybeCompact(StoreBuffer *owner) { MOZ_ASSERT(storage_); - if (storage_->used() != usedAtLastCompact_) { - gcstats::AutoPhase ap(owner->stats(), static_cast(phase)); + if (storage_->used() != usedAtLastCompact_) compact(owner); - } } template @@ -173,8 +159,7 @@ StoreBuffer::MonoTypeBuffer::mark(StoreBuffer *owner, JSTracer *trc) if (!storage_) return; - maybeCompact(owner, gcstats::PHASE_COMPACT_STOREBUFFER_IN_MINOR_GC); - + maybeCompact(owner); for (LifoAlloc::Enum e(*storage_); !e.empty(); e.popFront()) { T *edge = e.get(); edge->mark(trc); diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index 09276e8665a8..b5b19fb63457 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -22,10 +22,6 @@ namespace js { -namespace gcstats { -struct Statistics; -} - MOZ_NORETURN void CrashAtUnhandlableOOM(const char *reason); @@ -144,7 +140,7 @@ class StoreBuffer virtual void compact(StoreBuffer *owner); /* Compacts if any entries have been added since the last compaction. */ - void maybeCompact(StoreBuffer *owner, int phase); + void maybeCompact(StoreBuffer *owner); /* Add one item to the buffer. */ void put(StoreBuffer *owner, const T &t) { @@ -493,8 +489,6 @@ class StoreBuffer putFromAnyThread(bufferGeneric, CallbackRef(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); } diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 0428252db9b9..f092b5e116a6 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -503,10 +503,7 @@ js::gc::GCRuntime::endVerifyPostBarriers() if (!edges.init()) goto oom; trc->edges = &edges; - { - gcstats::AutoPhase ap(stats, gcstats::PHASE_MINOR_GC); - storeBuffer.markAll(trc); - } + storeBuffer.markAll(trc); /* Walk the heap to find any edges not the the |edges| set. */ trc->setTraceCallback(PostVerifierVisitEdge); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 7a10fdb64567..0c1f218a1d74 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -6282,7 +6282,6 @@ void GCRuntime::minorGC(JS::gcreason::Reason reason) { #ifdef JSGC_GENERATIONAL - gcstats::AutoPhase ap(stats, gcstats::PHASE_MINOR_GC); minorGCRequested = false; TraceLogger *logger = TraceLoggerForMainThread(rt); AutoTraceLog logMinorGC(logger, TraceLogger::MinorGC); @@ -6297,7 +6296,6 @@ GCRuntime::minorGC(JSContext *cx, JS::gcreason::Reason reason) // Alternate to the runtime-taking form above which allows marking type // objects as needing pretenuring. #ifdef JSGC_GENERATIONAL - gcstats::AutoPhase ap(stats, gcstats::PHASE_MINOR_GC); minorGCRequested = false; TraceLogger *logger = TraceLoggerForMainThread(rt); AutoTraceLog logMinorGC(logger, TraceLogger::MinorGC); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 223f7afbcbba..ea53b5a5842a 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -1669,43 +1669,6 @@ Quit(JSContext *cx, unsigned argc, jsval *vp) return false; } -static bool -StartTimingMutator(JSContext *cx, unsigned argc, jsval *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() > 0) { - JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, - JSSMSG_TOO_MANY_ARGS, "startTimingMutator"); - return false; - } - - cx->runtime()->gc.stats.startTimingMutator(); - args.rval().setUndefined(); - return true; -} - -static bool -StopTimingMutator(JSContext *cx, unsigned argc, jsval *vp) -{ - CallArgs args = CallArgsFromVp(argc, vp); - if (args.length() > 0) { - JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, - JSSMSG_TOO_MANY_ARGS, "stopTimingMutator"); - return false; - } - - double mutator_ms, gc_ms; - cx->runtime()->gc.stats.stopTimingMutator(mutator_ms, gc_ms); - double total_ms = mutator_ms + gc_ms; - if (total_ms > 0) { - fprintf(gOutFile, "Mutator: %.3fms (%.1f%%), GC: %.3fms (%.1f%%)\n", - mutator_ms, mutator_ms / total_ms * 100.0, gc_ms, gc_ms / total_ms * 100.0); - } - - args.rval().setUndefined(); - return true; -} - static const char * ToSource(JSContext *cx, MutableHandleValue vp, JSAutoByteString *bytes) { @@ -4310,14 +4273,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = { " Throw if the first two arguments are not the same (both +0 or both -0,\n" " both NaN, or non-zero and ===)."), - JS_FN_HELP("startTimingMutator", StartTimingMutator, 0, 0, -"startTimingMutator()", -" Start accounting time to mutator vs GC."), - - JS_FN_HELP("stopTimingMutator", StopTimingMutator, 0, 0, -"stopTimingMutator()", -" Stop accounting time to mutator vs GC and dump the results."), - JS_FN_HELP("throwError", ThrowError, 0, 0, "throwError()", " Throw an error from JS_ReportError."),