Backed out changeset c115f0bb2bfb (bug 1465505) spidermonkey bustages. CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Tue, 19 Jun 2018 06:48:03 +0300
changeset 479670 ef06853a18a59002945d9ebb29944296f9da2dcc
parent 479669 c115f0bb2bfbfc808f7a09a03f808aa80aeabfde
child 479671 245c6fe9938cd895ea56194c34d0bde72bfd995d
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1465505
milestone62.0a1
backs outc115f0bb2bfbfc808f7a09a03f808aa80aeabfde
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
Backed out changeset c115f0bb2bfb (bug 1465505) spidermonkey bustages. CLOSED TREE
js/public/SliceBudget.h
js/src/gc/GC.cpp
js/src/gc/GCRuntime.h
js/src/gc/Scheduling.h
js/src/gc/SliceBudget.cpp
js/src/jsfriendapi.cpp
js/src/moz.build
js/src/vm/Realm.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
--- a/js/public/SliceBudget.h
+++ b/js/public/SliceBudget.h
@@ -2,18 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_SliceBudget_h
 #define js_SliceBudget_h
 
-#include "mozilla/TimeStamp.h"
-
 #include <stdint.h>
 
 #include "jstypes.h"
 
 namespace js {
 
 struct JS_PUBLIC_API(TimeBudget)
 {
@@ -32,31 +30,31 @@ struct JS_PUBLIC_API(WorkBudget)
 /*
  * This class records how much work has been done in a given collection slice,
  * so that we can return before pausing for too long. Some slices are allowed
  * to run for unlimited time, and others are bounded. To reduce the number of
  * gettimeofday calls, we only check the time every 1000 operations.
  */
 class JS_PUBLIC_API(SliceBudget)
 {
-    static const mozilla::TimeStamp unlimitedDeadline;
+    static const int64_t unlimitedDeadline = INT64_MAX;
     static const intptr_t unlimitedStartCounter = INTPTR_MAX;
 
     bool checkOverBudget();
 
     SliceBudget();
 
   public:
     // Memory of the originally requested budget. If isUnlimited, neither of
     // these are in use. If deadline==0, then workBudget is valid. Otherwise
     // timeBudget is valid.
     TimeBudget timeBudget;
     WorkBudget workBudget;
 
-    mozilla::TimeStamp deadline;
+    int64_t deadline; /* in microseconds */
     intptr_t counter;
 
     static const intptr_t CounterReset = 1000;
 
     static const int64_t UnlimitedTimeBudget = -1;
     static const int64_t UnlimitedWorkBudget = -1;
 
     /* Use to create an unlimited budget. */
@@ -78,18 +76,18 @@ class JS_PUBLIC_API(SliceBudget)
     }
 
     bool isOverBudget() {
         if (counter > 0)
             return false;
         return checkOverBudget();
     }
 
-    bool isWorkBudget() const { return deadline.IsNull(); }
-    bool isTimeBudget() const { return !deadline.IsNull() && !isUnlimited(); }
+    bool isWorkBudget() const { return deadline == 0; }
+    bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); }
     bool isUnlimited() const { return deadline == unlimitedDeadline; }
 
     int describe(char* buffer, size_t maxlen) const;
 };
 
 } // namespace js
 
 #endif /* js_SliceBudget_h */
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -298,17 +298,17 @@ namespace TuningDefaults {
 
     /* no parameter */
     static const size_t ZoneAllocDelayBytes = 1024 * 1024;
 
     /* JSGC_DYNAMIC_HEAP_GROWTH */
     static const bool DynamicHeapGrowthEnabled = false;
 
     /* JSGC_HIGH_FREQUENCY_TIME_LIMIT */
-    static const auto HighFrequencyThresholdUsec = mozilla::TimeDuration::FromMicroseconds(1000000);
+    static const uint64_t HighFrequencyThresholdUsec = 1000000;
 
     /* JSGC_HIGH_FREQUENCY_LOW_LIMIT */
     static const uint64_t HighFrequencyLowLimitBytes = 100 * 1024 * 1024;
 
     /* JSGC_HIGH_FREQUENCY_HIGH_LIMIT */
     static const uint64_t HighFrequencyHighLimitBytes = 500 * 1024 * 1024;
 
     /* JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX */
@@ -339,18 +339,16 @@ namespace TuningDefaults {
     static const bool CompactingEnabled = true;
 
     /* JSGC_NURSERY_FREE_THRESHOLD_FOR_IDLE_COLLECTION */
     static const uint32_t NurseryFreeThresholdForIdleCollection =
         Nursery::NurseryChunkUsableSize / 4;
 
 }}} // namespace js::gc::TuningDefaults
 
-static const auto ONE_SECOND = mozilla::TimeDuration::FromSeconds(1);
-
 /*
  * We start to incremental collection for a zone when a proportion of its
  * threshold is reached. This is configured by the
  * JSGC_ALLOCATION_THRESHOLD_FACTOR and
  * JSGC_ALLOCATION_THRESHOLD_FACTOR_AVOID_INTERRUPT parameters.
  */
 static const double MinAllocationThresholdFactor = 0.9;
 
@@ -950,17 +948,17 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
     atomsZone(nullptr),
     stats_(rt),
     marker(rt),
     usage(nullptr),
     nextCellUniqueId_(LargestTaggedNullCellPointer + 1), // Ensure disjoint from null tagged pointers.
     numArenasFreeCommitted(0),
     verifyPreData(nullptr),
     chunkAllocationSinceLastGC(false),
-    lastGCTime(mozilla::TimeStamp::Now()),
+    lastGCTime(PRMJ_Now()),
     mode(TuningDefaults::Mode),
     numActiveZoneIters(0),
     cleanUpEverything(false),
     grayBufferState(GCRuntime::GrayBufferState::Unused),
     grayBitsValid(false),
     majorGCTriggerReason(JS::gcreason::NO_REASON),
     fullGCForAtomsRequested_(false),
     minorGCNumber(0),
@@ -1411,17 +1409,17 @@ GCSchedulingTunables::setParameter(JSGCP
     switch(key) {
       case JSGC_MAX_BYTES:
         gcMaxBytes_ = value;
         break;
       case JSGC_MAX_NURSERY_BYTES:
         gcMaxNurseryBytes_ = value;
         break;
       case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
-        highFrequencyThresholdUsec_ = mozilla::TimeDuration::FromMilliseconds(value);
+        highFrequencyThresholdUsec_ = value * PRMJ_USEC_PER_MSEC;
         break;
       case JSGC_HIGH_FREQUENCY_LOW_LIMIT: {
         uint64_t newLimit = (uint64_t)value * 1024 * 1024;
         if (newLimit == UINT64_MAX)
             return false;
         setHighFrequencyLowLimit(newLimit);
         break;
       }
@@ -1695,17 +1693,17 @@ GCRuntime::getParameter(JSGCParamKey key
         } else {
             MOZ_RELEASE_ASSERT(defaultTimeBudget_ >= 0);
             MOZ_RELEASE_ASSERT(defaultTimeBudget_ <= UINT32_MAX);
             return uint32_t(defaultTimeBudget_);
         }
       case JSGC_MARK_STACK_LIMIT:
         return marker.maxCapacity();
       case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
-        return tunables.highFrequencyThresholdUsec().ToMilliseconds();
+        return tunables.highFrequencyThresholdUsec() / PRMJ_USEC_PER_MSEC;
       case JSGC_HIGH_FREQUENCY_LOW_LIMIT:
         return tunables.highFrequencyLowLimitBytes() / 1024 / 1024;
       case JSGC_HIGH_FREQUENCY_HIGH_LIMIT:
         return tunables.highFrequencyHighLimitBytes() / 1024 / 1024;
       case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX:
         return uint32_t(tunables.highFrequencyHeapGrowthMax() * 100);
       case JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN:
         return uint32_t(tunables.highFrequencyHeapGrowthMin() * 100);
@@ -2139,17 +2137,17 @@ GCRuntime::shouldCompact()
         return false;
 
     if (initialReason == JS::gcreason::USER_INACTIVE ||
         initialReason == JS::gcreason::MEM_PRESSURE)
     {
         return true;
     }
 
-    return !isIncremental || rt->lastAnimationTime.ref() + ONE_SECOND < mozilla::TimeStamp::Now();
+    return !isIncremental || rt->lastAnimationTime + PRMJ_USEC_PER_SEC < PRMJ_Now();
 }
 
 bool
 GCRuntime::isCompactingGCEnabled() const
 {
     return compactingEnabled && rt->mainContextFromOwnThread()->compactingDisabledCount == 0;
 }
 
@@ -3255,28 +3253,28 @@ SliceBudget::SliceBudget()
 
 SliceBudget::SliceBudget(TimeBudget time)
   : timeBudget(time), workBudget(UnlimitedWorkBudget)
 {
     if (time.budget < 0) {
         makeUnlimited();
     } else {
         // Note: TimeBudget(0) is equivalent to WorkBudget(CounterReset).
-        deadline = mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromMilliseconds(time.budget);
+        deadline = PRMJ_Now() + time.budget * PRMJ_USEC_PER_MSEC;
         counter = CounterReset;
     }
 }
 
 SliceBudget::SliceBudget(WorkBudget work)
   : timeBudget(UnlimitedTimeBudget), workBudget(work)
 {
     if (work.budget < 0) {
         makeUnlimited();
     } else {
-        deadline = mozilla::TimeStamp();
+        deadline = 0;
         counter = work.budget;
     }
 }
 
 int
 SliceBudget::describe(char* buffer, size_t maxlen) const
 {
     if (isUnlimited())
@@ -3285,17 +3283,17 @@ SliceBudget::describe(char* buffer, size
         return snprintf(buffer, maxlen, "work(%" PRId64 ")", workBudget.budget);
     else
         return snprintf(buffer, maxlen, "%" PRId64 "ms", timeBudget.budget);
 }
 
 bool
 SliceBudget::checkOverBudget()
 {
-    bool over = mozilla::TimeStamp::Now() >= deadline;
+    bool over = PRMJ_Now() >= deadline;
     if (!over)
         counter = CounterReset;
     return over;
 }
 
 void
 GCRuntime::requestMajorGC(JS::gcreason::Reason reason)
 {
@@ -4087,30 +4085,29 @@ GCRuntime::purgeRuntime()
     if (auto cache = rt->maybeThisRuntimeSharedImmutableStrings())
         cache->purge();
 
     MOZ_ASSERT(unmarkGrayStack.empty());
     unmarkGrayStack.clearAndFree();
 }
 
 bool
-GCRuntime::shouldPreserveJITCode(Realm* realm, const mozilla::TimeStamp &currentTime,
+GCRuntime::shouldPreserveJITCode(Realm* realm, int64_t currentTime,
                                  JS::gcreason::Reason reason, bool canAllocateMoreCode)
 {
-
     if (cleanUpEverything)
         return false;
     if (!canAllocateMoreCode)
         return false;
 
     if (alwaysPreserveCode)
         return true;
     if (realm->preserveJitCode())
         return true;
-    if (realm->lastAnimationTime.ref() + ONE_SECOND >= currentTime)
+    if (realm->lastAnimationTime + PRMJ_USEC_PER_SEC >= currentTime)
         return true;
     if (reason == JS::gcreason::DEBUG_GC)
         return true;
 
     return false;
 }
 
 #ifdef DEBUG
@@ -4276,17 +4273,17 @@ GCRuntime::prepareZonesForCollection(JS:
         for (auto i : AllAllocKinds())
             MOZ_ASSERT(!zone->arenas.arenaListsToSweep(i));
     }
 #endif
 
     *isFullOut = true;
     bool any = false;
 
-    auto currentTime = mozilla::TimeStamp::Now();
+    int64_t currentTime = PRMJ_Now();
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         /* Set up which zones will be collected. */
         if (ShouldCollectZone(zone, reason)) {
             MOZ_ASSERT(zone->canCollect());
             any = true;
             zone->changeGCState(Zone::NoGC, Zone::Mark);
         } else {
@@ -6831,17 +6828,17 @@ GCRuntime::endCompactPhase()
 void
 GCRuntime::finishCollection()
 {
     assertBackgroundSweepingFinished();
     MOZ_ASSERT(marker.isDrained());
     marker.stop();
     clearBufferedGrayRoots();
 
-    auto currentTime = mozilla::TimeStamp::Now();
+    uint64_t currentTime = PRMJ_Now();
     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/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef gc_GCRuntime_h
 #define gc_GCRuntime_h
 
 #include "mozilla/Atomics.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/Maybe.h"
-#include "mozilla/TimeStamp.h"
 
 #include "gc/ArenaList.h"
 #include "gc/AtomMarking.h"
 #include "gc/GCHelperState.h"
 #include "gc/GCMarker.h"
 #include "gc/GCParallelTask.h"
 #include "gc/Nursery.h"
 #include "gc/Scheduling.h"
@@ -563,17 +562,17 @@ class GCRuntime
     friend class AutoCallGCCallbacks;
     void maybeCallGCCallback(JSGCStatus status);
 
     void pushZealSelectedObjects();
     void purgeRuntime();
     MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoTraceSession& session);
     bool prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut,
                                    AutoLockForExclusiveAccess& lock);
-    bool shouldPreserveJITCode(JS::Realm* realm, const mozilla::TimeStamp &currentTime,
+    bool shouldPreserveJITCode(JS::Realm* realm, int64_t currentTime,
                                JS::gcreason::Reason reason, bool canAllocateMoreCode);
     void traceRuntimeForMajorGC(JSTracer* trc, AutoTraceSession& session);
     void traceRuntimeAtoms(JSTracer* trc, AutoLockForExclusiveAccess& lock);
     void traceKeptAtoms(JSTracer* trc);
     void traceRuntimeCommon(JSTracer* trc, TraceOrMarkRuntime traceOrMark,
                             AutoTraceSession& session);
     void maybeDoCycleCollection();
     void markCompartments();
@@ -711,17 +710,17 @@ class GCRuntime
     /*
      * Number of the committed arenas in all GC chunks including empty chunks.
      */
     mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> numArenasFreeCommitted;
     MainThreadData<VerifyPreTracer*> verifyPreData;
 
   private:
     UnprotectedData<bool> chunkAllocationSinceLastGC;
-    MainThreadData<mozilla::TimeStamp> lastGCTime;
+    MainThreadData<int64_t> lastGCTime;
 
     /*
      * JSGC_MODE
      * prefs: javascript.options.mem.gc_per_zone and
      *   javascript.options.mem.gc_incremental.
      */
     MainThreadData<JSGCMode> mode;
 
--- a/js/src/gc/Scheduling.h
+++ b/js/src/gc/Scheduling.h
@@ -382,19 +382,19 @@ class GCSchedulingTunables
      * tunables that make GC non-deterministic.
      */
     MainThreadData<bool> dynamicHeapGrowthEnabled_;
 
     /*
      * JSGC_HIGH_FREQUENCY_TIME_LIMIT
      *
      * We enter high-frequency mode if we GC a twice within this many
-     * microseconds.
+     * microseconds. This value is stored directly in microseconds.
      */
-    MainThreadData<mozilla::TimeDuration> highFrequencyThresholdUsec_;
+    MainThreadData<uint64_t> highFrequencyThresholdUsec_;
 
     /*
      * JSGC_HIGH_FREQUENCY_LOW_LIMIT
      * JSGC_HIGH_FREQUENCY_HIGH_LIMIT
      * JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX
      * JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN
      *
      * When in the |highFrequencyGC| mode, these parameterize the per-zone
@@ -443,17 +443,17 @@ class GCSchedulingTunables
     size_t gcMaxBytes() const { return gcMaxBytes_; }
     size_t maxMallocBytes() const { return maxMallocBytes_; }
     size_t gcMaxNurseryBytes() const { return gcMaxNurseryBytes_; }
     size_t gcZoneAllocThresholdBase() const { return gcZoneAllocThresholdBase_; }
     double allocThresholdFactor() const { return allocThresholdFactor_; }
     double allocThresholdFactorAvoidInterrupt() const { return allocThresholdFactorAvoidInterrupt_; }
     size_t zoneAllocDelayBytes() const { return zoneAllocDelayBytes_; }
     bool isDynamicHeapGrowthEnabled() const { return dynamicHeapGrowthEnabled_; }
-    const mozilla::TimeDuration &highFrequencyThresholdUsec() const { return highFrequencyThresholdUsec_; }
+    uint64_t highFrequencyThresholdUsec() const { return highFrequencyThresholdUsec_; }
     uint64_t highFrequencyLowLimitBytes() const { return highFrequencyLowLimitBytes_; }
     uint64_t highFrequencyHighLimitBytes() const { return highFrequencyHighLimitBytes_; }
     double highFrequencyHeapGrowthMax() const { return highFrequencyHeapGrowthMax_; }
     double highFrequencyHeapGrowthMin() const { return highFrequencyHeapGrowthMin_; }
     double lowFrequencyHeapGrowth() const { return lowFrequencyHeapGrowth_; }
     bool isDynamicMarkSliceEnabled() const { return dynamicMarkSliceEnabled_; }
     unsigned minEmptyChunkCount(const AutoLockGC&) const { return minEmptyChunkCount_; }
     unsigned maxEmptyChunkCount() const { return maxEmptyChunkCount_; }
@@ -488,20 +488,20 @@ class GCSchedulingState
 
   public:
     GCSchedulingState()
       : inHighFrequencyGCMode_(false)
     {}
 
     bool inHighFrequencyGCMode() const { return inHighFrequencyGCMode_; }
 
-    void updateHighFrequencyMode(const mozilla::TimeStamp &lastGCTime, const mozilla::TimeStamp &currentTime,
+    void updateHighFrequencyMode(uint64_t lastGCTime, uint64_t currentTime,
                                  const GCSchedulingTunables& tunables) {
         inHighFrequencyGCMode_ =
-            tunables.isDynamicHeapGrowthEnabled() && !lastGCTime.IsNull() &&
+            tunables.isDynamicHeapGrowthEnabled() && lastGCTime &&
             lastGCTime + tunables.highFrequencyThresholdUsec() > currentTime;
     }
 };
 
 class MemoryCounter
 {
     // Bytes counter to measure memory pressure for GC scheduling. It counts
     // upwards from zero.
deleted file mode 100644
--- a/js/src/gc/SliceBudget.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "js/SliceBudget.h"
-
-namespace js {
-    const mozilla::TimeStamp SliceBudget::unlimitedDeadline = mozilla::TimeStamp() + mozilla::TimeDuration::Forever();
-}
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsfriendapi.h"
 
 #include "mozilla/Atomics.h"
 #include "mozilla/PodOperations.h"
-#include "mozilla/TimeStamp.h"
 
 #include <stdint.h>
 
 #ifdef ENABLE_BIGINT
 #include "builtin/BigInt.h"
 #endif
 #include "builtin/Promise.h"
 #include "builtin/TestingFunctions.h"
@@ -414,17 +413,17 @@ js::AssertSameCompartment(JSObject* objA
 {
     MOZ_ASSERT(objA->compartment() == objB->compartment());
 }
 #endif
 
 JS_FRIEND_API(void)
 js::NotifyAnimationActivity(JSObject* obj)
 {
-    auto timeNow = mozilla::TimeStamp::Now();
+    int64_t timeNow = PRMJ_Now();
     obj->realm()->lastAnimationTime = timeNow;
     obj->runtimeFromMainThread()->lastAnimationTime = timeNow;
 }
 
 JS_FRIEND_API(uint32_t)
 js::GetObjectSlotSpan(JSObject* obj)
 {
     return obj->as<NativeObject>().slotSpan();
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -218,17 +218,16 @@ UNIFIED_SOURCES += [
     'gc/Barrier.cpp',
     'gc/GC.cpp',
     'gc/GCTrace.cpp',
     'gc/Marking.cpp',
     'gc/Memory.cpp',
     'gc/Nursery.cpp',
     'gc/PublicIterators.cpp',
     'gc/RootMarking.cpp',
-    'gc/SliceBudget.cpp',
     'gc/Statistics.cpp',
     'gc/Tracer.cpp',
     'gc/Verifier.cpp',
     'gc/WeakMap.cpp',
     'gc/WeakMapPtr.cpp',
     'gc/Zone.cpp',
     'irregexp/NativeRegExpMacroAssembler.cpp',
     'irregexp/RegExpAST.cpp',
--- a/js/src/vm/Realm.h
+++ b/js/src/vm/Realm.h
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_Realm_h
 #define vm_Realm_h
 
 #include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/TimeStamp.h"
 #include "mozilla/Tuple.h"
 #include "mozilla/Variant.h"
 #include "mozilla/XorShift128PlusRNG.h"
 
 #include <stddef.h>
 
 #include "gc/Barrier.h"
 #include "gc/Zone.h"
@@ -416,17 +415,17 @@ class JS::Realm : public JS::shadow::Rea
 
     /*
      * Lazily initialized script source object to use for scripts cloned
      * from the self-hosting global.
      */
     js::ReadBarrieredScriptSourceObject selfHostingScriptSource { nullptr };
 
     // Last time at which an animation was played for this realm.
-    js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
+    int64_t lastAnimationTime = 0;
 
     /*
      * For generational GC, record whether a write barrier has added this
      * realm's global to the store buffer since the last minor GC.
      *
      * This is used to avoid calling into the VM every time a nursery object is
      * written to a property of the global.
      */
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -164,16 +164,17 @@ JSRuntime::JSRuntime(JSRuntime* parentRu
     jitSupportsFloatingPoint(false),
     jitSupportsUnalignedAccesses(false),
     jitSupportsSimd(false),
     offthreadIonCompilationEnabled_(true),
     parallelParsingEnabled_(true),
     autoWritableJitCodeActive_(false),
     oomCallback(nullptr),
     debuggerMallocSizeOf(ReturnZeroSize),
+    lastAnimationTime(0),
     performanceMonitoring_(),
     stackFormat_(parentRuntime ? js::StackFormat::Default
                                : js::StackFormat::SpiderMonkey),
     wasmInstances(mutexid::WasmRuntimeInstances),
     moduleResolveHook(),
     moduleMetadataHook()
 {
     JS_COUNT_CTOR(JSRuntime);
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -11,17 +11,16 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/DoublyLinkedList.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MaybeOneOf.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/ThreadLocal.h"
-#include "mozilla/TimeStamp.h"
 #include "mozilla/Vector.h"
 
 #include <algorithm>
 #include <setjmp.h>
 
 #include "builtin/AtomicsObject.h"
 #include "builtin/intl/SharedIntlData.h"
 #include "builtin/Promise.h"
@@ -888,17 +887,17 @@ struct JSRuntime : public js::MallocProv
 
     /*
      * Debugger.Memory functions like takeCensus use this embedding-provided
      * function to assess the size of malloc'd blocks of memory.
      */
     js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
 
     /* Last time at which an animation was played for this runtime. */
-    js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
+    mozilla::Atomic<int64_t> lastAnimationTime;
 
   private:
     js::MainThreadData<js::PerformanceMonitoring> performanceMonitoring_;
   public:
     js::PerformanceMonitoring& performanceMonitoring() { return performanceMonitoring_.ref(); }
 
   private:
     /* The stack format for the current runtime.  Only valid on non-child