mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1147911 Part 8: Create separate content process for file:// URIs. r=gabor, r=gijs, r=smaug
This commit is contained in:
parent
3f62d10e4d
commit
fd9634b56e
@ -30,13 +30,20 @@ function getAboutModule(aURL) {
|
||||
|
||||
const NOT_REMOTE = null;
|
||||
const WEB_REMOTE_TYPE = "web";
|
||||
const FILE_REMOTE_TYPE = "file";
|
||||
// This must match the one in ContentParent.h.
|
||||
const DEFAULT_REMOTE_TYPE = WEB_REMOTE_TYPE;
|
||||
|
||||
function validatedWebRemoteType(aPreferredRemoteType) {
|
||||
return aPreferredRemoteType && aPreferredRemoteType.startsWith(WEB_REMOTE_TYPE)
|
||||
? aPreferredRemoteType : WEB_REMOTE_TYPE;
|
||||
}
|
||||
|
||||
this.E10SUtils = {
|
||||
DEFAULT_REMOTE_TYPE,
|
||||
NOT_REMOTE,
|
||||
WEB_REMOTE_TYPE,
|
||||
FILE_REMOTE_TYPE,
|
||||
|
||||
canLoadURIInProcess: function(aURL, aProcess) {
|
||||
let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
|
||||
@ -67,6 +74,11 @@ this.E10SUtils = {
|
||||
: aPreferredRemoteType;
|
||||
}
|
||||
|
||||
if (aURL.startsWith("file:")) {
|
||||
return Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess")
|
||||
? FILE_REMOTE_TYPE : DEFAULT_REMOTE_TYPE;
|
||||
}
|
||||
|
||||
if (aURL.startsWith("about:")) {
|
||||
// We need to special case about:blank because it needs to load in any.
|
||||
if (aURL == "about:blank") {
|
||||
@ -127,7 +139,7 @@ this.E10SUtils = {
|
||||
aMultiProcess, aPreferredRemoteType);
|
||||
}
|
||||
|
||||
return WEB_REMOTE_TYPE;
|
||||
return validatedWebRemoteType(aPreferredRemoteType);
|
||||
},
|
||||
|
||||
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
|
||||
// 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.jsterm.clearOutput();
|
||||
|
@ -498,8 +498,7 @@ ContentParentsMemoryReporter::CollectReports(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTArray<ContentParent*>* ContentParent::sBrowserContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
|
||||
nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
|
||||
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
|
||||
StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
|
||||
#if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
@ -648,24 +647,22 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
|
||||
ContentParent* aOpener,
|
||||
bool aLargeAllocationProcess)
|
||||
{
|
||||
nsTArray<ContentParent*>* contentParents;
|
||||
int32_t maxContentParents;
|
||||
if (!sBrowserContentParents) {
|
||||
sBrowserContentParents =
|
||||
new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
|
||||
}
|
||||
|
||||
// Decide which pool of content parents we are going to be pulling from based
|
||||
// on the aLargeAllocationProcess flag.
|
||||
if (aLargeAllocationProcess) {
|
||||
if (!sLargeAllocationContentParents) {
|
||||
sLargeAllocationContentParents = new nsTArray<ContentParent*>();
|
||||
}
|
||||
contentParents = sLargeAllocationContentParents;
|
||||
|
||||
maxContentParents = Preferences::GetInt("dom.ipc.dedicatedProcessCount", 2);
|
||||
} else {
|
||||
if (!sBrowserContentParents) {
|
||||
sBrowserContentParents = new nsTArray<ContentParent*>();
|
||||
}
|
||||
contentParents = sBrowserContentParents;
|
||||
// on the aRemoteType and aLargeAllocationProcess flag.
|
||||
nsAutoString contentProcessType(aLargeAllocationProcess
|
||||
? LARGE_ALLOCATION_REMOTE_TYPE : aRemoteType);
|
||||
nsTArray<ContentParent*>* contentParents =
|
||||
sBrowserContentParents->LookupOrAdd(contentProcessType);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -688,7 +685,7 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
|
||||
} while (currIdx != startIdx);
|
||||
}
|
||||
|
||||
RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType);
|
||||
RefPtr<ContentParent> p = new ContentParent(aOpener, contentProcessType);
|
||||
|
||||
if (!p->LaunchSubprocess(aPriority)) {
|
||||
return nullptr;
|
||||
@ -696,8 +693,6 @@ ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
|
||||
|
||||
p->Init();
|
||||
|
||||
p->mLargeAllocationProcess = aLargeAllocationProcess;
|
||||
|
||||
contentParents->AppendElement(p);
|
||||
return p.forget();
|
||||
}
|
||||
@ -1288,18 +1283,17 @@ void
|
||||
ContentParent::MarkAsDead()
|
||||
{
|
||||
if (sBrowserContentParents) {
|
||||
sBrowserContentParents->RemoveElement(this);
|
||||
if (!sBrowserContentParents->Length()) {
|
||||
delete sBrowserContentParents;
|
||||
sBrowserContentParents = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (sLargeAllocationContentParents) {
|
||||
sLargeAllocationContentParents->RemoveElement(this);
|
||||
if (!sLargeAllocationContentParents->Length()) {
|
||||
delete sLargeAllocationContentParents;
|
||||
sLargeAllocationContentParents = nullptr;
|
||||
nsTArray<ContentParent*>* contentParents =
|
||||
sBrowserContentParents->Get(mRemoteType);
|
||||
if (contentParents) {
|
||||
contentParents->RemoveElement(this);
|
||||
if (contentParents->IsEmpty()) {
|
||||
sBrowserContentParents->Remove(mRemoteType);
|
||||
if (sBrowserContentParents->IsEmpty()) {
|
||||
delete sBrowserContentParents;
|
||||
sBrowserContentParents = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1607,6 +1601,38 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::ShouldKeepProcessAlive() const
|
||||
{
|
||||
if (!sBrowserContentParents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have already been marked as dead, don't prevent shutdown.
|
||||
if (!IsAlive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only keep processes for the default remote type alive.
|
||||
if (!mRemoteType.Equals(DEFAULT_REMOTE_TYPE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto contentParents = sBrowserContentParents->Get(mRemoteType);
|
||||
if (!contentParents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We might want to keep alive some content processes for testing, because of
|
||||
// performance reasons.
|
||||
// We don't want to alter behavior if the pref is not set, so default to 0.
|
||||
int32_t processesToKeepAlive =
|
||||
Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
|
||||
int32_t numberOfAliveProcesses = contentParents->Length();
|
||||
|
||||
return numberOfAliveProcesses <= processesToKeepAlive;
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::NotifyTabDestroying(const TabId& aTabId,
|
||||
const ContentParentId& aCpId)
|
||||
@ -1628,9 +1654,7 @@ ContentParent::NotifyTabDestroying(const TabId& aTabId,
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
|
||||
int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
|
||||
if (!cp->mLargeAllocationProcess && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive) {
|
||||
if (cp->ShouldKeepProcessAlive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1683,14 +1707,7 @@ ContentParent::NotifyTabDestroyed(const TabId& aTabId,
|
||||
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
|
||||
nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
|
||||
|
||||
// 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.
|
||||
uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
|
||||
int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
|
||||
bool shouldKeepAliveAny = !mLargeAllocationProcess && processesToKeepAlive > 0;
|
||||
bool shouldKeepAliveThis = shouldKeepAliveAny && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive;
|
||||
|
||||
if (tabIds.Length() == 1 && !shouldKeepAliveThis) {
|
||||
if (tabIds.Length() == 1 && !ShouldKeepProcessAlive()) {
|
||||
// In the case of normal shutdown, send a shutdown message to child to
|
||||
// allow it to perform shutdown tasks.
|
||||
MessageLoop::current()->PostTask(NewRunnableMethod
|
||||
@ -1779,7 +1796,6 @@ ContentParent::ContentParent(ContentParent* aOpener,
|
||||
, mOpener(aOpener)
|
||||
, mRemoteType(aRemoteType)
|
||||
, mIsForBrowser(!mRemoteType.IsEmpty())
|
||||
, mLargeAllocationProcess(false)
|
||||
{
|
||||
InitializeMembers(); // Perform common initialization.
|
||||
|
||||
@ -1815,10 +1831,9 @@ ContentParent::~ContentParent()
|
||||
|
||||
// We should be removed from all these lists in ActorDestroy.
|
||||
MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
|
||||
MOZ_ASSERT((!sBrowserContentParents ||
|
||||
!sBrowserContentParents->Contains(this)) &&
|
||||
(!sLargeAllocationContentParents ||
|
||||
!sLargeAllocationContentParents->Contains(this)));
|
||||
MOZ_ASSERT(!sBrowserContentParents ||
|
||||
!sBrowserContentParents->Contains(mRemoteType) ||
|
||||
!sBrowserContentParents->Get(mRemoteType)->Contains(this));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -87,6 +87,9 @@ class GetFilesHelper;
|
||||
|
||||
// This must match the one in E10SUtils.jsm.
|
||||
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, "");
|
||||
|
||||
class ContentParent final : public PContentParent
|
||||
@ -571,8 +574,7 @@ protected:
|
||||
void OnCompositorUnexpectedShutdown() override;
|
||||
|
||||
private:
|
||||
static nsTArray<ContentParent*>* sBrowserContentParents;
|
||||
static nsTArray<ContentParent*>* sLargeAllocationContentParents;
|
||||
static nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* sBrowserContentParents;
|
||||
static nsTArray<ContentParent*>* sPrivateContent;
|
||||
static StaticAutoPtr<LinkedList<ContentParent> > sContentParents;
|
||||
|
||||
@ -645,6 +647,12 @@ private:
|
||||
// unlikely that the process will be killed after this point.
|
||||
bool SetPriorityAndCheckIsAlive(hal::ProcessPriority aPriority);
|
||||
|
||||
/**
|
||||
* Decide whether the process should be kept alive even when it would normally
|
||||
* be shut down, for example when all its tabs are closed.
|
||||
*/
|
||||
bool ShouldKeepProcessAlive() const;
|
||||
|
||||
/**
|
||||
* Mark this ContentParent as dead for the purposes of Get*().
|
||||
* This method is idempotent.
|
||||
@ -1158,7 +1166,6 @@ private:
|
||||
nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests;
|
||||
|
||||
nsTArray<nsCString> mBlobURLs;
|
||||
bool mLargeAllocationProcess;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -2866,6 +2866,17 @@ pref("dom.ipc.plugins.asyncdrawing.enabled", true);
|
||||
|
||||
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
|
||||
pref("svg.path-caching.enabled", true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user