Bug 1147911 Part 8: Create separate content process for file:// URIs. r=gabor, r=gijs, r=smaug

This commit is contained in:
Bob Owen 2016-11-17 15:48:53 +00:00
Родитель ce1bc7d820
Коммит 52529cb9a9
5 изменённых файлов: 72 добавлений и 50 удалений

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

@ -26,13 +26,20 @@ function getAboutModule(aURL) {
const NOT_REMOTE = null; const NOT_REMOTE = null;
const WEB_REMOTE_TYPE = "web"; const WEB_REMOTE_TYPE = "web";
const FILE_REMOTE_TYPE = "file";
// This must match the one in ContentParent.h. // This must match the one in ContentParent.h.
const DEFAULT_REMOTE_TYPE = WEB_REMOTE_TYPE; const DEFAULT_REMOTE_TYPE = WEB_REMOTE_TYPE;
function validatedWebRemoteType(aPreferredRemoteType) {
return aPreferredRemoteType && aPreferredRemoteType.startsWith(WEB_REMOTE_TYPE)
? aPreferredRemoteType : WEB_REMOTE_TYPE;
}
this.E10SUtils = { this.E10SUtils = {
DEFAULT_REMOTE_TYPE, DEFAULT_REMOTE_TYPE,
NOT_REMOTE, NOT_REMOTE,
WEB_REMOTE_TYPE, WEB_REMOTE_TYPE,
FILE_REMOTE_TYPE,
canLoadURIInProcess: function(aURL, aProcess) { canLoadURIInProcess: function(aURL, aProcess) {
let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
@ -55,6 +62,11 @@ this.E10SUtils = {
return aPreferredRemoteType; return aPreferredRemoteType;
} }
if (aURL.startsWith("file:")) {
return Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess")
? FILE_REMOTE_TYPE : DEFAULT_REMOTE_TYPE;
}
if (aURL.startsWith("about:")) { if (aURL.startsWith("about:")) {
// We need to special case about:blank because it needs to load in any. // We need to special case about:blank because it needs to load in any.
if (aURL == "about:blank") { if (aURL == "about:blank") {
@ -115,7 +127,7 @@ this.E10SUtils = {
aMultiProcess, aPreferredRemoteType); aMultiProcess, aPreferredRemoteType);
} }
return WEB_REMOTE_TYPE; return validatedWebRemoteType(aPreferredRemoteType);
}, },
shouldLoadURIInThisProcess: function(aURI) { shouldLoadURIInThisProcess: function(aURI) {

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

@ -23,7 +23,7 @@ add_task(function* () {
// We need a file remote type to make sure we don't switch processes when we // We need a file remote type to make sure we don't switch processes when we
// load the file:// URI. // load the file:// URI.
let { browser } = yield loadTab("about:blank", "file"); let { browser } = yield loadTab("about:blank", E10SUtils.FILE_REMOTE_TYPE);
hud = yield openConsole(); hud = yield openConsole();
hud.jsterm.clearOutput(); hud.jsterm.clearOutput();

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

@ -494,8 +494,7 @@ ContentParentsMemoryReporter::CollectReports(
return NS_OK; return NS_OK;
} }
nsTArray<ContentParent*>* ContentParent::sBrowserContentParents; nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
nsTArray<ContentParent*>* ContentParent::sPrivateContent; nsTArray<ContentParent*>* ContentParent::sPrivateContent;
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents; StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX) #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
@ -648,24 +647,22 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
ContentParent* aOpener, ContentParent* aOpener,
bool aLargeAllocationProcess) bool aLargeAllocationProcess)
{ {
nsTArray<ContentParent*>* contentParents; if (!sBrowserContentParents) {
int32_t maxContentParents; sBrowserContentParents =
new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
}
// Decide which pool of content parents we are going to be pulling from based // Decide which pool of content parents we are going to be pulling from based
// on the aLargeAllocationProcess flag. // on the aRemoteType and aLargeAllocationProcess flag.
if (aLargeAllocationProcess) { nsAutoString contentProcessType(aLargeAllocationProcess
if (!sLargeAllocationContentParents) { ? LARGE_ALLOCATION_REMOTE_TYPE : aRemoteType);
sLargeAllocationContentParents = new nsTArray<ContentParent*>(); nsTArray<ContentParent*>* contentParents =
} sBrowserContentParents->LookupOrAdd(contentProcessType);
contentParents = sLargeAllocationContentParents;
maxContentParents = Preferences::GetInt("dom.ipc.dedicatedProcessCount", 2);
} else {
if (!sBrowserContentParents) {
sBrowserContentParents = new nsTArray<ContentParent*>();
}
contentParents = sBrowserContentParents;
int32_t maxContentParents;
nsAutoCString processCountPref("dom.ipc.processCount.");
processCountPref.Append(NS_ConvertUTF16toUTF8(contentProcessType));
if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1); maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
} }
@ -688,7 +685,7 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
} while (currIdx != startIdx); } while (currIdx != startIdx);
} }
RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType); RefPtr<ContentParent> p = new ContentParent(aOpener, contentProcessType);
if (!p->LaunchSubprocess(aPriority)) { if (!p->LaunchSubprocess(aPriority)) {
return nullptr; return nullptr;
@ -696,8 +693,6 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
p->Init(); p->Init();
p->mLargeAllocationProcess = aLargeAllocationProcess;
p->ForwardKnownInfo(); p->ForwardKnownInfo();
contentParents->AppendElement(p); contentParents->AppendElement(p);
@ -1308,18 +1303,17 @@ void
ContentParent::MarkAsDead() ContentParent::MarkAsDead()
{ {
if (sBrowserContentParents) { if (sBrowserContentParents) {
sBrowserContentParents->RemoveElement(this); nsTArray<ContentParent*>* contentParents =
if (!sBrowserContentParents->Length()) { sBrowserContentParents->Get(mRemoteType);
delete sBrowserContentParents; if (contentParents) {
sBrowserContentParents = nullptr; contentParents->RemoveElement(this);
} if (contentParents->IsEmpty()) {
} sBrowserContentParents->Remove(mRemoteType);
if (sBrowserContentParents->IsEmpty()) {
if (sLargeAllocationContentParents) { delete sBrowserContentParents;
sLargeAllocationContentParents->RemoveElement(this); sBrowserContentParents = nullptr;
if (!sLargeAllocationContentParents->Length()) { }
delete sLargeAllocationContentParents; }
sLargeAllocationContentParents = nullptr;
} }
} }
@ -1648,10 +1642,13 @@ ContentParent::NotifyTabDestroying(const TabId& aTabId,
return; return;
} }
uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0; if (sBrowserContentParents && cp->mRemoteType.Equals(DEFAULT_REMOTE_TYPE)) {
int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0); auto contentParents = sBrowserContentParents->Get(cp->mRemoteType);
if (!cp->mLargeAllocationProcess && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive) { int32_t numberOfParents = contentParents ? contentParents->Length() : 0;
return; int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
if (numberOfParents <= processesToKeepAlive) {
return;
}
} }
// We're dying now, so prevent this content process from being // We're dying now, so prevent this content process from being
@ -1705,10 +1702,13 @@ ContentParent::NotifyTabDestroyed(const TabId& aTabId,
// We might want to keep alive some content processes for testing, because of performance // We might want to keep alive some content processes for testing, because of performance
// reasons, but we don't want to alter behavior if the pref is not set. // reasons, but we don't want to alter behavior if the pref is not set.
uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0; bool shouldKeepAliveThis = false;
int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0); if (sBrowserContentParents && mRemoteType.Equals(DEFAULT_REMOTE_TYPE)) {
bool shouldKeepAliveAny = !mLargeAllocationProcess && processesToKeepAlive > 0; auto contentParents = sBrowserContentParents->Get(mRemoteType);
bool shouldKeepAliveThis = shouldKeepAliveAny && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive; int32_t numberOfParents = contentParents ? contentParents->Length() : 0;
int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
shouldKeepAliveThis = numberOfParents <= processesToKeepAlive;
}
if (tabIds.Length() == 1 && !shouldKeepAliveThis) { if (tabIds.Length() == 1 && !shouldKeepAliveThis) {
// In the case of normal shutdown, send a shutdown message to child to // In the case of normal shutdown, send a shutdown message to child to
@ -1800,7 +1800,6 @@ ContentParent::ContentParent(ContentParent* aOpener,
, mOpener(aOpener) , mOpener(aOpener)
, mRemoteType(aRemoteType) , mRemoteType(aRemoteType)
, mIsForBrowser(!mRemoteType.IsEmpty()) , mIsForBrowser(!mRemoteType.IsEmpty())
, mLargeAllocationProcess(false)
{ {
InitializeMembers(); // Perform common initialization. InitializeMembers(); // Perform common initialization.
@ -1838,10 +1837,9 @@ ContentParent::~ContentParent()
// We should be removed from all these lists in ActorDestroy. // We should be removed from all these lists in ActorDestroy.
MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this)); MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
MOZ_ASSERT((!sBrowserContentParents || MOZ_ASSERT(!sBrowserContentParents ||
!sBrowserContentParents->Contains(this)) && !sBrowserContentParents->Contains(mRemoteType) ||
(!sLargeAllocationContentParents || !sBrowserContentParents->Get(mRemoteType)->Contains(this));
!sLargeAllocationContentParents->Contains(this)));
} }
void void

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

@ -87,6 +87,9 @@ class GetFilesHelper;
// This must match the one in E10SUtils.jsm. // This must match the one in E10SUtils.jsm.
static NS_NAMED_LITERAL_STRING(DEFAULT_REMOTE_TYPE, "web"); static NS_NAMED_LITERAL_STRING(DEFAULT_REMOTE_TYPE, "web");
// This must start with the DEFAULT_REMOTE_TYPE above.
static NS_NAMED_LITERAL_STRING(LARGE_ALLOCATION_REMOTE_TYPE,
"webLargeAllocation");
static NS_NAMED_LITERAL_STRING(NO_REMOTE_TYPE, ""); static NS_NAMED_LITERAL_STRING(NO_REMOTE_TYPE, "");
class ContentParent final : public PContentParent class ContentParent final : public PContentParent
@ -554,8 +557,7 @@ protected:
void OnCompositorUnexpectedShutdown() override; void OnCompositorUnexpectedShutdown() override;
private: private:
static nsTArray<ContentParent*>* sBrowserContentParents; static nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* sBrowserContentParents;
static nsTArray<ContentParent*>* sLargeAllocationContentParents;
static nsTArray<ContentParent*>* sPrivateContent; static nsTArray<ContentParent*>* sPrivateContent;
static StaticAutoPtr<LinkedList<ContentParent> > sContentParents; static StaticAutoPtr<LinkedList<ContentParent> > sContentParents;
@ -1152,7 +1154,6 @@ private:
nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests; nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests;
nsTArray<nsCString> mBlobURLs; nsTArray<nsCString> mBlobURLs;
bool mLargeAllocationProcess;
}; };
} // namespace dom } // namespace dom

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

@ -2866,6 +2866,17 @@ pref("dom.ipc.plugins.asyncdrawing.enabled", true);
pref("dom.ipc.processCount", 1); pref("dom.ipc.processCount", 1);
// Override default dom.ipc.processCount for some remote content process types.
pref("dom.ipc.processCount.webLargeAllocation", 2);
// Pref to control whether we use separate content processes for top-level load
// of file:// URIs.
#if defined(NIGHTLY_BUILD)
pref("browser.tabs.remote.separateFileUriProcess", true);
#else
pref("browser.tabs.remote.separateFileUriProcess", false);
#endif
// Enable caching of Moz2D Path objects for SVG geometry elements // Enable caching of Moz2D Path objects for SVG geometry elements
pref("svg.path-caching.enabled", true); pref("svg.path-caching.enabled", true);