Bug 1329331 - Leave the Large-Allocation process after subsequent navigations, r=smaug

MozReview-Commit-ID: DfivmSEvzBu
This commit is contained in:
Michael Layzell 2017-01-06 16:38:53 -05:00
Родитель 1697309ff6
Коммит 3a272149c6
9 изменённых файлов: 71 добавлений и 10 удалений

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

@ -1688,7 +1688,8 @@
// Abort if we're not going to change anything
if (isRemote == aShouldBeRemote && !aOptions.newFrameloader && !aOptions.freshProcess &&
(!isRemote || aBrowser.getAttribute("remoteType") == aOptions.remoteType)) {
(!isRemote || aBrowser.getAttribute("remoteType") == aOptions.remoteType) &&
!aBrowser.frameLoader.isFreshProcess) {
return false;
}
@ -1835,7 +1836,8 @@
E10SUtils.getRemoteTypeForURI(aURL, gMultiProcessBrowser,
currentRemoteType);
if (currentRemoteType != aOptions.remoteType ||
aOptions.freshProcess || aOptions.newFrameloader) {
aOptions.freshProcess || aOptions.newFrameloader ||
aBrowser.frameLoader.isFreshProcess) {
let remote = aOptions.remoteType != E10SUtils.NOT_REMOTE;
return this.updateBrowserRemoteness(aBrowser, remote, aOptions);
}

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

@ -152,6 +152,13 @@ this.E10SUtils = {
if (aDocShell.QueryInterface(Ci.nsIDocShellTreeItem).sameTypeParent)
return true;
// If we are in a fresh process, and it wouldn't be content visible to
// change processes, we want to load into a new process so that we can throw
// this one out.
if (aDocShell.inFreshProcess && aDocShell.isOnlyToplevelInTabGroup) {
return false;
}
// If the URI can be loaded in the current process then continue
return this.shouldLoadURIInThisProcess(aURI);
},

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

@ -14758,3 +14758,10 @@ nsDocShell::GetIsOnlyToplevelInTabGroup(bool* aResult)
*aResult = true;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetInFreshProcess(bool* aResult)
{
*aResult = TabChild::GetWasFreshProcess();
return NS_OK;
}

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

@ -1124,4 +1124,9 @@ interface nsIDocShell : nsIDocShellTreeItem
* occuring in this docshell to be performed within a different docshell.
*/
[infallible] readonly attribute boolean isOnlyToplevelInTabGroup;
/**
* Returns `true` if this docshell was created by a Large-Allocation load.
*/
[infallible] readonly attribute boolean inFreshProcess;
};

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

@ -3668,6 +3668,13 @@ nsFrameLoader::GetIsDead(bool* aIsDead)
return NS_OK;
}
NS_IMETHODIMP
nsFrameLoader::GetIsFreshProcess(bool* aIsFreshProcess)
{
*aIsFreshProcess = mFreshProcess;
return NS_OK;
}
nsIMessageSender*
nsFrameLoader::GetProcessMessageManager() const
{

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

@ -268,6 +268,12 @@ interface nsIFrameLoader : nsISupports
* Is `true` if the frameloader is dead (destroy has been called on it)
*/
[infallible] readonly attribute boolean isDead;
/**
* Is `true` if the <xul:browser> which created this frameloader had the
* freshProcess attribute set when it was created.
*/
[infallible] readonly attribute boolean isFreshProcess;
};
%{C++

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

@ -157,6 +157,7 @@ static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
static TabChildMap* sTabChildren;
bool TabChild::sWasFreshProcess = false;
TabChildBase::TabChildBase()
: mTabChildGlobal(nullptr)
@ -3070,6 +3071,7 @@ TabChild::RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
mozilla::ipc::IPCResult
TabChild::RecvSetFreshProcess()
{
MOZ_ASSERT(!sWasFreshProcess, "Can only be a fresh process once!");
mIsFreshProcess = true;
return IPC_OK();
}

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

@ -660,15 +660,28 @@ public:
bool TakeIsFreshProcess()
{
bool wasFreshProcess = mIsFreshProcess;
mIsFreshProcess = false;
return wasFreshProcess;
if (mIsFreshProcess) {
MOZ_ASSERT(!sWasFreshProcess,
"At most one tabGroup may be a fresh process per process");
sWasFreshProcess = true;
mIsFreshProcess = false;
return true;
}
return false;
}
already_AddRefed<nsISHistory> GetRelatedSHistory();
mozilla::dom::TabGroup* TabGroup();
// Returns `true` if this this process was created to load a docshell in a
// "Fresh Process". This value is initialized to `false`, and is set to `true`
// in RecvSetFreshProcess.
static bool GetWasFreshProcess()
{
return sWasFreshProcess;
}
protected:
virtual ~TabChild();
@ -818,6 +831,8 @@ private:
uintptr_t mNativeWindowHandle;
#endif // defined(XP_WIN)
static bool sWasFreshProcess;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};

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

@ -153,7 +153,9 @@ add_task(function*() {
let pid3 = yield getPID(aBrowser);
is(pid2, pid3);
// We should have been kicked out of the large-allocation process by the
// load, meaning we're back in the first process.
is(pid1, pid3); // XXX: This may be flakey in multiple content process e10s?
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.document.location = TEST_URI;
@ -197,18 +199,26 @@ add_task(function*() {
let pid3 = yield getPID(aBrowser);
is(pid2, pid3, "PIDs 2 and 3 should match");
// We should have been kicked out of the large-allocation process by the
// load, meaning we're back in the first process.
is(pid1, pid3, "PIDs 1 and 3 should match");
// Navigate back to the previous page, loading it from bfcache
stopExpectNoProcess();
epc = expectProcessCreated();
// Navigate back to the previous page. As the large alloation process was
// left, it won't be in bfcache and will have to be loaded fresh.
yield ContentTask.spawn(aBrowser, TEST_URI, TEST_URI => {
content.window.history.back();
});
yield epc;
let pid4 = yield getPID(aBrowser);
isnot(pid1, pid4, "PID 4 shouldn't match PID 1");
is(pid2, pid4, "PID 4 should match PID 2");
isnot(pid2, pid4, "PID 4 shouldn't match PID 2");
stopExpectNoProcess();
});
});