Bug 1207696 Part 5b - Don't keep track of times or page fault counts in GC and helper thread activity when recording or replaying, r=sfink.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 23 Jul 2018 14:35:53 +0000
changeset 427870 1f2c6099f8521eb3e08ff6e1a90715e19af2be8a
parent 427869 eec76ff04ff90412415fd40c3d29c0c23d25f8d9
child 427871 ab179dae314c3435a4fcd35b5a0e46b57119af95
push id34320
push userrgurzau@mozilla.com
push dateTue, 24 Jul 2018 09:50:07 +0000
treeherdermozilla-central@1e5fa52a612e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1207696
milestone63.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 1207696 Part 5b - Don't keep track of times or page fault counts in GC and helper thread activity when recording or replaying, r=sfink.
dom/base/nsJSEnvironment.cpp
js/src/gc/GC.cpp
js/src/gc/Memory.cpp
js/src/gc/Nursery.cpp
js/src/gc/Statistics.cpp
js/src/vm/HelperThreads.cpp
js/src/vm/Time.h
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -281,16 +281,19 @@ FindExceptionStackForConsoleReport(nsPID
   }
 }
 
 } /* namespace xpc */
 
 static PRTime
 GetCollectionTimeDelta()
 {
+  if (recordreplay::IsRecordingOrReplaying()) {
+    return 0;
+  }
   PRTime now = PR_Now();
   if (sFirstCollectionTime) {
     return now - sFirstCollectionTime;
   }
   sFirstCollectionTime = now;
   return 0;
 }
 
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -6761,17 +6761,17 @@ GCRuntime::endCompactPhase()
 void
 GCRuntime::finishCollection()
 {
     assertBackgroundSweepingFinished();
     MOZ_ASSERT(marker.isDrained());
     marker.stop();
     clearBufferedGrayRoots();
 
-    auto currentTime = mozilla::TimeStamp::Now();
+    auto currentTime = ReallyNow();
     schedulingState.updateHighFrequencyMode(lastGCTime, currentTime, tunables);
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         if (zone->isCollecting()) {
             zone->changeGCState(Zone::Finished, Zone::NoGC);
             zone->notifyObservingDebuggers();
         }
 
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -281,16 +281,18 @@ MarkPagesInUse(void* p, size_t size)
         return;
 
     MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
 }
 
 size_t
 GetPageFaultCount()
 {
+    if (mozilla::recordreplay::IsRecordingOrReplaying())
+        return 0;
     PROCESS_MEMORY_COUNTERS pmc;
     if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
         return 0;
     return pmc.PageFaultCount;
 }
 
 void*
 AllocateMappedContent(int fd, size_t offset, size_t length, size_t alignment)
@@ -808,16 +810,18 @@ MarkPagesInUse(void* p, size_t size)
         return;
 
     MOZ_ASSERT(OffsetFromAligned(p, pageSize) == 0);
 }
 
 size_t
 GetPageFaultCount()
 {
+    if (mozilla::recordreplay::IsRecordingOrReplaying())
+        return 0;
     struct rusage usage;
     int err = getrusage(RUSAGE_SELF, &usage);
     if (err)
         return 0;
     return usage.ru_majflt;
 }
 
 void*
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -664,23 +664,23 @@ js::Nursery::maybeClearProfileDurations(
 {
     for (auto& duration : profileDurations_)
         duration = mozilla::TimeDuration();
 }
 
 inline void
 js::Nursery::startProfile(ProfileKey key)
 {
-    startTimes_[key] = TimeStamp::Now();
+    startTimes_[key] = ReallyNow();
 }
 
 inline void
 js::Nursery::endProfile(ProfileKey key)
 {
-    profileDurations_[key] = TimeStamp::Now() - startTimes_[key];
+    profileDurations_[key] = ReallyNow() - startTimes_[key];
     totalDurations_[key] += profileDurations_[key];
 }
 
 bool
 js::Nursery::needIdleTimeCollection() const {
     uint32_t threshold =
         runtime()->gc.tunables.nurseryFreeThresholdForIdleCollection();
     return minorGCRequested() || freeSpace() < threshold;
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -1046,17 +1046,17 @@ Statistics::beginSlice(const ZoneGCStats
     this->zoneStats = zoneStats;
 
     bool first = !runtime->gc.isIncrementalGCInProgress();
     if (first)
         beginGC(gckind);
 
     if (!slices_.emplaceBack(budget,
                              reason,
-                             TimeStamp::Now(),
+                             ReallyNow(),
                              GetPageFaultCount(),
                              runtime->gc.state()))
     {
         // If we are OOM, set a flag to indicate we have missing slice data.
         aborted = true;
         return;
     }
 
@@ -1078,17 +1078,17 @@ Statistics::beginSlice(const ZoneGCStats
 void
 Statistics::endSlice()
 {
     MOZ_ASSERT(phaseStack.empty() ||
                (phaseStack.length() == 1 && phaseStack[0] == Phase::MUTATOR));
 
     if (!aborted) {
         auto& slice = slices_.back();
-        slice.end = TimeStamp::Now();
+        slice.end = ReallyNow();
         slice.endFaults = GetPageFaultCount();
         slice.finalState = runtime->gc.state();
 
         writeLogMessage("end slice");
         TimeDuration sliceTime = slice.end - slice.start;
         runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(sliceTime));
         runtime->addTelemetry(JS_TELEMETRY_GC_RESET, slice.wasReset());
         if (slice.wasReset())
@@ -1241,17 +1241,17 @@ Statistics::resumePhases()
     suspendedPhases.popBack();
 
     while (!suspendedPhases.empty() &&
            suspendedPhases.back() != Phase::EXPLICIT_SUSPENSION &&
            suspendedPhases.back() != Phase::IMPLICIT_SUSPENSION)
     {
         Phase resumePhase = suspendedPhases.popCopy();
         if (resumePhase == Phase::MUTATOR)
-            timedGCTime += TimeStamp::Now() - timedGCStart;
+            timedGCTime += ReallyNow() - timedGCStart;
         recordPhaseBegin(resumePhase);
     }
 }
 
 void
 Statistics::beginPhase(PhaseKind phaseKind)
 {
     // No longer timing these phases. We should never see these.
@@ -1272,17 +1272,17 @@ Statistics::recordPhaseBegin(Phase phase
     // Guard against any other re-entry.
     MOZ_ASSERT(!phaseStartTimes[phase]);
 
     MOZ_ASSERT(phaseStack.length() < MAX_PHASE_NESTING);
 
     Phase current = currentPhase();
     MOZ_ASSERT(phases[phase].parent == current);
 
-    TimeStamp now = TimeStamp::Now();
+    TimeStamp now = ReallyNow();
 
     if (current != Phase::NONE) {
         MOZ_ASSERT(now >= phaseStartTimes[currentPhase()], "Inconsistent time data; see bug 1400153");
         if (now < phaseStartTimes[currentPhase()]) {
             now = phaseStartTimes[currentPhase()];
             aborted = true;
         }
     }
@@ -1294,17 +1294,17 @@ Statistics::recordPhaseBegin(Phase phase
 
 void
 Statistics::recordPhaseEnd(Phase phase)
 {
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime));
 
     MOZ_ASSERT(phaseStartTimes[phase]);
 
-    TimeStamp now = TimeStamp::Now();
+    TimeStamp now = ReallyNow();
 
     // Make sure this phase ends after it starts.
     MOZ_ASSERT(now >= phaseStartTimes[phase], "Inconsistent time data; see bug 1400153");
 
 #ifdef DEBUG
     // Make sure this phase ends after all of its children. Note that some
     // children might not have run in this instance, in which case they will
     // have run in a previous instance of this parent or not at all.
@@ -1378,26 +1378,26 @@ Statistics::recordParallelPhase(PhaseKin
         parallelTimes[phase] += duration;
         phase = phases[phase].parent;
     }
 }
 
 TimeStamp
 Statistics::beginSCC()
 {
-    return TimeStamp::Now();
+    return ReallyNow();
 }
 
 void
 Statistics::endSCC(unsigned scc, TimeStamp start)
 {
     if (scc >= sccTimes.length() && !sccTimes.resize(scc + 1))
         return;
 
-    sccTimes[scc] += TimeStamp::Now() - start;
+    sccTimes[scc] += ReallyNow() - start;
 }
 
 /*
  * MMU (minimum mutator utilization) is a measure of how much garbage collection
  * is affecting the responsiveness of the system. MMU measurements are given
  * with respect to a certain window size. If we report MMU(50ms) = 80%, then
  * that means that, for any 50ms window of time, at least 80% of the window is
  * devoted to the mutator. In other words, the GC is running for at most 20% of
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -1555,32 +1555,32 @@ TimeSince(TimeStamp prev)
     return now - prev;
 }
 
 void
 js::GCParallelTask::runFromMainThread(JSRuntime* rt)
 {
     assertNotStarted();
     MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(rt));
-    TimeStamp timeStart = TimeStamp::Now();
+    TimeStamp timeStart = ReallyNow();
     runTask();
     duration_ = TimeSince(timeStart);
 }
 
 void
 js::GCParallelTask::runFromHelperThread(AutoLockHelperThreadState& lock)
 {
     MOZ_ASSERT(isDispatched(lock));
 
     AutoSetContextRuntime ascr(runtime());
     gc::AutoSetThreadIsPerformingGC performingGC;
 
     {
         AutoUnlockHelperThreadState parallelSection(lock);
-        TimeStamp timeStart = TimeStamp::Now();
+        TimeStamp timeStart = ReallyNow();
         runTask();
         duration_ = TimeSince(timeStart);
     }
 
     setFinished(lock);
     HelperThreadState().notifyAll(GlobalHelperThreadState::CONSUMER, lock);
 }
 
--- a/js/src/vm/Time.h
+++ b/js/src/vm/Time.h
@@ -127,34 +127,40 @@ PRMJ_FormatTime(char* buf, int buflen, c
 #define MOZ_HAVE_RDTSC 1
 
 #if defined(_WIN32)
 
 #include <intrin.h>
 static __inline uint64_t
 ReadTimestampCounter(void)
 {
+    if (mozilla::recordreplay::IsRecordingOrReplaying())
+        return 0;
     return __rdtsc();
 }
 
 #elif defined(__i386__)
 
 static __inline__ uint64_t
 ReadTimestampCounter(void)
 {
+    if (mozilla::recordreplay::IsRecordingOrReplaying())
+        return 0;
     uint64_t x;
     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
     return x;
 }
 
 #elif defined(__x86_64__)
 
 static __inline__ uint64_t
 ReadTimestampCounter(void)
 {
+    if (mozilla::recordreplay::IsRecordingOrReplaying())
+        return 0;
     unsigned hi, lo;
     __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
     return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 );
 }
 
 #else
 
 #undef MOZ_HAVE_RDTSC