Bug 1477761 - Fix sketchy timestamp computation for unlimited slice budget r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 26 Jul 2018 17:23:18 +0100
changeset 428612 764e0cce4cd1fbb79213252aec99a51f75c7f0be
parent 428611 4534ae540e86d686f29098cbcc2f932a6b83117b
child 428613 5e38f6929994ccd7905cbc0f62f057ef49d28d8a
push id34337
push userncsoregi@mozilla.com
push dateThu, 26 Jul 2018 21:58:45 +0000
treeherdermozilla-central@8f2f847b2f9d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1477761
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 1477761 - Fix sketchy timestamp computation for unlimited slice budget r=sfink
js/public/SliceBudget.h
js/src/gc/GC.cpp
js/src/vm/Initialization.cpp
--- a/js/public/SliceBudget.h
+++ b/js/public/SliceBudget.h
@@ -32,23 +32,17 @@ 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)
 {
-    const mozilla::TimeStamp &UnlimitedDeadline() const {
-        mozilla::recordreplay::AutoPassThroughThreadEvents pt;
-        static const mozilla::TimeStamp unlimitedDeadline =
-            mozilla::TimeStamp::Now() + mozilla::TimeDuration::Forever();
-        return unlimitedDeadline;
-    }
-
+    static mozilla::TimeStamp unlimitedDeadline;
     static const intptr_t unlimitedStartCounter = INTPTR_MAX;
 
     bool checkOverBudget();
 
     SliceBudget();
 
   public:
     // Memory of the originally requested budget. If isUnlimited, neither of
@@ -70,32 +64,35 @@ class JS_PUBLIC_API(SliceBudget)
 
     /* Instantiate as SliceBudget(TimeBudget(n)). */
     explicit SliceBudget(TimeBudget time);
 
     /* Instantiate as SliceBudget(WorkBudget(n)). */
     explicit SliceBudget(WorkBudget work);
 
     void makeUnlimited() {
-        deadline = UnlimitedDeadline();
+        MOZ_ASSERT(unlimitedDeadline);
+        deadline = unlimitedDeadline;
         counter = unlimitedStartCounter;
     }
 
     void step(intptr_t amt = 1) {
         counter -= amt;
     }
 
     bool isOverBudget() {
         if (counter > 0)
             return false;
         return checkOverBudget();
     }
 
     bool isWorkBudget() const { return deadline.IsNull(); }
     bool isTimeBudget() const { return !deadline.IsNull() && !isUnlimited(); }
-    bool isUnlimited() const { return deadline == UnlimitedDeadline(); }
+    bool isUnlimited() const { return deadline == unlimitedDeadline; }
 
     int describe(char* buffer, size_t maxlen) const;
+
+    static void Init();
 };
 
 } // namespace js
 
 #endif /* js_SliceBudget_h */
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -3229,16 +3229,26 @@ void
 ArenaLists::queueForegroundThingsForSweep()
 {
     gcShapeArenasToUpdate = arenaListsToSweep(AllocKind::SHAPE);
     gcAccessorShapeArenasToUpdate = arenaListsToSweep(AllocKind::ACCESSOR_SHAPE);
     gcObjectGroupArenasToUpdate = arenaListsToSweep(AllocKind::OBJECT_GROUP);
     gcScriptArenasToUpdate = arenaListsToSweep(AllocKind::SCRIPT);
 }
 
+mozilla::TimeStamp SliceBudget::unlimitedDeadline;
+
+void
+SliceBudget::Init()
+{
+    MOZ_ASSERT(!unlimitedDeadline);
+    uint64_t oneYearsInSeconds = 365 * 24 * 60 * 60;
+    unlimitedDeadline = ReallyNow() + mozilla::TimeDuration::FromSeconds(100 * oneYearsInSeconds);
+}
+
 SliceBudget::SliceBudget()
   : timeBudget(UnlimitedTimeBudget), workBudget(UnlimitedWorkBudget)
 {
     makeUnlimited();
 }
 
 SliceBudget::SliceBudget(TimeBudget time)
   : timeBudget(time), workBudget(UnlimitedWorkBudget)
--- a/js/src/vm/Initialization.cpp
+++ b/js/src/vm/Initialization.cpp
@@ -83,16 +83,18 @@ JS::detail::InitWithFailureDiagnostic(bo
                "JS_SetICUMemoryFunctions or JS::SetGMPMemoryFunctions");
     MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
                "how do we have live runtimes before JS_Init?");
 
     libraryInitState = InitState::Initializing;
 
     PRMJ_NowInit();
 
+    js::SliceBudget::Init();
+
     // The first invocation of `ProcessCreation` creates a temporary thread
     // and crashes if that fails, i.e. because we're out of memory. To prevent
     // that from happening at some later time, get it out of the way during
     // startup.
     mozilla::TimeStamp::ProcessCreation();
 
 #ifdef DEBUG
     CheckMessageParameterCounts();