Skip to content

Commit 779cd4a

Browse files
committed
Bug 1241656 - Lazify AutoTaskDispatcher::mDirectTasks. r=bholley.
This avoids large amounts of heap churn while watching YouTube videos on Mac and Linux. --HG-- extra : rebase_source : 8606947287574826c455c25336c1a42d77ce6dcc
1 parent cf187c3 commit 779cd4a

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

xpcom/threads/TaskDispatcher.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ class TaskDispatcher
6969
class AutoTaskDispatcher : public TaskDispatcher
7070
{
7171
public:
72-
explicit AutoTaskDispatcher(bool aIsTailDispatcher = false) : mIsTailDispatcher(aIsTailDispatcher) {}
72+
explicit AutoTaskDispatcher(bool aIsTailDispatcher = false)
73+
: mIsTailDispatcher(aIsTailDispatcher)
74+
{}
75+
7376
~AutoTaskDispatcher()
7477
{
7578
// Given that direct tasks may trigger other code that uses the tail
@@ -81,25 +84,33 @@ class AutoTaskDispatcher : public TaskDispatcher
8184
// potentially not true for other hypothetical AutoTaskDispatchers). Feel
8285
// free to loosen this restriction to apply only to mIsTailDispatcher if a
8386
// use-case requires it.
84-
MOZ_ASSERT(mDirectTasks.empty());
87+
MOZ_ASSERT(!HaveDirectTasks());
8588

8689
for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
8790
DispatchTaskGroup(Move(mTaskGroups[i]));
8891
}
8992
}
9093

94+
bool HaveDirectTasks() const
95+
{
96+
return mDirectTasks.isSome() && !mDirectTasks->empty();
97+
}
98+
9199
void DrainDirectTasks() override
92100
{
93-
while (!mDirectTasks.empty()) {
94-
nsCOMPtr<nsIRunnable> r = mDirectTasks.front();
95-
mDirectTasks.pop();
101+
while (HaveDirectTasks()) {
102+
nsCOMPtr<nsIRunnable> r = mDirectTasks->front();
103+
mDirectTasks->pop();
96104
r->Run();
97105
}
98106
}
99107

100108
void AddDirectTask(already_AddRefed<nsIRunnable> aRunnable) override
101109
{
102-
mDirectTasks.push(Move(aRunnable));
110+
if (mDirectTasks.isNothing()) {
111+
mDirectTasks.emplace();
112+
}
113+
mDirectTasks->push(Move(aRunnable));
103114
}
104115

105116
void AddStateChangeTask(AbstractThread* aThread,
@@ -124,7 +135,8 @@ class AutoTaskDispatcher : public TaskDispatcher
124135

125136
bool HasTasksFor(AbstractThread* aThread) override
126137
{
127-
return !!GetTaskGroup(aThread) || (aThread == AbstractThread::GetCurrent() && !mDirectTasks.empty());
138+
return !!GetTaskGroup(aThread) ||
139+
(aThread == AbstractThread::GetCurrent() && HaveDirectTasks());
128140
}
129141

130142
void DispatchTasksFor(AbstractThread* aThread) override
@@ -232,8 +244,11 @@ class AutoTaskDispatcher : public TaskDispatcher
232244
thread->Dispatch(r.forget(), failureHandling, reason);
233245
}
234246

235-
// Direct tasks.
236-
std::queue<nsCOMPtr<nsIRunnable>> mDirectTasks;
247+
// Direct tasks. We use a Maybe<> because (a) this class is hot, (b)
248+
// mDirectTasks often doesn't get anything put into it, and (c) the
249+
// std::queue implementation in GNU libstdc++ does two largish heap
250+
// allocations when creating a new std::queue.
251+
mozilla::Maybe<std::queue<nsCOMPtr<nsIRunnable>>> mDirectTasks;
237252

238253
// Task groups, organized by thread.
239254
nsTArray<UniquePtr<PerThreadTaskGroup>> mTaskGroups;

0 commit comments

Comments
 (0)