Bug 1647470: Fix MinTabSelector to take into account empty but reusable content processes; r=nika

When the current number of existing content processes is less than the maximum,
`MinTabSelector` previously always created a new process. This is inefficient in
the case where we have `dom.ipc.keepProcessesAlive.web` set and there are
content processes that are idle with zero tabs -- we should allow those to be
reused.

Differential Revision: https://phabricator.services.mozilla.com/D80560
This commit is contained in:
Aaron Klotz 2020-06-27 06:14:27 +00:00
Родитель 71614873fb
Коммит 6ff329ef81
2 изменённых файлов: 21 добавлений и 10 удалений

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

@ -28,19 +28,16 @@ MinTabSelector.prototype = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIContentProcessProvider]),
provideProcess(aType, aProcesses, aMaxCount) {
if (aProcesses.length < aMaxCount) {
return Ci.nsIContentProcessProvider.NEW_PROCESS;
}
let min = Number.MAX_VALUE;
let candidate = Ci.nsIContentProcessProvider.NEW_PROCESS;
// Note, that at this point aMaxCount is in the valid range and
// the reason for not using aProcesses.length here is because if we keep
// processes alive for testing but want a test to use only single
// The reason for not directly using aProcesses.length here is because if
// we keep processes alive for testing but want a test to use only single
// content process we can just keep relying on dom.ipc.processCount = 1
// this way.
for (let i = 0; i < aMaxCount; i++) {
let numIters = Math.min(aProcesses.length, aMaxCount);
for (let i = 0; i < numIters; i++) {
let process = aProcesses[i];
let tabCount = process.tabCount;
if (tabCount < min) {
@ -49,6 +46,13 @@ MinTabSelector.prototype = {
}
}
// If all current processes have at least one tab and we have not yet
// reached the maximum, spawn a new process.
if (min > 0 && aProcesses.length < aMaxCount) {
return Ci.nsIContentProcessProvider.NEW_PROCESS;
}
// Otherwise we use candidate.
return candidate;
},
};

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

@ -848,6 +848,14 @@ already_AddRefed<ContentParent> ContentParent::MinTabSelect(
}
}
// If all current processes have at least one tab and we have not yet reached
// the maximum, use a new process.
if (min > 0 &&
aContentParents.Length() < static_cast<uint32_t>(aMaxContentParents)) {
return nullptr;
}
// Otherwise we return candidate.
return candidate.forget();
}
@ -901,8 +909,7 @@ already_AddRefed<ContentParent> ContentParent::GetUsedBrowserProcess(
// selection.
NS_WARNING("nsIContentProcessProvider failed to return a process");
RefPtr<ContentParent> random;
if (aContentParents.Length() >= aMaxContentParents &&
(random = MinTabSelect(aContentParents, aMaxContentParents))) {
if ((random = MinTabSelect(aContentParents, aMaxContentParents))) {
MOZ_LOG(ContentParent::GetLog(), LogLevel::Debug,
("GetUsedProcess: Reused random process %p (%d) for %s",
random.get(), (unsigned int)random->ChildID(),