Backed out changeset 873b1f683e95 (bug 1945470) for causing high frequency failures at test_ext_native_messaging_perf.js. CLOSED TREE

This commit is contained in:
Butkovits Atila
2025-03-03 23:28:43 +02:00
parent d4b9905630
commit 518c66d0dd
12 changed files with 49 additions and 141 deletions

View File

@@ -10,6 +10,11 @@
namespace mozilla::dom {
/* static */ TimeoutBudgetManager& TimeoutBudgetManager::Get() {
static TimeoutBudgetManager gTimeoutBudgetManager;
return gTimeoutBudgetManager;
}
void TimeoutBudgetManager::StartRecording(const TimeStamp& aNow) {
mStart = aNow;
}

View File

@@ -8,18 +8,22 @@
#define mozilla_dom_timeoutbudgetmanager_h
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/Timeout.h"
namespace mozilla::dom {
class Timeout;
class TimeoutBudgetManager {
public:
static TimeoutBudgetManager& Get();
void StartRecording(const TimeStamp& aNow);
void StopRecording();
TimeDuration RecordExecution(const TimeStamp& aNow, const Timeout* aTimeout);
private:
TimeStamp mStart{};
TimeoutBudgetManager() = default;
TimeStamp mStart;
};
} // namespace mozilla::dom

View File

@@ -21,6 +21,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TimeoutHandler.h"
#include "TimeoutExecutor.h"
#include "TimeoutBudgetManager.h"
#include "mozilla/net/WebSocketEventService.h"
#include "mozilla/MediaManager.h"
#include "mozilla/dom/WorkerScope.h"
@@ -30,14 +31,12 @@ using namespace mozilla::dom;
LazyLogModule gTimeoutLog("Timeout");
TimeoutBudgetManager TimeoutManager::sBudgetManager{};
static int32_t gRunningTimeoutDepth = 0;
// static
const uint32_t TimeoutManager::InvalidFiringId = 0;
namespace {
static int32_t gRunningTimeoutDepth = 0;
double GetRegenerationFactor(bool aIsBackground) {
// Lookup function for "dom.timeout.{background,
// foreground}_budget_regeneration_rate".
@@ -334,9 +333,8 @@ TimeDuration TimeoutManager::CalculateDelay(Timeout* aTimeout) const {
void TimeoutManager::RecordExecution(Timeout* aRunningTimeout,
Timeout* aTimeout) {
TimeoutBudgetManager& budgetManager = TimeoutBudgetManager::Get();
TimeStamp now = TimeStamp::Now();
TimeoutBudgetManager& budgetManager{GetInnerWindow() ? sBudgetManager
: mBudgetManager};
if (aRunningTimeout) {
// If we're running a timeout callback, record any execution until
@@ -490,12 +488,6 @@ nsresult TimeoutManager::SetTimeout(TimeoutHandler* aHandler, int32_t interval,
}
}
auto scopeExit = MakeScopeExit([&] {
if (!mGlobalObject.GetAsInnerWindow() && !HasTimeouts()) {
mGlobalObject.TriggerUpdateCCFlag();
}
});
// Disallow negative intervals.
interval = std::max(0, interval);
@@ -517,20 +509,13 @@ nsresult TimeoutManager::SetTimeout(TimeoutHandler* aHandler, int32_t interval,
timeout->mScriptHandler = aHandler;
timeout->mReason = aReason;
if (GetInnerWindow()) {
// No popups from timeouts by default
timeout->mPopupState = PopupBlocker::openAbused;
}
// No popups from timeouts by default
timeout->mPopupState = PopupBlocker::openAbused;
// XXX: Does eIdleCallbackTimeout need clamping?
if (aReason == Timeout::Reason::eTimeoutOrInterval ||
aReason == Timeout::Reason::eIdleCallbackTimeout) {
uint32_t nestingLevel{};
if (GetInnerWindow()) {
nestingLevel = GetNestingLevelForWindow();
} else {
nestingLevel = GetNestingLevelForWorker();
}
const uint32_t nestingLevel{GetNestingLevel()};
timeout->mNestingLevel =
nestingLevel < StaticPrefs::dom_clamp_timeout_nesting_level_AtStartup()
? nestingLevel + 1
@@ -550,20 +535,18 @@ nsresult TimeoutManager::SetTimeout(TimeoutHandler* aHandler, int32_t interval,
}
}
if (GetInnerWindow()) {
if (gRunningTimeoutDepth == 0 &&
PopupBlocker::GetPopupControlState() < PopupBlocker::openBlocked) {
// This timeout is *not* set from another timeout and it's set
// while popups are enabled. Propagate the state to the timeout if
// its delay (interval) is equal to or less than what
// "dom.disable_open_click_delay" is set to (in ms).
if (gRunningTimeoutDepth == 0 &&
PopupBlocker::GetPopupControlState() < PopupBlocker::openBlocked) {
// This timeout is *not* set from another timeout and it's set
// while popups are enabled. Propagate the state to the timeout if
// its delay (interval) is equal to or less than what
// "dom.disable_open_click_delay" is set to (in ms).
// This is checking |interval|, not realInterval, on purpose,
// because our lower bound for |realInterval| could be pretty high
// in some cases.
if (interval <= StaticPrefs::dom_disable_open_click_delay()) {
timeout->mPopupState = PopupBlocker::GetPopupControlState();
}
// This is checking |interval|, not realInterval, on purpose,
// because our lower bound for |realInterval| could be pretty high
// in some cases.
if (interval <= StaticPrefs::dom_disable_open_click_delay()) {
timeout->mPopupState = PopupBlocker::GetPopupControlState();
}
}
@@ -1127,18 +1110,14 @@ void TimeoutManager::Timeouts::Insert(Timeout* aTimeout, SortBy aSortBy) {
Timeout* TimeoutManager::BeginRunningTimeout(Timeout* aTimeout) {
Timeout* currentTimeout = mRunningTimeout;
mRunningTimeout = aTimeout;
if (GetInnerWindow()) {
++gRunningTimeoutDepth;
}
++gRunningTimeoutDepth;
RecordExecution(currentTimeout, aTimeout);
return currentTimeout;
}
void TimeoutManager::EndRunningTimeout(Timeout* aTimeout) {
if (GetInnerWindow()) {
--gRunningTimeoutDepth;
}
--gRunningTimeoutDepth;
RecordExecution(mRunningTimeout, aTimeout);
mRunningTimeout = aTimeout;

View File

@@ -10,7 +10,6 @@
#include "mozilla/dom/Timeout.h"
#include "nsTArray.h"
#include "nsISerialEventTarget.h"
#include "mozilla/dom/TimeoutBudgetManager.h"
class nsIEventTarget;
class nsITimer;
@@ -37,23 +36,16 @@ class TimeoutManager final {
bool IsRunningTimeout() const;
uint32_t GetNestingLevelForWorker() {
MOZ_DIAGNOSTIC_ASSERT(!NS_IsMainThread());
return mNestingLevel;
}
uint32_t GetNestingLevelForWindow() {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
return sNestingLevel;
uint32_t GetNestingLevel() {
return mGlobalObject.GetAsInnerWindow() ? sNestingLevel : mNestingLevel;
}
void SetNestingLevelForWorker(uint32_t aLevel) {
MOZ_DIAGNOSTIC_ASSERT(!NS_IsMainThread());
mNestingLevel = aLevel;
}
void SetNestingLevelForWindow(uint32_t aLevel) {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
sNestingLevel = aLevel;
void SetNestingLevel(uint32_t aLevel) {
if (mGlobalObject.GetAsInnerWindow()) {
sNestingLevel = aLevel;
} else {
mNestingLevel = aLevel;
}
}
bool HasTimeouts() const {
@@ -269,11 +261,7 @@ class TimeoutManager final {
nsCOMPtr<nsISerialEventTarget> mEventTarget;
uint32_t mNestingLevel{0};
static uint32_t sNestingLevel;
TimeoutBudgetManager mBudgetManager;
static TimeoutBudgetManager sBudgetManager;
};
} // namespace dom

View File

@@ -282,7 +282,6 @@ EXPORTS.mozilla.dom += [
"TestUtils.h",
"Text.h",
"Timeout.h",
"TimeoutBudgetManager.h",
"TimeoutHandler.h",
"TimeoutManager.h",
"TreeIterator.h",

View File

@@ -6274,8 +6274,8 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) {
// timeouts from repeatedly opening poups.
timeout->mPopupState = PopupBlocker::openAbused;
uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWindow();
mTimeoutManager->SetNestingLevelForWindow(timeout->mNestingLevel);
uint32_t nestingLevel = mTimeoutManager->GetNestingLevel();
mTimeoutManager->SetNestingLevel(timeout->mNestingLevel);
const char* reason = GetTimeoutReasonString(timeout);
@@ -6326,7 +6326,7 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout) {
// point anyway, and the script context should have already reported
// the script error in the usual way - so we just drop it.
mTimeoutManager->SetNestingLevelForWindow(nestingLevel);
mTimeoutManager->SetNestingLevel(nestingLevel);
mTimeoutManager->EndRunningTimeout(last_running_timeout);
timeout->mRunning = false;

View File

@@ -250,8 +250,6 @@ class nsIGlobalObject : public nsISupports {
// nullptr otherwise.
nsPIDOMWindowInner* GetAsInnerWindow();
virtual void TriggerUpdateCCFlag() {}
void QueueMicrotask(mozilla::dom::VoidFunction& aCallback);
void RegisterReportingObserver(mozilla::dom::ReportingObserver* aObserver,

View File

@@ -4558,16 +4558,6 @@ void WorkerPrivate::PropagateStorageAccessPermissionGrantedInternal() {
void WorkerPrivate::TraverseTimeouts(nsCycleCollectionTraversalCallback& cb) {
auto data = mWorkerThreadAccessible.Access();
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
if (timeoutManager) {
timeoutManager->ForEachUnorderedTimeout([&cb](Timeout* timeout) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(Timeout));
});
}
return;
}
for (uint32_t i = 0; i < data->mTimeouts.Length(); ++i) {
// TODO(erahm): No idea what's going on here.
TimeoutInfo* tmp = data->mTimeouts[i].get();
@@ -4577,17 +4567,6 @@ void WorkerPrivate::TraverseTimeouts(nsCycleCollectionTraversalCallback& cb) {
void WorkerPrivate::UnlinkTimeouts() {
auto data = mWorkerThreadAccessible.Access();
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
if (timeoutManager) {
timeoutManager->ClearAllTimeouts();
if (!timeoutManager->HasTimeouts()) {
UpdateCCFlag(CCFlag::EligibleForTimeout);
}
}
return;
}
data->mTimeouts.Clear();
}
@@ -4803,22 +4782,10 @@ void WorkerPrivate::UpdateCCFlag(const CCFlag aFlag) {
break;
}
case CCFlag::EligibleForTimeout: {
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
MOZ_ASSERT(timeoutManager && !timeoutManager->HasTimeouts());
break;
}
MOZ_ASSERT(data->mTimeouts.IsEmpty());
break;
}
case CCFlag::IneligibleForTimeout: {
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
MOZ_ASSERT(!timeoutManager || timeoutManager->HasTimeouts());
break;
}
MOZ_ASSERT(!data->mTimeouts.IsEmpty());
break;
}
@@ -4848,17 +4815,8 @@ void WorkerPrivate::UpdateCCFlag(const CCFlag aFlag) {
return totalCount > nonblockingActorCount;
};
bool noTimeouts{data->mTimeouts.IsEmpty()};
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
if (timeoutManager) {
noTimeouts = !timeoutManager->HasTimeouts();
}
}
bool eligibleForCC = data->mChildWorkers.IsEmpty() && noTimeouts &&
bool eligibleForCC = data->mChildWorkers.IsEmpty() &&
data->mTimeouts.IsEmpty() &&
!data->mNumWorkerRefsPreventingShutdownStart;
// Only checking BackgroundActors when no strong WorkerRef, ChildWorker, and
@@ -4912,9 +4870,6 @@ void WorkerPrivate::CancelAllTimeouts() {
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
if (timeoutManager) {
timeoutManager->ClearAllTimeouts();
if (!timeoutManager->HasTimeouts()) {
UpdateCCFlag(CCFlag::EligibleForTimeout);
}
}
return;
}
@@ -5635,18 +5590,12 @@ int32_t WorkerPrivate::SetTimeout(JSContext* aCx, TimeoutHandler* aHandler,
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
WorkerGlobalScope* globalScope = GlobalScope();
MOZ_DIAGNOSTIC_ASSERT(globalScope);
auto* timeoutManager = globalScope->GetTimeoutManager();
int32_t timerId = -1;
bool hadTimeouts = timeoutManager->HasTimeouts();
nsresult rv = timeoutManager->SetTimeout(aHandler, aTimeout, aIsInterval,
aReason, &timerId);
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_FAILURE);
return timerId;
}
if (!hadTimeouts) {
UpdateCCFlag(CCFlag::IneligibleForTimeout);
}
return timerId;
}
@@ -5733,12 +5682,8 @@ void WorkerPrivate::ClearTimeout(int32_t aId, Timeout::Reason aReason) {
"This timeout reason doesn't support cancellation.");
if (StaticPrefs::dom_workers_timeoutmanager_AtStartup()) {
WorkerGlobalScope* globalScope = GlobalScope();
MOZ_DIAGNOSTIC_ASSERT(globalScope);
auto* timeoutManager = globalScope->GetTimeoutManager();
timeoutManager->ClearTimeout(aId, aReason);
if (!timeoutManager->HasTimeouts()) {
UpdateCCFlag(CCFlag::EligibleForTimeout);
}
return;
}
@@ -6070,7 +6015,7 @@ uint32_t WorkerPrivate::GetCurrentTimerNestingLevel() const {
auto* timeoutManager =
data->mScope ? data->mScope->GetTimeoutManager() : nullptr;
if (timeoutManager) {
return timeoutManager->GetNestingLevelForWorker();
return timeoutManager->GetNestingLevel();
}
return data->mCurrentTimerNestingLevel;

View File

@@ -308,8 +308,8 @@ bool WorkerGlobalScopeBase::RunTimeoutHandler(mozilla::dom::Timeout* aTimeout) {
Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
timeout->mRunning = true;
uint32_t nestingLevel = mTimeoutManager->GetNestingLevelForWorker();
mTimeoutManager->SetNestingLevelForWorker(timeout->mNestingLevel);
uint32_t nestingLevel = mTimeoutManager->GetNestingLevel();
mTimeoutManager->SetNestingLevel(timeout->mNestingLevel);
const char* reason = workerinternals::GetTimeoutReasonString(timeout);
@@ -343,7 +343,7 @@ bool WorkerGlobalScopeBase::RunTimeoutHandler(mozilla::dom::Timeout* aTimeout) {
// point anyway, and the script context should have already reported
// the script error in the usual way - so we just drop it.
mTimeoutManager->SetNestingLevelForWorker(nestingLevel);
mTimeoutManager->SetNestingLevel(nestingLevel);
mTimeoutManager->EndRunningTimeout(last_running_timeout);
timeout->mRunning = false;

View File

@@ -206,10 +206,6 @@ class WorkerGlobalScopeBase : public DOMEventTargetHelper,
return mWorkerPrivate->IsFrozenForWorkerThread();
}
void TriggerUpdateCCFlag() override {
mWorkerPrivate->UpdateCCFlag(WorkerPrivate::CCFlag::EligibleForTimeout);
}
static WorkerGlobalScopeBase* Cast(nsIGlobalObject* obj) {
return static_cast<WorkerGlobalScopeBase*>(obj);
}

View File

@@ -4502,7 +4502,7 @@
- name: dom.workers.timeoutmanager
type: bool
value: @IS_NIGHTLY_BUILD@
value: false
mirror: once
- name: dom.workers.serialized-sab-access

View File

@@ -5,13 +5,7 @@ const { setTimeout } = ChromeUtils.importESModule(
"resource://gre/modules/Timer.sys.mjs"
);
let max_round_trip_time_ms = AppConstants.DEBUG || AppConstants.ASAN ? 18 : 9;
if (Services.prefs.getBoolPref("dom.workers.timeoutmanager") === true) {
max_round_trip_time_ms = 90;
}
const MAX_ROUND_TRIP_TIME_MS = max_round_trip_time_ms;
const MAX_ROUND_TRIP_TIME_MS = AppConstants.DEBUG || AppConstants.ASAN ? 18 : 9;
const MAX_RETRIES = 5;
let PYTHON;