bug 1468099, Add a way to check if all the tabs in a process can be throttled, r=farre

This commit is contained in:
Olli Pettay 2018-06-16 22:49:41 +03:00
Родитель 163724eccf
Коммит cbd7017dfb
3 изменённых файлов: 65 добавлений и 3 удалений

Просмотреть файл

@ -9,6 +9,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/TimeoutManager.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
@ -23,6 +24,8 @@ namespace dom {
static StaticRefPtr<TabGroup> sChromeTabGroup;
LinkedList<TabGroup>* TabGroup::sTabGroups = nullptr;
TabGroup::TabGroup(bool aIsChrome)
: mLastWindowLeft(false)
, mThrottledQueuesInitialized(false)
@ -31,6 +34,11 @@ TabGroup::TabGroup(bool aIsChrome)
, mIsChrome(aIsChrome)
, mForegroundCount(0)
{
if (!sTabGroups) {
sTabGroups = new LinkedList<TabGroup>();
}
sTabGroups->insertBack(this);
CreateEventTargets(/* aNeedValidation = */ !aIsChrome);
// Do not throttle runnables from chrome windows. In theory we should
@ -54,6 +62,15 @@ TabGroup::~TabGroup()
MOZ_ASSERT(mDocGroups.IsEmpty());
MOZ_ASSERT(mWindows.IsEmpty());
MOZ_RELEASE_ASSERT(mLastWindowLeft || mIsChrome);
LinkedListElement<TabGroup>* listElement =
static_cast<LinkedListElement<TabGroup>*>(this);
listElement->remove();
if (sTabGroups->isEmpty()) {
delete sTabGroups;
sTabGroups = nullptr;
}
}
void
@ -323,5 +340,37 @@ TabGroup::Count(bool aActiveOnly) const
return count;
}
/*static*/ bool
TabGroup::HasOnlyThrottableTabs()
{
if (!sTabGroups) {
return false;
}
for (TabGroup* tabGroup = sTabGroups->getFirst(); tabGroup;
tabGroup =
static_cast<LinkedListElement<TabGroup>*>(tabGroup)->getNext()) {
for (auto iter = tabGroup->Iter(); !iter.Done(); iter.Next()) {
DocGroup* docGroup = iter.Get()->mDocGroup;
for (auto* documentInDocGroup : *docGroup) {
if (documentInDocGroup->IsCurrentActiveDocument()) {
nsPIDOMWindowInner* win =
documentInDocGroup->GetInnerWindow();
if (win && win->IsCurrentInnerWindow()) {
nsPIDOMWindowOuter* outer = win->GetOuterWindow();
if (outer) {
TimeoutManager& tm = win->TimeoutManager();
if (!tm.BudgetThrottlingEnabled(outer->IsBackground())) {
return false;
}
}
}
}
}
}
}
return true;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -46,7 +46,8 @@ class TabChild;
class DocGroup;
class TabChild;
class TabGroup final : public SchedulerGroup
class TabGroup final : public SchedulerGroup,
public LinkedListElement<TabGroup>
{
private:
class HashEntry : public nsCStringHashKey
@ -146,6 +147,16 @@ public:
return mNumOfIndexedDBDatabases;
}
static LinkedList<TabGroup>* GetTabGroupList()
{
return sTabGroups;
}
// This returns true if all the window objects in all the TabGroups are
// either inactive (for example in bfcache) or are in background tabs which
// can be throttled.
static bool HasOnlyThrottableTabs();
private:
virtual AbstractThread*
AbstractMainThreadForImpl(TaskCategory aCategory) override;
@ -167,6 +178,8 @@ private:
DocGroupMap mDocGroups;
nsTArray<nsPIDOMWindowOuter*> mWindows;
uint32_t mForegroundCount;
static LinkedList<TabGroup>* sTabGroups;
};
} // namespace dom

Просмотреть файл

@ -111,6 +111,8 @@ public:
nsIEventTarget*
EventTarget();
bool BudgetThrottlingEnabled(bool aIsBackground) const;
static const uint32_t InvalidFiringId;
private:
@ -149,8 +151,6 @@ private:
void UpdateBudget(const TimeStamp& aNow,
const TimeDuration& aDuration = TimeDuration());
bool BudgetThrottlingEnabled(bool aIsBackground) const;
private:
struct Timeouts {
explicit Timeouts(const TimeoutManager& aManager)