diff --git a/dom/base/OrderedTimeoutIterator.h b/dom/base/OrderedTimeoutIterator.h deleted file mode 100644 index de988047077e..000000000000 --- a/dom/base/OrderedTimeoutIterator.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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 mozilla_dom_OrderedTimeoutIterator_h__ -#define mozilla_dom_OrderedTimeoutIterator_h__ - -#include "mozilla/RefPtr.h" -#include "mozilla/dom/Timeout.h" -#include "mozilla/dom/TimeoutManager.h" - -namespace mozilla { -namespace dom { - -// This class implements and iterator which iterates the normal and tracking -// timeouts lists simultaneously in the mWhen order. -class MOZ_STACK_CLASS OrderedTimeoutIterator final { -public: - typedef TimeoutManager::Timeouts Timeouts; - typedef Timeouts::TimeoutList TimeoutList; - - OrderedTimeoutIterator(Timeouts& aNormalTimeouts, - Timeouts& aTrackingTimeouts) - : mNormalTimeouts(aNormalTimeouts.mTimeoutList), - mTrackingTimeouts(aTrackingTimeouts.mTimeoutList), - mNormalIter(mNormalTimeouts.getFirst()), - mTrackingIter(mTrackingTimeouts.getFirst()), - mKind(Kind::None), - mUpdateIteratorCalled(true) - { - } - - // Return the current timeout and move to the next one. - // Unless this is the first time calling Next(), you must call - // UpdateIterator() before calling this method. - Timeout* Next() - { - MOZ_ASSERT(mUpdateIteratorCalled); - MOZ_ASSERT_IF(mNormalIter, mNormalIter->isInList()); - MOZ_ASSERT_IF(mTrackingIter, mTrackingIter->isInList()); - - mUpdateIteratorCalled = false; - mKind = Kind::None; - Timeout* timeout = nullptr; - if (!mNormalIter) { - if (!mTrackingIter) { - // We have reached the end of both lists. Bail out! - return nullptr; - } else { - // We have reached the end of the normal timeout list, select the next - // tracking timeout. - timeout = mTrackingIter; - mKind = Kind::Tracking; - } - } else if (!mTrackingIter) { - // We have reached the end of the tracking timeout list, select the next - // normal timeout. - timeout = mNormalIter; - mKind = Kind::Normal; - } else { - // If we have a normal and a tracking timer, return the one with the - // smaller mWhen (and prefer the timeout with a lower ID in case they are - // equal.) Otherwise, return whichever iterator has an item left, - // preferring a non-tracking timeout again. Note that in practice, even - // if a web page calls setTimeout() twice in a row, it should get - // different mWhen values, so in practice we shouldn't fall back to - // comparing timeout IDs. - if (mNormalIter && mTrackingIter && - (mTrackingIter->When() < mNormalIter->When() || - (mTrackingIter->When() == mNormalIter->When() && - mTrackingIter->mTimeoutId < mNormalIter->mTimeoutId))) { - timeout = mTrackingIter; - mKind = Kind::Tracking; - } else if (mNormalIter) { - timeout = mNormalIter; - mKind = Kind::Normal; - } else if (mTrackingIter) { - timeout = mTrackingIter; - mKind = Kind::Tracking; - } - } - if (!timeout) { - // We didn't find any suitable iterator. This can happen for example - // when getNext() in UpdateIterator() returns nullptr and then Next() - // gets called. Bail out! - return nullptr; - } - - MOZ_ASSERT(mKind != Kind::None); - - // Record the current timeout we just found. - mCurrent = timeout; - MOZ_ASSERT(mCurrent); - - return mCurrent; - } - - // Prepare the iterator for the next call to Next(). - // This method can be called as many times as needed. Calling this more than - // once is helpful in cases where we expect the timeouts list has been - // modified before we got a chance to call Next(). - void UpdateIterator() - { - MOZ_ASSERT(mKind != Kind::None); - // Update the winning iterator to point to the next element. Also check to - // see if the other iterator is still valid, otherwise reset it to the - // beginning of the list. This is needed in case a timeout handler removes - // the timeout pointed to from one of our iterators. - if (mKind == Kind::Normal) { - mNormalIter = mCurrent->getNext(); - if (mTrackingIter && !mTrackingIter->isInList()) { - mTrackingIter = mTrackingTimeouts.getFirst(); - } - } else { - mTrackingIter = mCurrent->getNext(); - if (mNormalIter && !mNormalIter->isInList()) { - mNormalIter = mNormalTimeouts.getFirst(); - } - } - - mUpdateIteratorCalled = true; - } - - // This function resets the iterator to a defunct state. It should only be - // used when we want to forcefully sever all of the strong references this - // class holds. - void Clear() - { - // Release all strong references. - mNormalIter = nullptr; - mTrackingIter = nullptr; - mCurrent = nullptr; - mKind = Kind::None; - mUpdateIteratorCalled = true; - } - - // Returns true if the previous call to Next() picked a normal timeout. - // Cannot be called before Next() has been called. Note that the result of - // this method is only affected by Next() and not UpdateIterator(), so calling - // UpdateIterator() before calling this is allowed. - bool PickedNormalIter() const - { - MOZ_ASSERT(mKind != Kind::None); - return mKind == Kind::Normal; - } - - // Returns true if the previous call to Next() picked a tracking timeout. - // Cannot be called before Next() has been called. Note that the result of - // this method is only affected by Next() and not UpdateIterator(), so calling - // UpdateIterator() before calling this is allowed. - bool PickedTrackingIter() const - { - MOZ_ASSERT(mKind != Kind::None); - return mKind == Kind::Tracking; - } - -private: - TimeoutList& mNormalTimeouts; // The list of normal timeouts. - TimeoutList& mTrackingTimeouts; // The list of tracking timeouts. - RefPtr mNormalIter; // The iterator over the normal timeout list. - RefPtr mTrackingIter; // The iterator over the tracking timeout list. - RefPtr mCurrent; // The current timeout that Next() just found. - enum class Kind { Normal, Tracking, None }; - Kind mKind; // The kind of iterator picked the last time. - DebugOnly mUpdateIteratorCalled; // Whether we have called UpdateIterator() before calling Next(). -}; - -} -} - -#endif diff --git a/dom/base/Timeout.cpp b/dom/base/Timeout.cpp index e8e86d06bac6..038721be378d 100644 --- a/dom/base/Timeout.cpp +++ b/dom/base/Timeout.cpp @@ -19,8 +19,7 @@ Timeout::Timeout() mNestingLevel(0), mCleared(false), mRunning(false), - mIsInterval(false), - mIsTracking(false) + mIsInterval(false) { } diff --git a/dom/base/Timeout.h b/dom/base/Timeout.h index 8231bea12bac..bed821d8f615 100644 --- a/dom/base/Timeout.h +++ b/dom/base/Timeout.h @@ -104,9 +104,6 @@ public: // True if this is a repeating/interval timer bool mIsInterval; - - // True if this is a timeout coming from a tracking script - bool mIsTracking; }; } // namespace dom diff --git a/dom/base/TimeoutBudgetManager.cpp b/dom/base/TimeoutBudgetManager.cpp index d1f9baa2bcca..2a9b5022c0d5 100644 --- a/dom/base/TimeoutBudgetManager.cpp +++ b/dom/base/TimeoutBudgetManager.cpp @@ -11,9 +11,6 @@ namespace mozilla { namespace dom { -// Time between sampling timeout execution time. -const uint32_t kTelemetryPeriodMS = 1000; - /* static */ TimeoutBudgetManager& TimeoutBudgetManager::Get() { @@ -35,8 +32,7 @@ TimeoutBudgetManager::StopRecording() TimeDuration TimeoutBudgetManager::RecordExecution(const TimeStamp& aNow, - const Timeout* aTimeout, - bool aIsBackground) + const Timeout* aTimeout) { if (!mStart) { // If we've started a sync operation mStart might be null, in @@ -44,53 +40,7 @@ TimeoutBudgetManager::RecordExecution(const TimeStamp& aNow, return TimeDuration(); } - TimeDuration duration = aNow - mStart; - - if (aIsBackground) { - if (aTimeout->mIsTracking) { - mTelemetryData.mBackgroundTracking += duration; - } else { - mTelemetryData.mBackgroundNonTracking += duration; - } - } else { - if (aTimeout->mIsTracking) { - mTelemetryData.mForegroundTracking += duration; - } else { - mTelemetryData.mForegroundNonTracking += duration; - } - } - - return duration; -} - -void -TimeoutBudgetManager::Accumulate(Telemetry::HistogramID aId, - const TimeDuration& aSample) -{ - uint32_t sample = std::round(aSample.ToMilliseconds()); - if (sample) { - Telemetry::Accumulate(aId, sample); - } -} - -void -TimeoutBudgetManager::MaybeCollectTelemetry(const TimeStamp& aNow) -{ - if ((aNow - mLastCollection).ToMilliseconds() < kTelemetryPeriodMS) { - return; - } - - Accumulate(Telemetry::TIMEOUT_EXECUTION_FG_TRACKING_MS, - mTelemetryData.mForegroundTracking); - Accumulate(Telemetry::TIMEOUT_EXECUTION_FG_MS, - mTelemetryData.mForegroundNonTracking); - Accumulate(Telemetry::TIMEOUT_EXECUTION_BG_TRACKING_MS, - mTelemetryData.mBackgroundTracking); - Accumulate(Telemetry::TIMEOUT_EXECUTION_BG_MS, - mTelemetryData.mBackgroundNonTracking); - - mTelemetryData = TelemetryData(); - mLastCollection = aNow; + return aNow - mStart; } } // namespace dom diff --git a/dom/base/TimeoutBudgetManager.h b/dom/base/TimeoutBudgetManager.h index fc7eb0ede781..0de19e32cd4a 100644 --- a/dom/base/TimeoutBudgetManager.h +++ b/dom/base/TimeoutBudgetManager.h @@ -7,7 +7,6 @@ #ifndef mozilla_dom_timeoutbudgetmanager_h #define mozilla_dom_timeoutbudgetmanager_h -#include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" namespace mozilla { @@ -22,24 +21,11 @@ public: void StartRecording(const TimeStamp& aNow); void StopRecording(); TimeDuration RecordExecution(const TimeStamp& aNow, - const Timeout* aTimeout, - bool aIsBackground); - void MaybeCollectTelemetry(const TimeStamp& aNow); + const Timeout* aTimeout); private: - TimeoutBudgetManager() : mLastCollection(TimeStamp::Now()) {} - struct TelemetryData - { - TimeDuration mForegroundTracking; - TimeDuration mForegroundNonTracking; - TimeDuration mBackgroundTracking; - TimeDuration mBackgroundNonTracking; - }; + TimeoutBudgetManager() = default; - void Accumulate(Telemetry::HistogramID aId, const TimeDuration& aSample); - - TelemetryData mTelemetryData; TimeStamp mStart; - TimeStamp mLastCollection; }; } // namespace dom diff --git a/dom/base/TimeoutManager.cpp b/dom/base/TimeoutManager.cpp index 7a6996e560d7..f0ec9c7809cd 100644 --- a/dom/base/TimeoutManager.cpp +++ b/dom/base/TimeoutManager.cpp @@ -18,7 +18,6 @@ #include "nsITimeoutHandler.h" #include "mozilla/dom/DocGroup.h" #include "mozilla/dom/TabGroup.h" -#include "OrderedTimeoutIterator.h" #include "TimeoutExecutor.h" #include "TimeoutBudgetManager.h" #include "mozilla/net/WebSocketEventService.h" @@ -293,11 +292,6 @@ TimeoutManager::CalculateDelay(Timeout* aTimeout) const { result, TimeDuration::FromMilliseconds(gMinClampTimeoutValue)); } - if (aTimeout->mIsTracking && mThrottleTrackingTimeouts) { - result = TimeDuration::Max( - result, TimeDuration::FromMilliseconds(gMinTrackingTimeoutValue)); - } - return result; } @@ -332,9 +326,7 @@ TimeoutManager::RecordExecution(Timeout* aRunningTimeout, if (aRunningTimeout) { // If we're running a timeout callback, record any execution until // now. - TimeDuration duration = budgetManager.RecordExecution( - now, aRunningTimeout, mWindow.IsBackgroundInternal()); - budgetManager.MaybeCollectTelemetry(now); + TimeDuration duration = budgetManager.RecordExecution(now, aRunningTimeout); UpdateBudget(now, duration); @@ -396,13 +388,6 @@ TimeoutManager::UpdateBudget(const TimeStamp& aNow, const TimeDuration& aDuratio mLastBudgetUpdate = aNow; } -#define TRACKING_SEPARATE_TIMEOUT_BUCKETING_STRATEGY 0 // Consider all timeouts coming from tracking scripts as tracking -// These strategies are useful for testing. -#define ALL_NORMAL_TIMEOUT_BUCKETING_STRATEGY 1 // Consider all timeouts as normal -#define ALTERNATE_TIMEOUT_BUCKETING_STRATEGY 2 // Put every other timeout in the list of tracking timeouts -#define RANDOM_TIMEOUT_BUCKETING_STRATEGY 3 // Put timeouts into either the normal or tracking timeouts list randomly -static int32_t gTimeoutBucketingStrategy = 0; - #define DEFAULT_TIMEOUT_THROTTLING_DELAY -1 // Only positive integers cause us to introduce a delay for // timeout throttling. @@ -430,8 +415,7 @@ int32_t gDisableOpenClickDelay; TimeoutManager::TimeoutManager(nsGlobalWindowInner& aWindow) : mWindow(aWindow), mExecutor(new TimeoutExecutor(this)), - mNormalTimeouts(*this), - mTrackingTimeouts(*this), + mTimeouts(*this), mTimeoutIdCounter(1), mNextFiringId(InvalidFiringId + 1), mRunningTimeout(nullptr), @@ -474,9 +458,6 @@ TimeoutManager::Initialize() Preferences::AddIntVarCache(&gMinTrackingBackgroundTimeoutValue, "dom.min_tracking_background_timeout_value", DEFAULT_MIN_TRACKING_BACKGROUND_TIMEOUT_VALUE); - Preferences::AddIntVarCache(&gTimeoutBucketingStrategy, - "dom.timeout_bucketing_strategy", - TRACKING_SEPARATE_TIMEOUT_BUCKETING_STRATEGY); Preferences::AddIntVarCache(&gTimeoutThrottlingDelay, "dom.timeout.throttling_delay", DEFAULT_TIMEOUT_THROTTLING_DELAY); @@ -563,43 +544,6 @@ TimeoutManager::SetTimeout(nsITimeoutHandler* aHandler, // No popups from timeouts by default timeout->mPopupState = openAbused; - switch (gTimeoutBucketingStrategy) { - default: - case TRACKING_SEPARATE_TIMEOUT_BUCKETING_STRATEGY: { - const char* filename = nullptr; - uint32_t dummyLine = 0, dummyColumn = 0; - aHandler->GetLocation(&filename, &dummyLine, &dummyColumn); - timeout->mIsTracking = doc->IsScriptTracking(nsDependentCString(filename)); - - MOZ_LOG(gLog, LogLevel::Debug, - ("Classified timeout %p set from %s as %stracking\n", - timeout.get(), filename, timeout->mIsTracking ? "" : "non-")); - break; - } - case ALL_NORMAL_TIMEOUT_BUCKETING_STRATEGY: - // timeout->mIsTracking is already false! - MOZ_DIAGNOSTIC_ASSERT(!timeout->mIsTracking); - - MOZ_LOG(gLog, LogLevel::Debug, - ("Classified timeout %p unconditionally as normal\n", - timeout.get())); - break; - case ALTERNATE_TIMEOUT_BUCKETING_STRATEGY: - timeout->mIsTracking = (mTimeoutIdCounter % 2) == 0; - - MOZ_LOG(gLog, LogLevel::Debug, - ("Classified timeout %p as %stracking (alternating mode)\n", - timeout.get(), timeout->mIsTracking ? "" : "non-")); - break; - case RANDOM_TIMEOUT_BUCKETING_STRATEGY: - timeout->mIsTracking = (rand() % 2) == 0; - - MOZ_LOG(gLog, LogLevel::Debug, - ("Classified timeout %p as %stracking (random mode)\n", - timeout.get(), timeout->mIsTracking ? "" : "non-")); - break; - } - timeout->mNestingLevel = sNestingLevel < DOM_CLAMP_TIMEOUT_NESTING_LEVEL ? sNestingLevel + 1 : sNestingLevel; @@ -633,11 +577,7 @@ TimeoutManager::SetTimeout(nsITimeoutHandler* aHandler, Timeouts::SortBy sort(mWindow.IsFrozen() ? Timeouts::SortBy::TimeRemaining : Timeouts::SortBy::TimeWhen); - if (timeout->mIsTracking) { - mTrackingTimeouts.Insert(timeout, sort); - } else { - mNormalTimeouts.Insert(timeout, sort); - } + mTimeouts.Insert(timeout, sort); timeout->mTimeoutId = GetTimeoutId(aReason); *aReturn = timeout->mTimeoutId; @@ -646,7 +586,7 @@ TimeoutManager::SetTimeout(nsITimeoutHandler* aHandler, LogLevel::Debug, ("Set%s(TimeoutManager=%p, timeout=%p, delay=%i, " "minimum=%f, throttling=%s, state=%s(%s), realInterval=%f) " - "returned %stracking timeout ID %u, budget=%d\n", + "returned timeout ID %u, budget=%d\n", aIsInterval ? "Interval" : "Timeout", this, timeout.get(), interval, (CalculateDelay(timeout) - timeout->mInterval).ToMilliseconds(), @@ -656,7 +596,6 @@ TimeoutManager::SetTimeout(nsITimeoutHandler* aHandler, IsActive() ? "active" : "inactive", mWindow.IsBackgroundInternal() ? "background" : "foreground", realInterval.ToMilliseconds(), - timeout->mIsTracking ? "" : "non-", timeout->mTimeoutId, int(mExecutionBudget.ToMilliseconds()))); @@ -671,11 +610,10 @@ TimeoutManager::ClearTimeout(int32_t aTimerId, Timeout::Reason aReason) bool firstTimeout = true; bool deferredDeletion = false; - ForEachUnorderedTimeoutAbortable([&](Timeout* aTimeout) { + mTimeouts.ForEachAbortable([&](Timeout* aTimeout) { MOZ_LOG(gLog, LogLevel::Debug, - ("Clear%s(TimeoutManager=%p, timeout=%p, aTimerId=%u, ID=%u, tracking=%d)\n", aTimeout->mIsInterval ? "Interval" : "Timeout", - this, aTimeout, timerId, aTimeout->mTimeoutId, - int(aTimeout->mIsTracking))); + ("Clear%s(TimeoutManager=%p, timeout=%p, aTimerId=%u, ID=%u)\n", aTimeout->mIsInterval ? "Interval" : "Timeout", + this, aTimeout, timerId, aTimeout->mTimeoutId)); if (aTimeout->mTimeoutId == timerId && aTimeout->mReason == aReason) { if (aTimeout->mRunning) { @@ -712,8 +650,7 @@ TimeoutManager::ClearTimeout(int32_t aTimerId, Timeout::Reason aReason) // Stop the executor and restart it at the next soonest deadline. mExecutor->Cancel(); - OrderedTimeoutIterator iter(mNormalTimeouts, mTrackingTimeouts); - Timeout* nextTimeout = iter.Next(); + Timeout* nextTimeout = mTimeouts.GetFirst(); if (nextTimeout) { MOZ_ALWAYS_SUCCEEDS(MaybeSchedule(nextTimeout->When())); } @@ -787,39 +724,30 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli // if the timer fired early. So we can stop walking if we get to timeouts // whose When() is greater than deadline, since once that happens we know // nothing past that point is expired. - { - // Use a nested scope in order to make sure the strong references held by - // the iterator are freed after the loop. - OrderedTimeoutIterator expiredIter(mNormalTimeouts, mTrackingTimeouts); + for (Timeout* timeout = mTimeouts.GetFirst(); + timeout != nullptr; + timeout = timeout->getNext()) { + if (totalTimeLimit.IsZero() || timeout->When() > deadline) { + nextDeadline = timeout->When(); + break; + } - while (true) { - Timeout* timeout = expiredIter.Next(); - if (!timeout || totalTimeLimit.IsZero() || timeout->When() > deadline) { - if (timeout) { + if (IsInvalidFiringId(timeout->mFiringId)) { + // Mark any timeouts that are on the list to be fired with the + // firing depth so that we can reentrantly run timeouts + timeout->mFiringId = firingId; + + numTimersToRun += 1; + + // Run only a limited number of timers based on the configured maximum. + if (numTimersToRun % kNumTimersPerInitialElapsedCheck == 0) { + now = TimeStamp::Now(); + TimeDuration elapsed(now - start); + if (elapsed >= initialTimeLimit) { nextDeadline = timeout->When(); - } - break; - } - - if (IsInvalidFiringId(timeout->mFiringId)) { - // Mark any timeouts that are on the list to be fired with the - // firing depth so that we can reentrantly run timeouts - timeout->mFiringId = firingId; - - numTimersToRun += 1; - - // Run only a limited number of timers based on the configured maximum. - if (numTimersToRun % kNumTimersPerInitialElapsedCheck == 0) { - now = TimeStamp::Now(); - TimeDuration elapsed(now - start); - if (elapsed >= initialTimeLimit) { - nextDeadline = timeout->When(); - break; - } + break; } } - - expiredIter.UpdateIterator(); } } @@ -853,17 +781,18 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli // next item after the last timeout we looked at or nullptr if we have // exhausted the entire list while looking for the last expired timeout. { - // Use a nested scope in order to make sure the strong references held by - // the iterator are freed after the loop. - OrderedTimeoutIterator runIter(mNormalTimeouts, mTrackingTimeouts); - while (true) { - RefPtr timeout = runIter.Next(); - if (!timeout) { - // We have run out of timeouts! - break; - } - runIter.UpdateIterator(); + // Use a nested scope in order to make sure the strong references held while + // iterating are freed after the loop. + // The next timeout to run. This is used to advance the loop, but + // we cannot set it until we've run the current timeout, since + // running the current timeout might remove the immediate next + // timeout. + RefPtr next; + + for (RefPtr timeout = mTimeouts.GetFirst(); + timeout != nullptr; + timeout = next) { // We should only execute callbacks for the set of expired Timeout // objects we computed above. if (timeout->mFiringId != firingId) { @@ -907,15 +836,18 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli // This timeout is good to run bool timeout_was_cleared = mWindow.RunTimeoutHandler(timeout, scx); - MOZ_LOG(gLog, LogLevel::Debug, - ("Run%s(TimeoutManager=%p, timeout=%p, tracking=%d) returned %d\n", timeout->mIsInterval ? "Interval" : "Timeout", - this, timeout.get(), - int(timeout->mIsTracking), - !!timeout_was_cleared)); + MOZ_LOG( + gLog, + LogLevel::Debug, + ("Run%s(TimeoutManager=%p, timeout=%p) returned %d\n", + timeout->mIsInterval ? "Interval" : "Timeout", + this, + timeout.get(), + !!timeout_was_cleared)); if (timeout_was_cleared) { - // Make sure the iterator isn't holding any Timeout objects alive. - runIter.Clear(); + // Make sure we're not holding any Timeout objects alive. + next = nullptr; // Since ClearAllTimeouts() was called the lists should be empty. MOZ_DIAGNOSTIC_ASSERT(!HasTimeouts()); @@ -936,22 +868,16 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli // Running a timeout can cause another timeout to be deleted, so // we need to reset the pointer to the following timeout. - runIter.UpdateIterator(); + next = timeout->getNext(); timeout->remove(); if (needsReinsertion) { // Insert interval timeout onto the corresponding list sorted in // deadline order. AddRefs timeout. - if (runIter.PickedTrackingIter()) { - mTrackingTimeouts.Insert(timeout, - mWindow.IsFrozen() ? Timeouts::SortBy::TimeRemaining - : Timeouts::SortBy::TimeWhen); - } else { - mNormalTimeouts.Insert(timeout, - mWindow.IsFrozen() ? Timeouts::SortBy::TimeRemaining - : Timeouts::SortBy::TimeWhen); - } + mTimeouts.Insert(timeout, + mWindow.IsFrozen() ? Timeouts::SortBy::TimeRemaining + : Timeouts::SortBy::TimeWhen); } // Check to see if we have run out of time to execute timeout handlers. @@ -963,8 +889,7 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli // however, that the last timeout handler suspended the window. If // that happened then we must skip this step. if (!mWindow.IsSuspended()) { - RefPtr timeout = runIter.Next(); - if (timeout) { + if (next) { // If we ran out of execution budget we need to force a // reschedule. By cancelling the executor we will not run // immediately, but instead reschedule to the minimum @@ -973,7 +898,7 @@ TimeoutManager::RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadli mExecutor->Cancel(); } - MOZ_ALWAYS_SUCCEEDS(MaybeSchedule(timeout->When(), now)); + MOZ_ALWAYS_SUCCEEDS(MaybeSchedule(next->When(), now)); } } break; @@ -1056,8 +981,7 @@ TimeoutManager::ClearAllTimeouts() }); // Clear out our list - mNormalTimeouts.Clear(); - mTrackingTimeouts.Clear(); + mTimeouts.Clear(); } void @@ -1149,8 +1073,7 @@ TimeoutManager::Resume() MaybeStartThrottleTimeout(); } - OrderedTimeoutIterator iter(mNormalTimeouts, mTrackingTimeouts); - Timeout* nextTimeout = iter.Next(); + Timeout* nextTimeout = mTimeouts.GetFirst(); if (nextTimeout) { MOZ_ALWAYS_SUCCEEDS(MaybeSchedule(nextTimeout->When())); } @@ -1202,8 +1125,7 @@ TimeoutManager::UpdateBackgroundState() // changed. Only do this if the window is not suspended and we // actually have a timeout. if (!mWindow.IsSuspended()) { - OrderedTimeoutIterator iter(mNormalTimeouts, mTrackingTimeouts); - Timeout* nextTimeout = iter.Next(); + Timeout* nextTimeout = mTimeouts.GetFirst(); if (nextTimeout) { mExecutor->Cancel(); MOZ_ALWAYS_SUCCEEDS(MaybeSchedule(nextTimeout->When())); @@ -1211,14 +1133,6 @@ TimeoutManager::UpdateBackgroundState() } } -bool -TimeoutManager::IsTimeoutTracking(uint32_t aTimeoutId) -{ - return mTrackingTimeouts.ForEachAbortable([&](Timeout* aTimeout) { - return aTimeout->mTimeoutId == aTimeoutId; - }); -} - namespace { class ThrottleTimeoutsCallback final : public nsITimerCallback diff --git a/dom/base/TimeoutManager.h b/dom/base/TimeoutManager.h index d5240c4ce20a..7f833ceddb58 100644 --- a/dom/base/TimeoutManager.h +++ b/dom/base/TimeoutManager.h @@ -21,7 +21,6 @@ class PerformanceCounter; namespace dom { -class OrderedTimeoutIterator; class TimeoutExecutor; // This class manages the timeouts in a Window's setTimeout/setInterval pool. @@ -40,8 +39,7 @@ public: bool HasTimeouts() const { - return !mNormalTimeouts.IsEmpty() || - !mTrackingTimeouts.IsEmpty(); + return !mTimeouts.IsEmpty(); } nsresult SetTimeout(nsITimeoutHandler* aHandler, @@ -81,9 +79,6 @@ public: // Initialize TimeoutManager before the first time it is accessed. static void Initialize(); - // Exposed only for testing - bool IsTimeoutTracking(uint32_t aTimeoutId); - // The document finished loading void OnDocumentLoaded(); void StartThrottlingTimeouts(); @@ -93,19 +88,7 @@ public: template void ForEachUnorderedTimeout(Callable c) { - mNormalTimeouts.ForEach(c); - mTrackingTimeouts.ForEach(c); - } - - // Run some code for each Timeout in our list, but let the callback cancel the - // iteration by returning true. Note that this function doesn't guarantee - // that Timeouts are iterated in any particular order. - template - void ForEachUnorderedTimeoutAbortable(Callable c) - { - if (!mNormalTimeouts.ForEachAbortable(c)) { - mTrackingTimeouts.ForEachAbortable(c); - } + mTimeouts.ForEach(c); } void BeginSyncOperation(); @@ -204,8 +187,6 @@ private: return false; } - friend class OrderedTimeoutIterator; - private: // The TimeoutManager that owns this Timeouts structure. This is // mainly used to call state inspecting methods like IsValidFiringId(). @@ -218,8 +199,6 @@ private: TimeoutList mTimeoutList; }; - friend class OrderedTimeoutIterator; - // Each nsGlobalWindowInner object has a TimeoutManager member. This reference // points to that holder object. nsGlobalWindowInner& mWindow; @@ -228,9 +207,7 @@ private: // it must be a separate ref-counted object. RefPtr mExecutor; // The list of timeouts coming from non-tracking scripts. - Timeouts mNormalTimeouts; - // The list of timeouts coming from scripts on the tracking protection list. - Timeouts mTrackingTimeouts; + Timeouts mTimeouts; uint32_t mTimeoutIdCounter; uint32_t mNextFiringId; AutoTArray mFiringIdStack; diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 5c7980f65da2..2dcc80f1e36f 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -4250,21 +4250,6 @@ nsDOMWindowUtils::GetGpuProcessPid(int32_t* aPid) return NS_OK; } -NS_IMETHODIMP -nsDOMWindowUtils::IsTimeoutTracking(uint32_t aTimeoutId, bool* aResult) -{ - NS_ENSURE_ARG_POINTER(aResult); - *aResult = false; - - nsCOMPtr window = do_QueryReferent(mWindow); - NS_ENSURE_STATE(window); - nsCOMPtr innerWindow = window->GetCurrentInnerWindow(); - NS_ENSURE_STATE(innerWindow); - - *aResult = innerWindow->TimeoutManager().IsTimeoutTracking(aTimeoutId); - return NS_OK; -} - struct StateTableEntry { const char* mStateString; @@ -4493,4 +4478,3 @@ nsDOMWindowUtils::IsCssPropertyRecordedInUseCounter(const nsACString& aPropName, &knownProp); return knownProp ? NS_OK : NS_ERROR_FAILURE; } - diff --git a/dom/base/test/file_timer_flood.html b/dom/base/test/file_timer_flood.html index 94647d1750bf..dc729d7e4214 100644 --- a/dom/base/test/file_timer_flood.html +++ b/dom/base/test/file_timer_flood.html @@ -3,25 +3,15 @@ diff --git a/dom/base/test/test_timer_flood.html b/dom/base/test/test_timer_flood.html index c55dcf45ca82..95d778afb922 100644 --- a/dom/base/test/test_timer_flood.html +++ b/dom/base/test/test_timer_flood.html @@ -22,24 +22,15 @@ function onLoad() { }); } -function setPrefs() { - // Put timeouts randomly in the tracking or normal buffer. We do this in order to - // test to ensure that by default, this will not change the scheduling of timeouts. - return SpecialPowers.pushPrefEnv({"set": [["dom.timeout_bucketing_strategy", 3]]}); -} - // Create a frame that executes a timer flood. The frame signals // that is ready once the flood has had a chance to warm up. function withFloodFrame() { - return new Promise((resolve, reject) => { + return new Promise(resolve => { let frame = document.createElement('iframe'); addEventListener('message', function onMsg(evt) { if (evt.data === 'STARTED') { removeEventListener('message', onMsg); resolve(frame); - } else if (evt.data == 'OUT_OF_ORDER') { - ok(false, "Out of order timeout observed"); - reject(); } }); frame.src = 'file_timer_flood.html'; @@ -86,9 +77,7 @@ function testRequestAnimationFrame() { let floodFrame; -onLoad() -.then(setPrefs) -.then(_ => { +onLoad().then(_ => { // Start a timer flood in a frame. return withFloodFrame(); }).then(frame => { @@ -122,8 +111,6 @@ onLoad() ok(true, 'completed tests without timing out'); floodFrame.remove(); SimpleTest.finish(); -}).catch(_ => { - SimpleTest.finish(); }); diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 7c9dd211a2c2..65c2e7b50f9f 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -1876,12 +1876,6 @@ interface nsIDOMWindowUtils : nsISupports { */ readonly attribute int32_t gpuProcessPid; - /** - * Returns true if the given timeout ID is in the list of tracking - * timeouts. - */ - boolean isTimeoutTracking(in unsigned long timeoutId); - /** * Adds an EventStates bit to the element. * diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index f6bd304d86ea..1fc3c2c7940f 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -13179,51 +13179,6 @@ "keyed": true, "description": "Measures the number of milliseconds we spend waiting for sync message manager IPC messages to finish sending, keyed by message name. Note: only messages that wait for more than 500 microseconds are included in this probe." }, - "TIMEOUT_EXECUTION_FG_MS": - { - "record_in_processes": ["main", "content"], - "alert_emails": ["farre@mozilla.com"], - "bug_numbers": [1355480], - "expires_in_version": "61", - "kind": "exponential", - "high": 1000, - "n_buckets": 20, - "description": "Time in ms used to execute callbacks from setTimeout/setInterval, when the script belongs to a tab in the foreground and the script is not on the tracking list. Multiple events are aggregated over a 1s interval." - }, - "TIMEOUT_EXECUTION_FG_TRACKING_MS": - { - "record_in_processes": ["main", "content"], - "alert_emails": ["farre@mozilla.com"], - "bug_numbers": [1355480], - "expires_in_version": "61", - "kind": "exponential", - "high": 1000, - "n_buckets": 20, - "description": "Time in ms used to execute callbacks from setTimeout/setInterval, when the script belongs to a tab in the foreground and the script is on the tracking list. Multiple events are aggregated over a 1s interval." - }, - "TIMEOUT_EXECUTION_BG_MS": - { - "record_in_processes": ["main", "content"], - "alert_emails": ["farre@mozilla.com"], - "bug_numbers": [1355480], - "expires_in_version": "61", - "kind": "exponential", - "high": 1000, - "n_buckets": 20, - "description": "Time in ms used to execute callbacks from setTimeout/setInterval, when the script belongs to a tab in the background and the script is not on the tracking list. Multiple events are aggregated over a 1s interval." - }, - "TIMEOUT_EXECUTION_BG_TRACKING_MS": - { - "record_in_processes": ["main", "content"], - "alert_emails": ["farre@mozilla.com"], - "bug_numbers": [1355480], - "expires_in_version": "61", - "kind": "exponential", - "low": 1, - "high": 1000, - "n_buckets": 10, - "description": "Time in ms used to execute callbacks from setTimeout/setInterval, when the script belongs to a tab in the background and the script is on the tracking list. Multiple events are aggregated over a 1s interval." - }, "TIME_TO_DOM_LOADING_MS": { "record_in_processes": ["content"], "alert_emails": ["hbambas@mozilla.com", "vgosu@mozilla.com", "jduell@mozilla.com"], diff --git a/toolkit/components/url-classifier/tests/mochitest/chrome.ini b/toolkit/components/url-classifier/tests/mochitest/chrome.ini index 3207639c0331..21a9c09d1595 100644 --- a/toolkit/components/url-classifier/tests/mochitest/chrome.ini +++ b/toolkit/components/url-classifier/tests/mochitest/chrome.ini @@ -42,7 +42,6 @@ support-files = !/toolkit/components/url-classifier/tests/mochitest/bad.css !/toolkit/components/url-classifier/tests/mochitest/bad.css^headers^ !/toolkit/components/url-classifier/tests/mochitest/gethashFrame.html - !/toolkit/components/url-classifier/tests/mochitest/tracker.js !/toolkit/components/url-classifier/tests/mochitest/seek.webm !/toolkit/components/url-classifier/tests/mochitest/cache.sjs diff --git a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html index f1325175a7a0..7c4b3ac834da 100644 --- a/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html +++ b/toolkit/components/url-classifier/tests/mochitest/classifierFrame.html @@ -32,17 +32,6 @@ function checkLoads() { return; } - let dwu = window.parent.SpecialPowers.getDOMWindowUtils(window); - let timer1 = window.setTimeout(function() {}, 0); - window.parent.ok(!dwu.isTimeoutTracking(timer1), - "Timeout set from main script should not be considered as tracking"); - /* global getTrackerTimeout */ - let timer2 = getTrackerTimeout(); - window.parent.ok(dwu.isTimeoutTracking(timer2), - "Timeout set from included script should be considered as tracking"); - window.clearTimeout(timer1); - window.clearTimeout(timer2); - // End (parent) test. window.parent.SimpleTest.finish(); } @@ -52,9 +41,6 @@ function checkLoads() { - - - diff --git a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini index 19e005181b5c..ddc9ce55e1aa 100644 --- a/toolkit/components/url-classifier/tests/mochitest/mochitest.ini +++ b/toolkit/components/url-classifier/tests/mochitest/mochitest.ini @@ -30,7 +30,6 @@ support-files = bad.css^headers^ gethash.sjs gethashFrame.html - tracker.js seek.webm cache.sjs diff --git a/toolkit/components/url-classifier/tests/mochitest/tracker.js b/toolkit/components/url-classifier/tests/mochitest/tracker.js deleted file mode 100644 index cedfc51793ed..000000000000 --- a/toolkit/components/url-classifier/tests/mochitest/tracker.js +++ /dev/null @@ -1,3 +0,0 @@ -function getTrackerTimeout() { - return window.setTimeout(function() {}, 0); -}