Bug 1508306 - Part 1: Migate the Large-Allocation handler to DocumentLoadListener, r=mattwoodrow,necko-reviewers,geckoview-reviewers,agi,valentin

This removes the diagnostic warnings which used to be logged when the
Large-Allocation header was present, but failed to switch into a
Large-Allocation process. Due to the low adoption of the header, this shouldn't
be too large of a problem, but we can look into re-adding the diagnostics if
needed in the future.

The new codepath no longer performs multiple network requests for
Large-Allocation resources, and now relies on the battle-tested
DocumentLoadListener codepath for process switching.

Differential Revision: https://phabricator.services.mozilla.com/D78998
This commit is contained in:
Nika Layzell 2020-06-15 23:24:07 +00:00
parent 5b6ea0f456
commit cde53b3bec
23 changed files with 53 additions and 458 deletions

View File

@ -1636,21 +1636,6 @@ function RedirectLoad(browser, data) {
data.loadOptions.newFrameloader = true;
}
if (data.loadOptions.reloadInFreshProcess) {
// Convert the fresh process load option into a large allocation remote type
// to use common processing from this point.
data.loadOptions.remoteType = E10SUtils.LARGE_ALLOCATION_REMOTE_TYPE;
data.loadOptions.newFrameloader = true;
} else if (browser.remoteType == E10SUtils.LARGE_ALLOCATION_REMOTE_TYPE) {
// If we're in a Large-Allocation process, we prefer switching back into a
// normal content process, as that way we can clean up the L-A process.
data.loadOptions.remoteType = E10SUtils.getRemoteTypeForURI(
data.loadOptions.uri,
gMultiProcessBrowser,
gFissionBrowser
);
}
// We should only start the redirection if the browser window has finished
// starting up. Otherwise, we should wait until the startup is done.
if (gBrowserInit.delayedStartupFinished) {
@ -5114,7 +5099,6 @@ var XULBrowserWindow = {
aURI,
aReferrerInfo,
aTriggeringPrincipal,
false,
null,
aCsp
);

View File

@ -54,7 +54,6 @@ var WebBrowserChrome = {
aURI,
aReferrerInfo,
aTriggeringPrincipal,
false,
null,
aCsp
);
@ -69,27 +68,6 @@ var WebBrowserChrome = {
.useRemoteSubframes;
return E10SUtils.shouldLoadURIInThisProcess(aURI, remoteSubframes);
},
// Try to reload the currently active or currently loading page in a new process.
reloadInFreshProcess(
aDocShell,
aURI,
aReferrerInfo,
aTriggeringPrincipal,
aLoadFlags,
aCsp
) {
E10SUtils.redirectLoad(
aDocShell,
aURI,
aReferrerInfo,
aTriggeringPrincipal,
true,
aLoadFlags,
aCsp
);
return true;
},
};
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {

View File

@ -174,27 +174,4 @@ class WebBrowserChrome {
shouldLoadURIInThisProcess(uri) {
return this.ssb.canLoad(uri);
}
/**
* Instructs us to start a fresh process to load this URI. Usually used for
* large allocation sites. SSB does not support this.
*
* @param {nsIDocShell} docShell the current docshell.
* @param {nsIURI} uri the URI that will be loaded.
* @param {nsIReferrerInfo} referrerInfo the referrer info.
* @param {nsIPrincipal} triggeringPrincipal the triggering principal.
* @param {Number} loadFlags the load flags.
* @param {nsIContentSecurityPolicy} csp the content security policy.
* @return {boolean} whether the load should proceed or not.
*/
reloadInFreshProcess(
docShell,
uri,
referrerInfo,
triggeringPrincipal,
loadFlags,
csp
) {
return false;
}
}

View File

@ -12391,19 +12391,6 @@ nsCommandManager* nsDocShell::GetCommandManager() {
return mCommandManager;
}
NS_IMETHODIMP
nsDocShell::GetAwaitingLargeAlloc(bool* aResult) {
MOZ_ASSERT(aResult);
nsCOMPtr<nsIBrowserChild> browserChild = GetBrowserChild();
if (!browserChild) {
*aResult = false;
return NS_OK;
}
*aResult =
static_cast<BrowserChild*>(browserChild.get())->IsAwaitingLargeAlloc();
return NS_OK;
}
NS_IMETHODIMP_(void)
nsDocShell::GetOriginAttributes(mozilla::OriginAttributes& aAttrs) {
mBrowsingContext->GetOriginAttributes(aAttrs);

View File

@ -892,12 +892,6 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
[infallible] attribute nsIDocShell_MetaViewportOverride metaViewportOverride;
/**
* Returns `true` if this docshell was created due to a Large-Allocation
* header, and has not seen the initiating load yet.
*/
[infallible] readonly attribute boolean awaitingLargeAlloc;
/**
* Attribute that determines whether tracking protection is enabled.
*/

View File

@ -9334,149 +9334,6 @@ void nsContentUtils::EnqueueLifecycleCallback(
aType, aCustomElement, aArgs, aAdoptedCallbackArgs, aDefinition);
}
/* static */
bool nsContentUtils::AttemptLargeAllocationLoad(nsIHttpChannel* aChannel) {
MOZ_ASSERT(aChannel);
nsCOMPtr<nsILoadGroup> loadGroup;
nsresult rv = aChannel->GetLoadGroup(getter_AddRefs(loadGroup));
if (NS_WARN_IF(NS_FAILED(rv) || !loadGroup)) {
return false;
}
nsCOMPtr<nsIInterfaceRequestor> callbacks;
rv = loadGroup->GetNotificationCallbacks(getter_AddRefs(callbacks));
if (NS_WARN_IF(NS_FAILED(rv) || !callbacks)) {
return false;
}
nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(callbacks);
if (NS_WARN_IF(!loadContext)) {
return false;
}
nsCOMPtr<mozIDOMWindowProxy> window;
rv = loadContext->GetAssociatedWindow(getter_AddRefs(window));
if (NS_WARN_IF(NS_FAILED(rv) || !window)) {
return false;
}
nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::From(window);
if (NS_WARN_IF(!outer)) {
return false;
}
if (!XRE_IsContentProcess()) {
outer->SetLargeAllocStatus(LargeAllocStatus::NON_E10S);
return false;
}
nsIDocShell* docShell = outer->GetDocShell();
BrowsingContext* browsingContext = docShell->GetBrowsingContext();
bool isOnlyToplevelBrowsingContext =
browsingContext->IsTop() &&
browsingContext->Group()->Toplevels().Length() == 1;
if (!isOnlyToplevelBrowsingContext) {
outer->SetLargeAllocStatus(LargeAllocStatus::NOT_ONLY_TOPLEVEL_IN_TABGROUP);
return false;
}
// Get the request method, and check if it is a GET request. If it is not GET,
// then we cannot perform a large allocation load.
nsAutoCString requestMethod;
rv = aChannel->GetRequestMethod(requestMethod);
NS_ENSURE_SUCCESS(rv, false);
if (NS_WARN_IF(!requestMethod.LowerCaseEqualsLiteral("get"))) {
outer->SetLargeAllocStatus(LargeAllocStatus::NON_GET);
return false;
}
BrowserChild* browserChild = BrowserChild::GetFrom(outer);
NS_ENSURE_TRUE(browserChild, false);
if (browserChild->IsAwaitingLargeAlloc()) {
NS_WARNING(
"In a Large-Allocation BrowserChild, ignoring Large-Allocation "
"header!");
browserChild->StopAwaitingLargeAlloc();
outer->SetLargeAllocStatus(LargeAllocStatus::SUCCESS);
return false;
}
// On Win32 systems, we want to behave differently, so set the isWin32 bool to
// be true iff we are on win32.
#if defined(XP_WIN) && defined(_X86_)
const bool isWin32 = true;
#else
const bool isWin32 = false;
#endif
// We want to enable the large allocation header on 32-bit windows machines,
// and disable it on other machines, while still printing diagnostic messages.
// dom.largeAllocation.forceEnable can allow you to enable the process
// switching behavior of the Large-Allocation header on non 32-bit windows
// machines.
bool largeAllocEnabled =
isWin32 || StaticPrefs::dom_largeAllocation_forceEnable();
if (!largeAllocEnabled) {
NS_WARNING(
"dom.largeAllocation.forceEnable not set - "
"ignoring otherwise successful Large-Allocation header.");
// On platforms which aren't WIN32, we don't activate the largeAllocation
// header, instead we simply emit diagnostics into the console.
outer->SetLargeAllocStatus(LargeAllocStatus::NON_WIN32);
return false;
}
// At this point the fress process load should succeed! We just need to get
// ourselves a nsIWebBrowserChrome3 to ask to perform the reload. We should
// have one, as we have already confirmed that we are running in a content
// process.
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
NS_ENSURE_TRUE(treeOwner, false);
nsCOMPtr<nsIWebBrowserChrome3> wbc3 = do_GetInterface(treeOwner);
NS_ENSURE_TRUE(wbc3, false);
nsCOMPtr<nsIURI> uri;
rv = aChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(uri, false);
nsCOMPtr<nsIReferrerInfo> referrerInfo;
rv = aChannel->GetReferrerInfo(getter_AddRefs(referrerInfo));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
nsCOMPtr<nsIPrincipal> triggeringPrincipal = loadInfo->TriggeringPrincipal();
nsCOMPtr<nsIContentSecurityPolicy> csp = loadInfo->GetCspToInherit();
// Get the channel's load flags, and use them to generate nsIWebNavigation
// load flags. We want to make sure to propagate the refresh and cache busting
// flags.
nsLoadFlags channelLoadFlags;
aChannel->GetLoadFlags(&channelLoadFlags);
uint32_t webnavLoadFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
if (channelLoadFlags & nsIRequest::LOAD_BYPASS_CACHE) {
webnavLoadFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE;
webnavLoadFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
} else if (channelLoadFlags & nsIRequest::VALIDATE_ALWAYS) {
webnavLoadFlags |= nsIWebNavigation::LOAD_FLAGS_IS_REFRESH;
}
// Actually perform the cross process load
bool reloadSucceeded = false;
rv = wbc3->ReloadInFreshProcess(docShell, uri, referrerInfo,
triggeringPrincipal, webnavLoadFlags, csp,
&reloadSucceeded);
NS_ENSURE_SUCCESS(rv, false);
return reloadSucceeded;
}
/* static */
void nsContentUtils::AppendDocumentLevelNativeAnonymousContentTo(
Document* aDocument, nsTArray<nsIContent*>& aElements) {

View File

@ -3042,8 +3042,6 @@ class nsContentUtils {
nullptr,
mozilla::dom::CustomElementDefinition* aDefinition = nullptr);
static bool AttemptLargeAllocationLoad(nsIHttpChannel* aChannel);
/**
* Appends all "document level" native anonymous content subtree roots for
* aDocument to aElements. Document level NAC subtrees are those created

View File

@ -2458,11 +2458,6 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
PreloadLocalStorage();
// If we have a recorded interesting Large-Allocation header status, report it
// to the newly attached document.
ReportLargeAllocStatus();
mLargeAllocStatus = LargeAllocStatus::NONE;
mStorageAccessPermissionGranted =
CheckStorageAccessPermission(aDocument, newInnerWindow);
@ -7475,11 +7470,6 @@ int16_t nsGlobalWindowOuter::Orientation(CallerType aCallerType) const {
}
#endif
void nsPIDOMWindowOuter::SetLargeAllocStatus(LargeAllocStatus aStatus) {
MOZ_ASSERT(mLargeAllocStatus == LargeAllocStatus::NONE);
mLargeAllocStatus = aStatus;
}
bool nsPIDOMWindowOuter::IsTopLevelWindow() {
return nsGlobalWindowOuter::Cast(this)->IsTopLevelWindow();
}
@ -7488,38 +7478,6 @@ bool nsPIDOMWindowOuter::HadOriginalOpener() const {
return nsGlobalWindowOuter::Cast(this)->HadOriginalOpener();
}
void nsGlobalWindowOuter::ReportLargeAllocStatus() {
uint32_t errorFlags = nsIScriptError::warningFlag;
const char* message = nullptr;
switch (mLargeAllocStatus) {
case LargeAllocStatus::SUCCESS:
// Override the error flags such that the success message isn't reported
// as a warning.
errorFlags = nsIScriptError::infoFlag;
message = "LargeAllocationSuccess";
break;
case LargeAllocStatus::NON_WIN32:
errorFlags = nsIScriptError::infoFlag;
message = "LargeAllocationNonWin32";
break;
case LargeAllocStatus::NON_GET:
message = "LargeAllocationNonGetRequest";
break;
case LargeAllocStatus::NON_E10S:
message = "LargeAllocationNonE10S";
break;
case LargeAllocStatus::NOT_ONLY_TOPLEVEL_IN_TABGROUP:
message = "LargeAllocationNotOnlyToplevelInTabGroup";
break;
default: // LargeAllocStatus::NONE
return; // Don't report a message to the console
}
nsContentUtils::ReportToConsole(errorFlags, NS_LITERAL_CSTRING("DOM"), mDoc,
nsContentUtils::eDOM_PROPERTIES, message);
}
#if defined(_WINDOWS_) && !defined(MOZ_WRAPPED_WINDOWS_H)
# pragma message( \
"wrapper failure reason: " MOZ_WINDOWS_WRAPPER_DISABLED_REASON)
@ -7661,7 +7619,6 @@ nsPIDOMWindowOuter::nsPIDOMWindowOuter(uint64_t aWindowID)
mInnerWindow(nullptr),
mWindowID(aWindowID),
mMarkedCCGeneration(0),
mServiceWorkersTestingEnabled(false),
mLargeAllocStatus(LargeAllocStatus::NONE) {}
mServiceWorkersTestingEnabled(false) {}
nsPIDOMWindowOuter::~nsPIDOMWindowOuter() = default;

View File

@ -811,10 +811,6 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
const nsAString& aPopupWindowName,
const nsAString& aPopupWindowFeatures);
private:
void ReportLargeAllocStatus();
public:
void FlushPendingNotifications(mozilla::FlushType aType);
// Outer windows only.

View File

@ -59,6 +59,7 @@ class ContentFrameMessageManager;
class DocGroup;
class Document;
class Element;
class Location;
class Navigator;
class Performance;
class Selection;
@ -91,33 +92,6 @@ enum class FullscreenReason {
ForForceExitFullscreen
};
namespace mozilla {
namespace dom {
class Location;
// The states in this enum represent the different possible outcomes which the
// window could be experiencing of loading a document with the
// Large-Allocation header. The NONE case represents the case where no
// Large-Allocation header was set.
enum class LargeAllocStatus : uint8_t {
// These are the OK states, NONE means that no large allocation status message
// should be printed, while SUCCESS means that the success message should be
// printed.
NONE,
SUCCESS,
// These are the ERROR states. If a window is in one of these states, then the
// next document loaded in that window should have an error message reported
// to it.
NON_GET,
NON_E10S,
NOT_ONLY_TOPLEVEL_IN_TABGROUP,
NON_WIN32
};
} // namespace dom
} // namespace mozilla
// Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
#define NS_PIDOMWINDOWINNER_IID \
{ \
@ -741,8 +715,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
float GetDevicePixelRatio(mozilla::dom::CallerType aCallerType);
void SetLargeAllocStatus(mozilla::dom::LargeAllocStatus aStatus);
bool IsTopLevelWindow();
bool HadOriginalOpener() const;
@ -1112,8 +1084,6 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy {
// Let the service workers plumbing know that some feature are enabled while
// testing.
bool mServiceWorkersTestingEnabled;
mozilla::dom::LargeAllocStatus mLargeAllocStatus;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowOuter, NS_PIDOMWINDOWOUTER_IID)

View File

@ -345,7 +345,6 @@ BrowserChild::BrowserChild(ContentChild* aManager, const TabId& aTabId,
mParentIsActive(false),
mDidSetRealShowInfo(false),
mDidLoadURLInit(false),
mAwaitingLA(false),
mSkipKeyPress(false),
mLayersObserverEpoch{1},
#if defined(XP_WIN) && defined(ACCESSIBILITY)
@ -3208,19 +3207,6 @@ mozilla::ipc::IPCResult BrowserChild::RecvSafeAreaInsetsChanged(
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserChild::RecvAwaitLargeAlloc() {
mAwaitingLA = true;
return IPC_OK();
}
bool BrowserChild::IsAwaitingLargeAlloc() { return mAwaitingLA; }
bool BrowserChild::StopAwaitingLargeAlloc() {
bool awaiting = mAwaitingLA;
mAwaitingLA = false;
return awaiting;
}
mozilla::ipc::IPCResult BrowserChild::RecvAllowScriptsToClose() {
nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
if (window) {

View File

@ -614,11 +614,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
uintptr_t GetNativeWindowHandle() const { return mNativeWindowHandle; }
#endif
// These methods return `true` if this BrowserChild is currently awaiting a
// Large-Allocation header.
bool StopAwaitingLargeAlloc();
bool IsAwaitingLargeAlloc();
BrowsingContext* GetBrowsingContext() const { return mBrowsingContext; }
#if defined(ACCESSIBILITY)
@ -736,8 +731,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
mozilla::ipc::IPCResult RecvStopIMEStateManagement();
mozilla::ipc::IPCResult RecvAwaitLargeAlloc();
mozilla::ipc::IPCResult RecvAllowScriptsToClose();
mozilla::ipc::IPCResult RecvSetWidgetNativeData(
@ -876,7 +869,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
CSSSize mUnscaledInnerSize;
bool mDidSetRealShowInfo;
bool mDidLoadURLInit;
bool mAwaitingLA;
bool mSkipKeyPress;

View File

@ -1417,12 +1417,6 @@ already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
windowParent->Init();
if (remoteType.EqualsLiteral(LARGE_ALLOCATION_REMOTE_TYPE)) {
// Tell the BrowserChild object that it was created due to a
// Large-Allocation request.
Unused << browserParent->SendAwaitLargeAlloc();
}
RefPtr<BrowserHost> browserHost = new BrowserHost(browserParent);
browserParent->SetOwnerElement(aFrameElement);
return browserHost.forget();

View File

@ -979,12 +979,6 @@ child:
*/
async UpdateNativeWindowHandle(uintptr_t aNewHandle);
/**
* Tell the BrowserChild that it should expect a Large-Allocation load to occur.
* Loads which occur until this flag is cleared will not leave the process.
*/
async AwaitLargeAlloc();
/**
* Tell the BrowserChild to allow scripts in the docshell to close the window.
*/

View File

@ -300,21 +300,11 @@ BiquadFilterChannelCountChangeWarning=BiquadFilterNode channel count changes may
# LOCALIZATION NOTE: Do not translate ".png"
GenericImageNamePNG=image.png
GenericFileName=file
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name
LargeAllocationSuccess=This page was loaded in a new process due to a Large-Allocation header.
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name. Do not translate GET.
LargeAllocationNonGetRequest=A Large-Allocation header was ignored due to the load being triggered by a non-GET request.
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name. Do not translate `window.opener`.
LargeAllocationNotOnlyToplevelInTabGroup=A Large-Allocation header was ignored due to the presence of windows which have a reference to this browsing context through the frame hierarchy or window.opener.
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name
LargeAllocationNonE10S=A Large-Allocation header was ignored due to the document not being loaded out of process.
GeolocationInsecureRequestIsForbidden=A Geolocation request can only be fulfilled in a secure context.
NotificationsInsecureRequestIsForbidden=The Notification permission may only be requested in a secure context.
NotificationsCrossOriginIframeRequestIsForbidden=The Notification permission may only be requested in a top-level document or same-origin iframe.
NotificationsRequireUserGesture=The Notification permission may only be requested from inside a short running user-generated event handler.
NotificationsRequireUserGestureDeprecationWarning=Requesting Notification permission outside a short running user-generated event handler is deprecated and will not be supported in the future.
# LOCALIZATION NOTE: Do not translate "Large-Allocation", as it is a literal header name.
LargeAllocationNonWin32=This page would be loaded in a new process due to a Large-Allocation header, however Large-Allocation process creation is disabled on non-Win32 platforms.
# LOCALIZATION NOTE: Do not translate "content", "Window", and "window.top"
WindowContentUntrustedWarning=The content attribute of Window objects is deprecated. Please use window.top instead.
# LOCALIZATION NOTE: The first %S is the tag name of the element that starts the loop, the second %S is the element's ID.

View File

@ -54,7 +54,6 @@ class WebBrowserChromeChild extends GeckoViewActorChild {
aURI,
aReferrerInfo,
aTriggeringPrincipal,
false,
null,
aCsp
);
@ -70,28 +69,6 @@ class WebBrowserChromeChild extends GeckoViewActorChild {
const remoteSubframes = this.docShell.nsILoadContext.useRemoteSubframes;
return E10SUtils.shouldLoadURIInThisProcess(aURI, remoteSubframes);
}
// nsIWebBrowserChrome
reloadInFreshProcess(
aDocShell,
aURI,
aReferrerInfo,
aTriggeringPrincipal,
aLoadFlags,
aCsp
) {
debug`reloadInFreshProcess ${aURI.displaySpec}`;
E10SUtils.redirectLoad(
aDocShell,
aURI,
aReferrerInfo,
aTriggeringPrincipal,
true,
aLoadFlags,
aCsp
);
return true;
}
}
WebBrowserChromeChild.prototype.QueryInterface = ChromeUtils.generateQI([

View File

@ -2111,11 +2111,6 @@
value: false
mirror: always
- name: dom.largeAllocation.testing.allHttpLoads
type: bool
value: false
mirror: always
# Whether "W3C Web Manifest" processing is enabled
- name: dom.manifest.enabled
type: bool

View File

@ -13,6 +13,7 @@
#include "mozilla/StaticPrefs_extensions.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_security.h"
#include "mozilla/dom/BrowsingContextGroup.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ClientChannelHelper.h"
#include "mozilla/dom/ContentParent.h"
@ -1085,6 +1086,34 @@ void DocumentLoadListener::SerializeRedirectData(
}
}
static bool IsLargeAllocationLoad(CanonicalBrowsingContext* aBrowsingContext,
nsIChannel* aChannel) {
if (!StaticPrefs::dom_largeAllocationHeader_enabled() ||
aBrowsingContext->UseRemoteSubframes()) {
return false;
}
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
if (!httpChannel) {
return false;
}
nsAutoCString ignoredHeaderValue;
nsresult rv = httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("Large-Allocation"), ignoredHeaderValue);
if (NS_FAILED(rv)) {
return false;
}
// On all platforms other than win32, LargeAllocation is disabled by default,
// and has to be force-enabled using `dom.largeAllocation.forceEnable`.
#if defined(XP_WIN) && defined(_X86_)
return true;
#else
return StaticPrefs::dom_largeAllocation_forceEnable();
#endif
}
bool DocumentLoadListener::MaybeTriggerProcessSwitch(
bool* aWillSwitchToRemote) {
MOZ_ASSERT(XRE_IsParentProcess());
@ -1206,6 +1235,25 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
currentRemoteType = VoidString();
}
nsAutoString preferredRemoteType = currentRemoteType;
// If we're performing a large allocation load, override the remote type
// with `LARGE_ALLOCATION_REMOTE_TYPE` to move it into an exclusive content
// process. If we're already in one, and don't otherwise we force ourselves
// out of that content process.
bool isLargeAllocSwitch = false;
if (browsingContext->IsTop() &&
browsingContext->Group()->Toplevels().Length() == 1) {
if (IsLargeAllocationLoad(browsingContext, mChannel)) {
preferredRemoteType.Assign(
NS_LITERAL_STRING(LARGE_ALLOCATION_REMOTE_TYPE));
isLargeAllocSwitch = true;
} else if (preferredRemoteType.EqualsLiteral(
LARGE_ALLOCATION_REMOTE_TYPE)) {
preferredRemoteType.Assign(NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE));
isLargeAllocSwitch = true;
}
}
if (coop ==
nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP) {
// We want documents with SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP COOP
@ -1252,7 +1300,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
NS_ConvertUTF16toUTF8(remoteType).get()));
// Check if a process switch is needed.
if (currentRemoteType == remoteType && !isCOOPSwitch && !isPreloadSwitch) {
if (currentRemoteType == remoteType && !isCOOPSwitch && !isPreloadSwitch &&
!isLargeAllocSwitch) {
LOG(("Process Switch Abort: type (%s) is compatible",
NS_ConvertUTF16toUTF8(remoteType).get()));
return false;
@ -1276,7 +1325,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
LOG(("Process Switch: Calling ChangeRemoteness"));
browsingContext
->ChangeRemoteness(remoteType, mCrossProcessRedirectIdentifier,
isCOOPSwitch)
isCOOPSwitch || isLargeAllocSwitch)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}](BrowserParent* aBrowserParent) {

View File

@ -66,21 +66,4 @@ interface nsIWebBrowserChrome3 : nsIWebBrowserChrome
in nsIContentSecurityPolicy aCsp);
bool shouldLoadURIInThisProcess(in nsIURI aURI);
/**
* Attempts to load the currently loaded page into a fresh process to increase
* available memory.
*
* @param aDocShell
* The docshell performing the load.
* @param aCsp
* The CSP to be used for reloading the top-level load. That is the CSP
* of the document that initially triggered the new document load.
*/
bool reloadInFreshProcess(in nsIDocShell aDocShell,
in nsIURI aURI,
in nsIReferrerInfo aReferrerInfo,
in nsIPrincipal aTriggeringPrincipal,
in uint32_t aLoadFlags,
in nsIContentSecurityPolicy aCsp);
};

View File

@ -345,16 +345,6 @@ var WebBrowserChrome = {
.useRemoteSubframes;
return E10SUtils.shouldLoadURIInThisProcess(URI, remoteSubframes);
},
reloadInFreshProcess(
docShell,
URI,
referrerInfo,
triggeringPrincipal,
loadFlags
) {
return false;
},
};
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {

View File

@ -913,25 +913,6 @@ var E10SUtils = {
return false;
}
// If we are in a Large-Allocation 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. We don't want to move into a new process if we have post data,
// because we would accidentally throw out that data.
let isOnlyToplevelBrowsingContext =
!aDocShell.browsingContext.parent &&
aDocShell.browsingContext.group.getToplevels().length == 1;
if (
!aHasPostData &&
remoteType == LARGE_ALLOCATION_REMOTE_TYPE &&
!aDocShell.awaitingLargeAlloc &&
isOnlyToplevelBrowsingContext
) {
this.log().info(
"returning false to throw away large allocation process\n"
);
return false;
}
// Allow history load if loaded in this process before.
let requestedIndex = sessionHistory.legacySHistory.requestedIndex;
if (requestedIndex >= 0) {
@ -961,7 +942,6 @@ var E10SUtils = {
aURI,
aReferrerInfo,
aTriggeringPrincipal,
aFreshProcess,
aFlags,
aCsp
) {
@ -981,7 +961,6 @@ var E10SUtils = {
Services.scriptSecurityManager.createNullPrincipal({})
),
csp: aCsp ? this.serializeCSP(aCsp) : null,
reloadInFreshProcess: !!aFreshProcess,
},
historyIndex: sessionHistory.legacySHistory.requestedIndex,
});

View File

@ -128,29 +128,6 @@ NS_IMETHODIMP nsDocumentOpenInfo::OnStartRequest(nsIRequest* request) {
if (204 == responseCode || 205 == responseCode) {
return NS_BINDING_ABORTED;
}
if (StaticPrefs::dom_largeAllocationHeader_enabled()) {
if (StaticPrefs::dom_largeAllocation_testing_allHttpLoads()) {
nsCOMPtr<nsIURI> uri;
rv = httpChannel->GetURI(getter_AddRefs(uri));
if (NS_SUCCEEDED(rv) && uri) {
if ((uri->SchemeIs("http") || uri->SchemeIs("https")) &&
nsContentUtils::AttemptLargeAllocationLoad(httpChannel)) {
return NS_BINDING_ABORTED;
}
}
}
// If we have a Large-Allocation header, let's check if we should perform
// a process switch.
nsAutoCString largeAllocationHeader;
rv = httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("Large-Allocation"), largeAllocationHeader);
if (NS_SUCCEEDED(rv) &&
nsContentUtils::AttemptLargeAllocationLoad(httpChannel)) {
return NS_BINDING_ABORTED;
}
}
}
//

View File

@ -409,15 +409,6 @@ NS_IMETHODIMP nsContentTreeOwner::ShouldLoadURIInThisProcess(nsIURI* aURI,
return NS_OK;
}
NS_IMETHODIMP nsContentTreeOwner::ReloadInFreshProcess(
nsIDocShell* aDocShell, nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
nsIPrincipal* aTriggeringPrincipal, uint32_t aLoadFlags,
nsIContentSecurityPolicy* aCsp, bool* aRetVal) {
NS_WARNING("Cannot reload in fresh process from a nsContentTreeOwner!");
*aRetVal = false;
return NS_OK;
}
//*****************************************************************************
// nsContentTreeOwner::nsIWebBrowserChrome
//*****************************************************************************