Backed out 16 changesets (bug 1689601) for causing cpp bustages in nsFrameLoader.

CLOSED TREE

Backed out changeset 6e5523a7210d (bug 1689601)
Backed out changeset 745eaa468c74 (bug 1689601)
Backed out changeset a594bd02b8b6 (bug 1689601)
Backed out changeset 0c5fe977ced6 (bug 1689601)
Backed out changeset 2fca23521891 (bug 1689601)
Backed out changeset 334aeb627855 (bug 1689601)
Backed out changeset 2b2081a15d67 (bug 1689601)
Backed out changeset 307bde43cc96 (bug 1689601)
Backed out changeset 04aadec67ce2 (bug 1689601)
Backed out changeset 701eccb34772 (bug 1689601)
Backed out changeset 278db692aa8b (bug 1689601)
Backed out changeset c261c243a64d (bug 1689601)
Backed out changeset 7e8022e5696a (bug 1689601)
Backed out changeset 6138bfc6c08d (bug 1689601)
Backed out changeset 63295b3a62d0 (bug 1689601)
Backed out changeset 6d02e59ddc51 (bug 1689601)
This commit is contained in:
Mihai Alexandru Michis 2021-03-02 13:15:10 +02:00
Родитель 5b58a3f6a5
Коммит 87f481bf9a
40 изменённых файлов: 212 добавлений и 890 удалений

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

@ -2621,25 +2621,6 @@ void BrowsingContext::DidSet(FieldIndex<IDX_UserAgentOverride>) {
}); });
} }
bool BrowsingContext::CanSet(FieldIndex<IDX_IsInBFCache>, bool,
ContentParent* aSource) {
return IsTop() && !aSource && mozilla::BFCacheInParent();
}
void BrowsingContext::DidSet(FieldIndex<IDX_IsInBFCache>) {
MOZ_RELEASE_ASSERT(mozilla::BFCacheInParent());
MOZ_DIAGNOSTIC_ASSERT(IsTop());
const bool isInBFCache = GetIsInBFCache();
PreOrderWalk([&](BrowsingContext* aContext) {
nsCOMPtr<nsIDocShell> shell = aContext->GetDocShell();
if (shell) {
static_cast<nsDocShell*>(shell.get())
->FirePageHideShowNonRecursive(!isInBFCache);
}
});
}
void BrowsingContext::SetCustomPlatform(const nsAString& aPlatform, void BrowsingContext::SetCustomPlatform(const nsAString& aPlatform,
ErrorResult& aRv) { ErrorResult& aRv) {
Top()->SetPlatformOverride(aPlatform, aRv); Top()->SetPlatformOverride(aPlatform, aRv);

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

@ -197,8 +197,7 @@ enum class ExplicitActiveStatus : uint8_t {
FIELD(HasMainMediaController, bool) \ FIELD(HasMainMediaController, bool) \
/* The number of entries added to the session history because of this \ /* The number of entries added to the session history because of this \
* browsing context. */ \ * browsing context. */ \
FIELD(HistoryEntryCount, uint32_t) \ FIELD(HistoryEntryCount, uint32_t)
FIELD(IsInBFCache, bool)
// BrowsingContext, in this context, is the cross process replicated // BrowsingContext, in this context, is the cross process replicated
// environment in which information about documents is stored. In // environment in which information about documents is stored. In
@ -1036,9 +1035,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void DidSet(FieldIndex<IDX_TextZoom>, float aOldValue); void DidSet(FieldIndex<IDX_TextZoom>, float aOldValue);
void DidSet(FieldIndex<IDX_AuthorStyleDisabledDefault>); void DidSet(FieldIndex<IDX_AuthorStyleDisabledDefault>);
bool CanSet(FieldIndex<IDX_IsInBFCache>, bool, ContentParent* aSource);
void DidSet(FieldIndex<IDX_IsInBFCache>);
// True if the process attemping to set field is the same as the owning // True if the process attemping to set field is the same as the owning
// process. Deprecated. New code that might use this should generally be moved // process. Deprecated. New code that might use this should generally be moved
// to WindowContext or be settable only by the parent process. // to WindowContext or be settable only by the parent process.

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

@ -24,7 +24,6 @@
#include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/net/DocumentLoadListener.h" #include "mozilla/net/DocumentLoadListener.h"
#include "mozilla/NullPrincipal.h" #include "mozilla/NullPrincipal.h"
#include "mozilla/StaticPrefs_fission.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "mozilla/MozPromiseInlines.h" #include "mozilla/MozPromiseInlines.h"
#include "nsDocShell.h" #include "nsDocShell.h"
@ -158,45 +157,21 @@ void CanonicalBrowsingContext::MaybeAddAsProgressListener(
} }
void CanonicalBrowsingContext::ReplacedBy( void CanonicalBrowsingContext::ReplacedBy(
CanonicalBrowsingContext* aNewContext, CanonicalBrowsingContext* aNewContext) {
const RemotenessChangeOptions& aRemotenessOptions) { MOZ_ASSERT(!aNewContext->EverAttached());
MOZ_ASSERT(!aNewContext->mWebProgress);
MOZ_ASSERT(!aNewContext->mSessionHistory);
MOZ_ASSERT(IsTop() && aNewContext->IsTop()); MOZ_ASSERT(IsTop() && aNewContext->IsTop());
if (mStatusFilter) { if (mStatusFilter) {
mStatusFilter->RemoveProgressListener(mWebProgress); mStatusFilter->RemoveProgressListener(mWebProgress);
mStatusFilter = nullptr; mStatusFilter = nullptr;
} }
aNewContext->mWebProgress = std::move(mWebProgress); aNewContext->mWebProgress = std::move(mWebProgress);
aNewContext->mFields.SetWithoutSyncing<IDX_BrowserId>(GetBrowserId());
// Use the Transaction for the fields which need to be updated whether or not aNewContext->mFields.SetWithoutSyncing<IDX_HistoryID>(GetHistoryID());
// the new context has been attached before. aNewContext->mFields.SetWithoutSyncing<IDX_ExplicitActive>(
// SetWithoutSyncing can be used if context hasn't been attached. GetExplicitActive());
Transaction txn;
txn.SetBrowserId(GetBrowserId());
txn.SetHistoryID(GetHistoryID());
txn.SetExplicitActive(GetExplicitActive());
if (aNewContext->EverAttached()) {
MOZ_ALWAYS_SUCCEEDS(txn.Commit(aNewContext));
} else {
txn.CommitWithoutSyncing(aNewContext);
}
// XXXBFCache name handling is still a bit broken in Fission in general,
// at least in case name should be cleared.
if (aRemotenessOptions.mTryUseBFCache) {
MOZ_ASSERT(!aNewContext->EverAttached());
aNewContext->mFields.SetWithoutSyncing<IDX_Name>(GetName());
aNewContext->mFields.SetWithoutSyncing<IDX_HasLoadedNonInitialDocument>(
GetHasLoadedNonInitialDocument());
}
if (mSessionHistory) { if (mSessionHistory) {
mSessionHistory->SetBrowsingContext(aNewContext); mSessionHistory->SetBrowsingContext(aNewContext);
if (mozilla::BFCacheInParent()) {
// XXXBFCache Should we clear the epoch always?
mSessionHistory->SetEpoch(0, Nothing());
}
mSessionHistory.swap(aNewContext->mSessionHistory); mSessionHistory.swap(aNewContext->mSessionHistory);
RefPtr<ChildSHistory> childSHistory = ForgetChildSHistory(); RefPtr<ChildSHistory> childSHistory = ForgetChildSHistory();
aNewContext->SetChildSHistory(childSHistory); aNewContext->SetChildSHistory(childSHistory);
@ -332,11 +307,6 @@ SessionHistoryEntry* CanonicalBrowsingContext::GetActiveSessionHistoryEntry() {
return mActiveEntry; return mActiveEntry;
} }
void CanonicalBrowsingContext::SetActiveSessionHistoryEntry(
SessionHistoryEntry* aEntry) {
mActiveEntry = aEntry;
}
bool CanonicalBrowsingContext::HasHistoryEntry(nsISHEntry* aEntry) { bool CanonicalBrowsingContext::HasHistoryEntry(nsISHEntry* aEntry) {
// XXX Should we check also loading entries? // XXX Should we check also loading entries?
return aEntry && mActiveEntry == aEntry; return aEntry && mActiveEntry == aEntry;
@ -1153,8 +1123,8 @@ void CanonicalBrowsingContext::PendingRemotenessChange::Finish() {
// The process has been created, hand off to nsFrameLoaderOwner to finish // The process has been created, hand off to nsFrameLoaderOwner to finish
// the process switch. // the process switch.
ErrorResult error; ErrorResult error;
frameLoaderOwner->ChangeRemotenessToProcess(mContentParent, mOptions, frameLoaderOwner->ChangeRemotenessToProcess(
mSpecificGroup, error); mContentParent, mReplaceBrowsingContext, mSpecificGroup, error);
if (error.Failed()) { if (error.Failed()) {
Cancel(error.StealNSResult()); Cancel(error.StealNSResult());
return; return;
@ -1258,8 +1228,7 @@ void CanonicalBrowsingContext::PendingRemotenessChange::Finish() {
oldBrowser->Destroy(); oldBrowser->Destroy();
} }
MOZ_ASSERT(!mOptions.mReplaceBrowsingContext, MOZ_ASSERT(!mReplaceBrowsingContext, "Cannot replace BC for subframe");
"Cannot replace BC for subframe");
nsCOMPtr<nsIPrincipal> initialPrincipal = nsCOMPtr<nsIPrincipal> initialPrincipal =
NullPrincipal::CreateWithInheritedAttributes( NullPrincipal::CreateWithInheritedAttributes(
target->OriginAttributesRef(), target->OriginAttributesRef(),
@ -1345,11 +1314,11 @@ void CanonicalBrowsingContext::PendingRemotenessChange::Clear() {
CanonicalBrowsingContext::PendingRemotenessChange::PendingRemotenessChange( CanonicalBrowsingContext::PendingRemotenessChange::PendingRemotenessChange(
CanonicalBrowsingContext* aTarget, RemotenessPromise::Private* aPromise, CanonicalBrowsingContext* aTarget, RemotenessPromise::Private* aPromise,
uint64_t aPendingSwitchId, const RemotenessChangeOptions& aOptions) uint64_t aPendingSwitchId, bool aReplaceBrowsingContext)
: mTarget(aTarget), : mTarget(aTarget),
mPromise(aPromise), mPromise(aPromise),
mPendingSwitchId(aPendingSwitchId), mPendingSwitchId(aPendingSwitchId),
mOptions(aOptions) {} mReplaceBrowsingContext(aReplaceBrowsingContext) {}
CanonicalBrowsingContext::PendingRemotenessChange::~PendingRemotenessChange() { CanonicalBrowsingContext::PendingRemotenessChange::~PendingRemotenessChange() {
MOZ_ASSERT(!mPromise && !mTarget && !mContentParent && !mSpecificGroup && MOZ_ASSERT(!mPromise && !mTarget && !mContentParent && !mSpecificGroup &&
@ -1365,18 +1334,19 @@ BrowserParent* CanonicalBrowsingContext::GetBrowserParent() const {
} }
RefPtr<CanonicalBrowsingContext::RemotenessPromise> RefPtr<CanonicalBrowsingContext::RemotenessPromise>
CanonicalBrowsingContext::ChangeRemoteness( CanonicalBrowsingContext::ChangeRemoteness(const nsACString& aRemoteType,
const RemotenessChangeOptions& aOptions, uint64_t aPendingSwitchId) { uint64_t aPendingSwitchId,
bool aReplaceBrowsingContext,
uint64_t aSpecificGroupId) {
MOZ_DIAGNOSTIC_ASSERT(IsContent(), MOZ_DIAGNOSTIC_ASSERT(IsContent(),
"cannot change the process of chrome contexts"); "cannot change the process of chrome contexts");
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
IsTop() == IsEmbeddedInProcess(0), IsTop() == IsEmbeddedInProcess(0),
"toplevel content must be embedded in the parent process"); "toplevel content must be embedded in the parent process");
MOZ_DIAGNOSTIC_ASSERT(!aOptions.mReplaceBrowsingContext || IsTop(), MOZ_DIAGNOSTIC_ASSERT(!aReplaceBrowsingContext || IsTop(),
"Cannot replace BrowsingContext for subframes"); "Cannot replace BrowsingContext for subframes");
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(aSpecificGroupId == 0 || aReplaceBrowsingContext,
aOptions.mSpecificGroupId == 0 || aOptions.mReplaceBrowsingContext, "Cannot specify group ID unless replacing BC");
"Cannot specify group ID unless replacing BC");
MOZ_DIAGNOSTIC_ASSERT(aPendingSwitchId || !IsTop(), MOZ_DIAGNOSTIC_ASSERT(aPendingSwitchId || !IsTop(),
"Should always have aPendingSwitchId for top-level " "Should always have aPendingSwitchId for top-level "
"frames"); "frames");
@ -1398,7 +1368,7 @@ CanonicalBrowsingContext::ChangeRemoteness(
return RemotenessPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__); return RemotenessPromise::CreateAndReject(NS_ERROR_NOT_AVAILABLE, __func__);
} }
if (aOptions.mRemoteType.IsEmpty() && (!IsTop() || !GetEmbedderElement())) { if (aRemoteType.IsEmpty() && (!IsTop() || !GetEmbedderElement())) {
NS_WARNING("Cannot load non-remote subframes"); NS_WARNING("Cannot load non-remote subframes");
return RemotenessPromise::CreateAndReject(NS_ERROR_FAILURE, __func__); return RemotenessPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
} }
@ -1413,7 +1383,7 @@ CanonicalBrowsingContext::ChangeRemoteness(
embedderWindowGlobal->GetBrowserParent(); embedderWindowGlobal->GetBrowserParent();
// Switching to local. No new process, so perform switch sync. // Switching to local. No new process, so perform switch sync.
if (embedderBrowser && if (embedderBrowser &&
aOptions.mRemoteType == embedderBrowser->Manager()->GetRemoteType()) { aRemoteType == embedderBrowser->Manager()->GetRemoteType()) {
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
aPendingSwitchId, aPendingSwitchId,
"We always have a PendingSwitchId, except for print-preview loads, " "We always have a PendingSwitchId, except for print-preview loads, "
@ -1435,8 +1405,8 @@ CanonicalBrowsingContext::ChangeRemoteness(
// If the embedder process is remote, tell that remote process to become // If the embedder process is remote, tell that remote process to become
// the owner. // the owner.
MOZ_DIAGNOSTIC_ASSERT(!aOptions.mReplaceBrowsingContext); MOZ_DIAGNOSTIC_ASSERT(!aReplaceBrowsingContext);
MOZ_DIAGNOSTIC_ASSERT(!aOptions.mRemoteType.IsEmpty()); MOZ_DIAGNOSTIC_ASSERT(!aRemoteType.IsEmpty());
SetOwnerProcessId(embedderBrowser->Manager()->ChildID()); SetOwnerProcessId(embedderBrowser->Manager()->ChildID());
Unused << embedderWindowGlobal->SendMakeFrameLocal(this, aPendingSwitchId); Unused << embedderWindowGlobal->SendMakeFrameLocal(this, aPendingSwitchId);
return RemotenessPromise::CreateAndResolve(embedderBrowser, __func__); return RemotenessPromise::CreateAndResolve(embedderBrowser, __func__);
@ -1444,15 +1414,15 @@ CanonicalBrowsingContext::ChangeRemoteness(
// Switching to remote. Wait for new process to launch before switch. // Switching to remote. Wait for new process to launch before switch.
auto promise = MakeRefPtr<RemotenessPromise::Private>(__func__); auto promise = MakeRefPtr<RemotenessPromise::Private>(__func__);
RefPtr<PendingRemotenessChange> change = RefPtr<PendingRemotenessChange> change = new PendingRemotenessChange(
new PendingRemotenessChange(this, promise, aPendingSwitchId, aOptions); this, promise, aPendingSwitchId, aReplaceBrowsingContext);
mPendingRemotenessChange = change; mPendingRemotenessChange = change;
// If a specific BrowsingContextGroup ID was specified for this load, make // If a specific BrowsingContextGroup ID was specified for this load, make
// sure to keep it alive until the process switch is completed. // sure to keep it alive until the process switch is completed.
if (aOptions.mSpecificGroupId) { if (aSpecificGroupId) {
change->mSpecificGroup = change->mSpecificGroup =
BrowsingContextGroup::GetOrCreate(aOptions.mSpecificGroupId); BrowsingContextGroup::GetOrCreate(aSpecificGroupId);
change->mSpecificGroup->AddKeepAlive(); change->mSpecificGroup->AddKeepAlive();
} }
@ -1474,7 +1444,7 @@ CanonicalBrowsingContext::ChangeRemoteness(
change->mPrepareToChangePromise = GenericPromise::FromDomPromise(blocker); change->mPrepareToChangePromise = GenericPromise::FromDomPromise(blocker);
} }
if (aOptions.mRemoteType.IsEmpty()) { if (aRemoteType.IsEmpty()) {
change->ProcessReady(); change->ProcessReady();
} else { } else {
// Try to predict which BrowsingContextGroup will be used for the final load // Try to predict which BrowsingContextGroup will be used for the final load
@ -1485,12 +1455,11 @@ CanonicalBrowsingContext::ChangeRemoteness(
// It's _technically_ OK to provide a group here if we're actually going to // It's _technically_ OK to provide a group here if we're actually going to
// switch into a brand new group, though it's sub-optimal, as it can // switch into a brand new group, though it's sub-optimal, as it can
// restrict the set of processes we're using. // restrict the set of processes we're using.
BrowsingContextGroup* finalGroup = aOptions.mReplaceBrowsingContext BrowsingContextGroup* finalGroup =
? change->mSpecificGroup.get() aReplaceBrowsingContext ? change->mSpecificGroup.get() : Group();
: Group();
change->mContentParent = ContentParent::GetNewOrUsedLaunchingBrowserProcess( change->mContentParent = ContentParent::GetNewOrUsedLaunchingBrowserProcess(
/* aRemoteType = */ aOptions.mRemoteType, /* aRemoteType = */ aRemoteType,
/* aGroup = */ finalGroup, /* aGroup = */ finalGroup,
/* aPriority = */ hal::PROCESS_PRIORITY_FOREGROUND, /* aPriority = */ hal::PROCESS_PRIORITY_FOREGROUND,
/* aPreferUsed = */ false); /* aPreferUsed = */ false);
@ -1543,12 +1512,6 @@ bool CanonicalBrowsingContext::SupportsLoadingInParent(
return false; return false;
} }
// Session-history-in-parent implementation relies currently on getting a
// round trip through a child process.
if (aLoadState->LoadIsFromSessionHistory()) {
return false;
}
// DocumentChannel currently only supports connecting channels into the // DocumentChannel currently only supports connecting channels into the
// content process, so we can only support schemes that will always be loaded // content process, so we can only support schemes that will always be loaded
// there for now. Restrict to just http(s) for simplicity. // there for now. Restrict to just http(s) for simplicity.
@ -1622,6 +1585,12 @@ bool CanonicalBrowsingContext::AttemptSpeculativeLoadInParent(
return false; return false;
} }
// Session-history-in-parent implementation relies currently on getting a
// round trip through a child process.
if (aLoadState->LoadIsFromSessionHistory()) {
return false;
}
// If we successfully open the DocumentChannel, then it'll register // If we successfully open the DocumentChannel, then it'll register
// itself using aLoadIdentifier and be kept alive until it completes // itself using aLoadIdentifier and be kept alive until it completes
// loading. // loading.

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

@ -44,15 +44,6 @@ struct LoadingSessionHistoryInfo;
class SessionHistoryEntry; class SessionHistoryEntry;
class WindowGlobalParent; class WindowGlobalParent;
// RemotenessChangeOptions is passed through the methods to store the state
// of the possible remoteness change.
struct RemotenessChangeOptions {
nsCString mRemoteType;
bool mReplaceBrowsingContext = false;
uint64_t mSpecificGroupId = 0;
bool mTryUseBFCache = false;
};
// CanonicalBrowsingContext is a BrowsingContext living in the parent // CanonicalBrowsingContext is a BrowsingContext living in the parent
// process, with whatever extra data that a BrowsingContext in the // process, with whatever extra data that a BrowsingContext in the
// parent needs. // parent needs.
@ -120,7 +111,6 @@ class CanonicalBrowsingContext final : public BrowsingContext {
nsISHistory* GetSessionHistory(); nsISHistory* GetSessionHistory();
SessionHistoryEntry* GetActiveSessionHistoryEntry(); SessionHistoryEntry* GetActiveSessionHistoryEntry();
void SetActiveSessionHistoryEntry(SessionHistoryEntry* aEntry);
UniquePtr<LoadingSessionHistoryInfo> CreateLoadingSessionHistoryEntryForLoad( UniquePtr<LoadingSessionHistoryInfo> CreateLoadingSessionHistoryEntryForLoad(
nsDocShellLoadState* aLoadState, nsIChannel* aChannel); nsDocShellLoadState* aLoadState, nsIChannel* aChannel);
@ -216,8 +206,10 @@ class CanonicalBrowsingContext final : public BrowsingContext {
// A NOT_REMOTE_TYPE aRemoteType argument will perform a process switch into // A NOT_REMOTE_TYPE aRemoteType argument will perform a process switch into
// the parent process, and the method will resolve with a null BrowserParent. // the parent process, and the method will resolve with a null BrowserParent.
using RemotenessPromise = MozPromise<RefPtr<BrowserParent>, nsresult, false>; using RemotenessPromise = MozPromise<RefPtr<BrowserParent>, nsresult, false>;
RefPtr<RemotenessPromise> ChangeRemoteness( RefPtr<RemotenessPromise> ChangeRemoteness(const nsACString& aRemoteType,
const RemotenessChangeOptions& aOptions, uint64_t aPendingSwitchId); uint64_t aPendingSwitchId,
bool aReplaceBrowsingContext,
uint64_t aSpecificGroupId);
// Return a media controller from the top-level browsing context that can // Return a media controller from the top-level browsing context that can
// control all media belonging to this browsing context tree. Return nullptr // control all media belonging to this browsing context tree. Return nullptr
@ -255,8 +247,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
// process). // process).
// aNewContext is the newly created BrowsingContext that is replacing // aNewContext is the newly created BrowsingContext that is replacing
// us. // us.
void ReplacedBy(CanonicalBrowsingContext* aNewContext, void ReplacedBy(CanonicalBrowsingContext* aNewContext);
const RemotenessChangeOptions& aRemotenessOptions);
bool HasHistoryEntry(nsISHEntry* aEntry); bool HasHistoryEntry(nsISHEntry* aEntry);
@ -302,7 +293,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
PendingRemotenessChange(CanonicalBrowsingContext* aTarget, PendingRemotenessChange(CanonicalBrowsingContext* aTarget,
RemotenessPromise::Private* aPromise, RemotenessPromise::Private* aPromise,
uint64_t aPendingSwitchId, uint64_t aPendingSwitchId,
const RemotenessChangeOptions& aOptions); bool aReplaceBrowsingContext);
void Cancel(nsresult aRv); void Cancel(nsresult aRv);
@ -321,7 +312,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
RefPtr<BrowsingContextGroup> mSpecificGroup; RefPtr<BrowsingContextGroup> mSpecificGroup;
uint64_t mPendingSwitchId; uint64_t mPendingSwitchId;
RemotenessChangeOptions mOptions; bool mReplaceBrowsingContext;
}; };
friend class net::DocumentLoadListener; friend class net::DocumentLoadListener;

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

@ -74,16 +74,6 @@ class Transaction {
mozilla::ipc::IPCResult CommitFromIPC(const MaybeDiscarded<Context>& aOwner, mozilla::ipc::IPCResult CommitFromIPC(const MaybeDiscarded<Context>& aOwner,
uint64_t aEpoch, ContentChild* aSource); uint64_t aEpoch, ContentChild* aSource);
// Apply the changes from this transaction to the specified Context WITHOUT
// syncing the changes to other processes.
//
// Unlike `Commit`, this method will NOT call the corresponding `CanSet` or
// `DidSet` methods, and can be performed when the target context is
// unattached or discarded.
//
// NOTE: YOU PROBABLY DO NOT WANT TO USE THIS METHOD
void CommitWithoutSyncing(Context* aOwner);
private: private:
friend struct mozilla::ipc::IPDLParamTraits<Transaction<Context>>; friend struct mozilla::ipc::IPDLParamTraits<Transaction<Context>>;

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

@ -223,22 +223,6 @@ void Transaction<Context>::Apply(Context* aOwner, bool aFromIPC) {
mModified.clear(); mModified.clear();
} }
template <typename Context>
void Transaction<Context>::CommitWithoutSyncing(Context* aOwner) {
MOZ_LOG(
Context::GetSyncLog(), LogLevel::Debug,
("Transaction::CommitWithoutSyncing(#%" PRIx64 "): %s", aOwner->Id(),
FormatTransaction<Context>(mModified, aOwner->mFields.mValues, mValues)
.get()));
EachIndex([&](auto idx) {
if (mModified.contains(idx)) {
aOwner->mFields.mValues.Get(idx) = std::move(mValues.Get(idx));
}
});
mModified.clear();
}
inline CanSetResult AsCanSetResult(CanSetResult aValue) { return aValue; } inline CanSetResult AsCanSetResult(CanSetResult aValue) { return aValue; }
inline CanSetResult AsCanSetResult(bool aValue) { inline CanSetResult AsCanSetResult(bool aValue) {
return aValue ? CanSetResult::Allow : CanSetResult::Deny; return aValue ? CanSetResult::Allow : CanSetResult::Deny;

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

@ -1195,58 +1195,6 @@ void nsDocShell::FirePageHideNotificationInternal(
} }
} }
void nsDocShell::FirePageHideShowNonRecursive(bool aShow) {
MOZ_ASSERT(mozilla::BFCacheInParent());
if (!mContentViewer) {
return;
}
// Emulate what non-SHIP BFCache does too. In pageshow case
// add and remove a request and before that call SetCurrentURI to get
// the location change notification.
// For pagehide, set mFiredUnloadEvent to true, so that unload doesn't fire.
nsCOMPtr<nsIContentViewer> contentViewer(mContentViewer);
if (aShow) {
mFiredUnloadEvent = false;
RefPtr<Document> doc = contentViewer->GetDocument();
if (doc) {
if (mBrowsingContext->IsTop()) {
doc->NotifyPossibleTitleChange(false);
}
if (mScriptGlobal && mScriptGlobal->GetCurrentInnerWindowInternal()) {
mScriptGlobal->GetCurrentInnerWindowInternal()->Thaw(false);
}
nsCOMPtr<nsIChannel> channel = doc->GetChannel();
if (channel) {
SetCurrentURI(doc->GetDocumentURI(), channel, true, 0);
mEODForCurrentDocument = false;
mIsRestoringDocument = true;
mLoadGroup->AddRequest(channel, nullptr);
mLoadGroup->RemoveRequest(channel, nullptr, NS_OK);
mIsRestoringDocument = false;
}
RefPtr<PresShell> presShell = GetPresShell();
if (presShell) {
presShell->Thaw(false);
}
}
} else if (!mFiredUnloadEvent) {
// XXXBFCache check again that the page can enter bfcache.
// XXXBFCache should mTiming->NotifyUnloadEventStart()/End() be called here?
mFiredUnloadEvent = true;
contentViewer->PageHide(false);
if (mScriptGlobal && mScriptGlobal->GetCurrentInnerWindowInternal()) {
mScriptGlobal->GetCurrentInnerWindowInternal()->Freeze(false);
}
RefPtr<PresShell> presShell = GetPresShell();
if (presShell) {
presShell->Freeze(false);
}
}
}
nsresult nsDocShell::Dispatch(TaskCategory aCategory, nsresult nsDocShell::Dispatch(TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable) { already_AddRefed<nsIRunnable>&& aRunnable) {
nsCOMPtr<nsIRunnable> runnable(aRunnable); nsCOMPtr<nsIRunnable> runnable(aRunnable);
@ -3507,14 +3455,12 @@ nsresult nsDocShell::LoadURI(const nsAString& aURI,
} else { } else {
triggeringPrincipal = nsContentUtils::GetSystemPrincipal(); triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
} }
if (mozilla::SessionHistoryInParent()) { mActiveEntry = MakeUnique<SessionHistoryInfo>(
mActiveEntry = MakeUnique<SessionHistoryInfo>( uri, triggeringPrincipal, nullptr, nullptr, nullptr,
uri, triggeringPrincipal, nullptr, nullptr, nullptr, nsLiteralCString("text/html"));
nsLiteralCString("text/html")); mBrowsingContext->SetActiveSessionHistoryEntry(
mBrowsingContext->SetActiveSessionHistoryEntry( Nothing(), mActiveEntry.get(), MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags),
Nothing(), mActiveEntry.get(), MAKE_LOAD_TYPE(LOAD_NORMAL, loadFlags), /* aUpdatedCacheKey = */ 0);
/* aUpdatedCacheKey = */ 0);
}
if (DisplayLoadError(rv, nullptr, PromiseFlatString(aURI).get(), nullptr) && if (DisplayLoadError(rv, nullptr, PromiseFlatString(aURI).get(), nullptr) &&
(loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) { (loadFlags & LOAD_FLAGS_ERROR_LOAD_CHANGES_RV) != 0) {
return NS_ERROR_LOAD_SHOWED_ERRORPAGE; return NS_ERROR_LOAD_SHOWED_ERRORPAGE;
@ -6950,7 +6896,6 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
// Only save presentation for "normal" loads and link loads. Anything else // Only save presentation for "normal" loads and link loads. Anything else
// probably wants to refetch the page, so caching the old presentation // probably wants to refetch the page, so caching the old presentation
// would be incorrect. // would be incorrect.
// XXXBFCache in parent needs something like this!
if (aLoadType != LOAD_NORMAL && aLoadType != LOAD_HISTORY && if (aLoadType != LOAD_NORMAL && aLoadType != LOAD_HISTORY &&
aLoadType != LOAD_LINK && aLoadType != LOAD_STOP_CONTENT && aLoadType != LOAD_LINK && aLoadType != LOAD_STOP_CONTENT &&
aLoadType != LOAD_STOP_CONTENT_AND_REPLACE && aLoadType != LOAD_STOP_CONTENT_AND_REPLACE &&
@ -6991,7 +6936,7 @@ bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
uint16_t bfCacheCombo = 0; uint16_t bfCacheCombo = 0;
bool canSavePresentation = bool canSavePresentation =
doc->CanSavePresentation(aNewRequest, bfCacheCombo, true); doc->CanSavePresentation(aNewRequest, bfCacheCombo);
MOZ_ASSERT_IF(canSavePresentation, bfCacheCombo == 0); MOZ_ASSERT_IF(canSavePresentation, bfCacheCombo == 0);
if (canSavePresentation && doc->IsTopLevelContentDocument()) { if (canSavePresentation && doc->IsTopLevelContentDocument()) {
auto* browsingContextGroup = mBrowsingContext->Group(); auto* browsingContextGroup = mBrowsingContext->Group();

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

@ -937,8 +937,6 @@ class nsDocShell final : public nsDocLoader,
void FirePageHideNotificationInternal(bool aIsUnload, void FirePageHideNotificationInternal(bool aIsUnload,
bool aSkipCheckingDynEntries); bool aSkipCheckingDynEntries);
void FirePageHideShowNonRecursive(bool aShow);
nsresult Dispatch(mozilla::TaskCategory aCategory, nsresult Dispatch(mozilla::TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable); already_AddRefed<nsIRunnable>&& aRunnable);

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

@ -9,13 +9,11 @@
#include "nsDocShell.h" #include "nsDocShell.h"
#include "nsDocShellLoadState.h" #include "nsDocShellLoadState.h"
#include "nsIHttpChannel.h" #include "nsIHttpChannel.h"
#include "nsIXULRuntime.h"
#include "nsSHEntryShared.h" #include "nsSHEntryShared.h"
#include "nsSHistory.h" #include "nsSHistory.h"
#include "nsStructuredCloneContainer.h" #include "nsStructuredCloneContainer.h"
#include "nsXULAppAPI.h" #include "nsXULAppAPI.h"
#include "mozilla/PresState.h" #include "mozilla/PresState.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/Tuple.h" #include "mozilla/Tuple.h"
#include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
@ -389,28 +387,20 @@ void SessionHistoryEntry::RemoveLoadId(uint64_t aLoadId) {
} }
SessionHistoryEntry::SessionHistoryEntry() SessionHistoryEntry::SessionHistoryEntry()
: mInfo(new SessionHistoryInfo()), mID(++gEntryID) { : mInfo(new SessionHistoryInfo()), mID(++gEntryID) {}
MOZ_ASSERT(mozilla::SessionHistoryInParent());
}
SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState, SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState,
nsIChannel* aChannel) nsIChannel* aChannel)
: mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) { : mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) {}
MOZ_ASSERT(mozilla::SessionHistoryInParent());
}
SessionHistoryEntry::SessionHistoryEntry(SessionHistoryInfo* aInfo) SessionHistoryEntry::SessionHistoryEntry(SessionHistoryInfo* aInfo)
: mInfo(MakeUnique<SessionHistoryInfo>(*aInfo)), mID(++gEntryID) { : mInfo(MakeUnique<SessionHistoryInfo>(*aInfo)), mID(++gEntryID) {}
MOZ_ASSERT(mozilla::SessionHistoryInParent());
}
SessionHistoryEntry::SessionHistoryEntry(const SessionHistoryEntry& aEntry) SessionHistoryEntry::SessionHistoryEntry(const SessionHistoryEntry& aEntry)
: mInfo(MakeUnique<SessionHistoryInfo>(*aEntry.mInfo)), : mInfo(MakeUnique<SessionHistoryInfo>(*aEntry.mInfo)),
mParent(aEntry.mParent), mParent(aEntry.mParent),
mID(aEntry.mID), mID(aEntry.mID),
mBCHistoryLength(aEntry.mBCHistoryLength) { mBCHistoryLength(aEntry.mBCHistoryLength) {}
MOZ_ASSERT(mozilla::SessionHistoryInParent());
}
SessionHistoryEntry::~SessionHistoryEntry() { SessionHistoryEntry::~SessionHistoryEntry() {
// Null out the mParent pointers on all our kids. // Null out the mParent pointers on all our kids.
@ -1346,29 +1336,6 @@ SHEntrySharedParentState* SessionHistoryEntry::SharedInfo() const {
return static_cast<SHEntrySharedParentState*>(mInfo->mSharedState.Get()); return static_cast<SHEntrySharedParentState*>(mInfo->mSharedState.Get());
} }
void SessionHistoryEntry::SetFrameLoader(nsFrameLoader* aFrameLoader) {
MOZ_ASSERT_IF(aFrameLoader, !SharedInfo()->mFrameLoader);
// If the pref is disabled, we still allow evicting the existing entries.
MOZ_RELEASE_ASSERT(!aFrameLoader || mozilla::BFCacheInParent());
SharedInfo()->mFrameLoader = aFrameLoader;
if (aFrameLoader) {
// When a new frameloader is stored, try to evict some older
// frameloaders. Non-SHIP session history has a similar call in
// nsDocumentViewer::Show.
nsCOMPtr<nsISHistory> shistory;
GetShistory(getter_AddRefs(shistory));
if (shistory) {
int32_t index = 0;
shistory->GetIndex(&index);
shistory->EvictOutOfRangeContentViewers(index);
}
}
}
nsFrameLoader* SessionHistoryEntry::GetFrameLoader() {
return SharedInfo()->mFrameLoader;
}
void SessionHistoryEntry::SetInfo(SessionHistoryInfo* aInfo) { void SessionHistoryEntry::SetInfo(SessionHistoryInfo* aInfo) {
// FIXME Assert that we're not changing shared state! // FIXME Assert that we're not changing shared state!
mInfo = MakeUnique<SessionHistoryInfo>(*aInfo); mInfo = MakeUnique<SessionHistoryInfo>(*aInfo);

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

@ -340,9 +340,6 @@ class SessionHistoryEntry : public nsISHEntry {
SHEntrySharedParentState* SharedInfo() const; SHEntrySharedParentState* SharedInfo() const;
void SetFrameLoader(nsFrameLoader* aFrameLoader);
nsFrameLoader* GetFrameLoader();
void AddChild(SessionHistoryEntry* aChild, int32_t aOffset, void AddChild(SessionHistoryEntry* aChild, int32_t aOffset,
bool aUseRemoteSubframes); bool aUseRemoteSubframes);
void RemoveChild(SessionHistoryEntry* aChild); void RemoveChild(SessionHistoryEntry* aChild);

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

@ -16,7 +16,7 @@
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
#include "nsSHistory.h" #include "nsSHistory.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsFrameLoader.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
@ -70,11 +70,6 @@ SHEntrySharedParentState::SHEntrySharedParentState(
SHEntrySharedParentState::~SHEntrySharedParentState() { SHEntrySharedParentState::~SHEntrySharedParentState() {
MOZ_ASSERT(mId != 0); MOZ_ASSERT(mId != 0);
RefPtr<nsFrameLoader> loader = mFrameLoader.forget();
if (loader) {
loader->Destroy();
}
sIdToSharedState->Remove(mId); sIdToSharedState->Remove(mId);
if (sIdToSharedState->IsEmpty()) { if (sIdToSharedState->IsEmpty()) {
delete sIdToSharedState; delete sIdToSharedState;
@ -116,14 +111,6 @@ void SHEntrySharedChildState::CopyFrom(SHEntrySharedChildState* aEntry) {
mChildShells.AppendObjects(aEntry->mChildShells); mChildShells.AppendObjects(aEntry->mChildShells);
} }
void SHEntrySharedParentState::SetFrameLoader(nsFrameLoader* aFrameLoader) {
mFrameLoader = aFrameLoader;
}
nsFrameLoader* SHEntrySharedParentState::GetFrameLoader() {
return mFrameLoader;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

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

@ -28,7 +28,6 @@ class nsIDocShellTreeItem;
class nsILayoutHistoryState; class nsILayoutHistoryState;
class nsIPrincipal; class nsIPrincipal;
class nsDocShellEditorData; class nsDocShellEditorData;
class nsFrameLoader;
class nsIMutableArray; class nsIMutableArray;
class nsSHistory; class nsSHistory;
@ -97,10 +96,6 @@ class SHEntrySharedParentState : public SHEntrySharedState {
uint64_t GetId() const { return mId; } uint64_t GetId() const { return mId; }
void ChangeId(uint64_t aId); void ChangeId(uint64_t aId);
void SetFrameLoader(nsFrameLoader* aFrameLoader);
nsFrameLoader* GetFrameLoader();
void NotifyListenersContentViewerEvicted(); void NotifyListenersContentViewerEvicted();
SHEntrySharedParentState(); SHEntrySharedParentState();
@ -135,8 +130,6 @@ class SHEntrySharedParentState : public SHEntrySharedState {
// they're specific to a particular content viewer. // they're specific to a particular content viewer.
nsWeakPtr mSHistory; nsWeakPtr mSHistory;
RefPtr<nsFrameLoader> mFrameLoader;
bool mSticky = true; bool mSticky = true;
bool mDynamicallyCreated = false; bool mDynamicallyCreated = false;

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

@ -12,7 +12,6 @@
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsDocShell.h" #include "nsDocShell.h"
#include "nsFrameLoaderOwner.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
@ -32,15 +31,12 @@
#include "prsystem.h" #include "prsystem.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/dom/BrowsingContextGroup.h"
#include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/LinkedList.h" #include "mozilla/LinkedList.h"
#include "mozilla/MathAlgorithms.h" #include "mozilla/MathAlgorithms.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Services.h" #include "mozilla/Services.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPtr.h" #include "mozilla/StaticPtr.h"
#include "mozilla/dom/CanonicalBrowsingContext.h" #include "mozilla/dom/CanonicalBrowsingContext.h"
#include "nsIWebNavigation.h" #include "nsIWebNavigation.h"
@ -55,16 +51,12 @@ using namespace mozilla::dom;
"browser.sessionhistory.max_total_viewers" "browser.sessionhistory.max_total_viewers"
#define CONTENT_VIEWER_TIMEOUT_SECONDS \ #define CONTENT_VIEWER_TIMEOUT_SECONDS \
"browser.sessionhistory.contentViewerTimeout" "browser.sessionhistory.contentViewerTimeout"
// Observe fission.bfcacheInParent so that BFCache can be enabled/disabled when
// the pref is changed.
#define PREF_FISSION_BFCACHEINPARENT "fission.bfcacheInParent"
// Default this to time out unused content viewers after 30 minutes // Default this to time out unused content viewers after 30 minutes
#define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30 * 60) #define CONTENT_VIEWER_TIMEOUT_SECONDS_DEFAULT (30 * 60)
static const char* kObservedPrefs[] = {PREF_SHISTORY_SIZE, static const char* kObservedPrefs[] = {
PREF_SHISTORY_MAX_TOTAL_VIEWERS, PREF_SHISTORY_SIZE, PREF_SHISTORY_MAX_TOTAL_VIEWERS, nullptr};
PREF_FISSION_BFCACHEINPARENT, nullptr};
static int32_t gHistoryMaxSize = 50; static int32_t gHistoryMaxSize = 50;
// List of all SHistory objects, used for content viewer cache eviction // List of all SHistory objects, used for content viewer cache eviction
@ -84,7 +76,6 @@ LazyLogModule gSHistoryLog("nsSHistory");
#define LOG(format) MOZ_LOG(gSHistoryLog, mozilla::LogLevel::Debug, format) #define LOG(format) MOZ_LOG(gSHistoryLog, mozilla::LogLevel::Debug, format)
extern mozilla::LazyLogModule gPageCacheLog; extern mozilla::LazyLogModule gPageCacheLog;
extern mozilla::LazyLogModule gSHIPBFCacheLog;
// This macro makes it easier to print a log message which includes a URI's // This macro makes it easier to print a log message which includes a URI's
// spec. Example use: // spec. Example use:
@ -241,15 +232,6 @@ void nsSHistory::EvictContentViewerForEntry(nsISHEntry* aEntry) {
aEntry->SetContentViewer(nullptr); aEntry->SetContentViewer(nullptr);
aEntry->SyncPresentationState(); aEntry->SyncPresentationState();
viewer->Destroy(); viewer->Destroy();
} else if (nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(aEntry)) {
if (RefPtr<nsFrameLoader> frameLoader = she->GetFrameLoader()) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::EvictContentViewerForEntry "
"destroying an nsFrameLoader."));
NotifyListenersContentViewerEvicted(1);
she->SetFrameLoader(nullptr);
frameLoader->Destroy();
}
} }
// When dropping bfcache, we have to remove associated dynamic entries as // When dropping bfcache, we have to remove associated dynamic entries as
@ -360,7 +342,7 @@ uint32_t nsSHistory::CalcMaxTotalViewers() {
// static // static
void nsSHistory::UpdatePrefs() { void nsSHistory::UpdatePrefs() {
Preferences::GetInt(PREF_SHISTORY_SIZE, &gHistoryMaxSize); Preferences::GetInt(PREF_SHISTORY_SIZE, &gHistoryMaxSize);
if (mozilla::SessionHistoryInParent() && !mozilla::BFCacheInParent()) { if (mozilla::SessionHistoryInParent()) {
sHistoryMaxTotalViewers = 0; sHistoryMaxTotalViewers = 0;
return; return;
} }
@ -1146,9 +1128,6 @@ nsSHistory::NotifyOnHistoryReload(bool* aCanReload) {
NS_IMETHODIMP NS_IMETHODIMP
nsSHistory::EvictOutOfRangeContentViewers(int32_t aIndex) { nsSHistory::EvictOutOfRangeContentViewers(int32_t aIndex) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::EvictOutOfRangeContentViewers %i", aIndex));
// Check our per SHistory object limit in the currently navigated SHistory // Check our per SHistory object limit in the currently navigated SHistory
EvictOutOfRangeWindowContentViewers(aIndex); EvictOutOfRangeWindowContentViewers(aIndex);
// Check our total limit across all SHistory objects // Check our total limit across all SHistory objects
@ -1186,112 +1165,10 @@ nsSHistory::EvictAllContentViewers() {
return NS_OK; return NS_OK;
} }
/* static */
void nsSHistory::LoadURIOrBFCache(LoadEntryResult& aLoadEntry) {
if (mozilla::BFCacheInParent() && aLoadEntry.mBrowsingContext->IsTop()) {
MOZ_ASSERT(XRE_IsParentProcess());
RefPtr<nsDocShellLoadState> loadState = aLoadEntry.mLoadState;
RefPtr<CanonicalBrowsingContext> canonicalBC =
aLoadEntry.mBrowsingContext->Canonical();
nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(loadState->SHEntry());
nsCOMPtr<SessionHistoryEntry> currentShe =
canonicalBC->GetActiveSessionHistoryEntry();
MOZ_ASSERT(she);
RefPtr<nsFrameLoader> frameLoader = she->GetFrameLoader();
if (canonicalBC->Group()->Toplevels().Length() == 1 && frameLoader &&
(!currentShe || she->SharedInfo() != currentShe->SharedInfo())) {
nsTArray<RefPtr<PContentParent::CanSavePresentationPromise>>
canSavePromises;
canonicalBC->Group()->EachParent([&](ContentParent* aParent) {
RefPtr<PContentParent::CanSavePresentationPromise> canSave =
aParent->SendCanSavePresentation(canonicalBC, Nothing());
canSavePromises.AppendElement(canSave);
});
// Check if the current page can enter bfcache.
PContentParent::CanSavePresentationPromise::All(
GetCurrentSerialEventTarget(), canSavePromises)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[canonicalBC, loadState, she](const nsTArray<bool> aCanSaves) {
bool canSave = !aCanSaves.Contains(false);
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::LoadURIOrBFCache "
"saving presentation=%i",
canSave));
nsCOMPtr<nsFrameLoaderOwner> frameLoaderOwner =
do_QueryInterface(canonicalBC->GetEmbedderElement());
if (frameLoaderOwner) {
RefPtr<nsFrameLoader> fl = she->GetFrameLoader();
if (fl) {
she->SetFrameLoader(nullptr);
RefPtr<BrowsingContext> loadingBC =
fl->GetMaybePendingBrowsingContext();
if (loadingBC) {
RefPtr<nsFrameLoader> currentFrameLoader =
frameLoaderOwner->GetFrameLoader();
// The current page can be bfcached, store the
// nsFrameLoader in the current SessionHistoryEntry.
if (canSave &&
canonicalBC->GetActiveSessionHistoryEntry()) {
canonicalBC->GetActiveSessionHistoryEntry()
->SetFrameLoader(currentFrameLoader);
Unused << canonicalBC->SetIsInBFCache(true);
}
// ReplacedBy will swap the entry back.
canonicalBC->SetActiveSessionHistoryEntry(she);
loadingBC->Canonical()->SetActiveSessionHistoryEntry(
nullptr);
RemotenessChangeOptions options;
canonicalBC->ReplacedBy(loadingBC->Canonical(), options);
frameLoaderOwner->ReplaceFrameLoader(fl);
// The old page can't be stored in the bfcache,
// destroy the nsFrameLoader.
if (!canSave && currentFrameLoader) {
currentFrameLoader->Destroy();
}
// The current active entry should not store
// nsFrameLoader.
loadingBC->Canonical()
->GetSessionHistory()
->UpdateIndex();
loadingBC->Canonical()->HistoryCommitIndexAndLength();
Unused << loadingBC->SetIsInBFCache(false);
// ResetSHEntryHasUserInteractionCache(); ?
// browser.navigation.requireUserInteraction is still
// disabled everywhere.
return;
}
}
}
// Fall back to do a normal load.
canonicalBC->LoadURI(loadState, false);
},
[canonicalBC, loadState](mozilla::ipc::ResponseRejectReason) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsSHistory::LoadURIOrBFCache "
"error in trying to save presentation"));
canonicalBC->LoadURI(loadState, false);
});
return;
}
if (frameLoader) {
she->SetFrameLoader(nullptr);
frameLoader->Destroy();
}
}
aLoadEntry.mBrowsingContext->LoadURI(aLoadEntry.mLoadState, false);
}
/* static */ /* static */
void nsSHistory::LoadURIs(nsTArray<LoadEntryResult>& aLoadResults) { void nsSHistory::LoadURIs(nsTArray<LoadEntryResult>& aLoadResults) {
for (LoadEntryResult& loadEntry : aLoadResults) { for (LoadEntryResult& loadEntry : aLoadResults) {
LoadURIOrBFCache(loadEntry); loadEntry.mBrowsingContext->LoadURI(loadEntry.mLoadState, false);
} }
} }
@ -1420,18 +1297,9 @@ void nsSHistory::EvictOutOfRangeWindowContentViewers(int32_t aIndex) {
// evicted. Collect a set of them so we don't accidentally evict one of them // evicted. Collect a set of them so we don't accidentally evict one of them
// if it appears outside this range. // if it appears outside this range.
nsCOMArray<nsIContentViewer> safeViewers; nsCOMArray<nsIContentViewer> safeViewers;
nsTArray<RefPtr<nsFrameLoader>> safeFrameLoaders;
for (int32_t i = startSafeIndex; i <= endSafeIndex; i++) { for (int32_t i = startSafeIndex; i <= endSafeIndex; i++) {
nsCOMPtr<nsIContentViewer> viewer = mEntries[i]->GetContentViewer(); nsCOMPtr<nsIContentViewer> viewer = mEntries[i]->GetContentViewer();
if (viewer) { safeViewers.AppendObject(viewer);
safeViewers.AppendObject(viewer);
} else if (nsCOMPtr<SessionHistoryEntry> she =
do_QueryInterface(mEntries[i])) {
nsFrameLoader* frameLoader = she->GetFrameLoader();
if (frameLoader) {
safeFrameLoaders.AppendElement(frameLoader);
}
}
} }
// Walk the SHistory list and evict any content viewers that aren't safe. // Walk the SHistory list and evict any content viewers that aren't safe.
@ -1440,18 +1308,8 @@ void nsSHistory::EvictOutOfRangeWindowContentViewers(int32_t aIndex) {
for (int32_t i = 0; i < Length(); i++) { for (int32_t i = 0; i < Length(); i++) {
nsCOMPtr<nsISHEntry> entry = mEntries[i]; nsCOMPtr<nsISHEntry> entry = mEntries[i];
nsCOMPtr<nsIContentViewer> viewer = entry->GetContentViewer(); nsCOMPtr<nsIContentViewer> viewer = entry->GetContentViewer();
if (viewer) { if (safeViewers.IndexOf(viewer) == -1) {
if (safeViewers.IndexOf(viewer) == -1) { EvictContentViewerForEntry(entry);
EvictContentViewerForEntry(entry);
}
} else if (nsCOMPtr<SessionHistoryEntry> she =
do_QueryInterface(mEntries[i])) {
nsFrameLoader* frameLoader = she->GetFrameLoader();
if (frameLoader) {
if (!safeFrameLoaders.Contains(frameLoader)) {
EvictContentViewerForEntry(entry);
}
}
} }
} }
} }
@ -1466,12 +1324,7 @@ class EntryAndDistance {
mViewer(aEntry->GetContentViewer()), mViewer(aEntry->GetContentViewer()),
mLastTouched(mEntry->GetLastTouched()), mLastTouched(mEntry->GetLastTouched()),
mDistance(aDist) { mDistance(aDist) {
nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(aEntry); NS_ASSERTION(mViewer, "Entry should have a content viewer");
if (she) {
mFrameLoader = she->GetFrameLoader();
}
NS_ASSERTION(mViewer || (mozilla::BFCacheInParent() && mFrameLoader),
"Entry should have a content viewer or frame loader.");
} }
bool operator<(const EntryAndDistance& aOther) const { bool operator<(const EntryAndDistance& aOther) const {
@ -1494,7 +1347,6 @@ class EntryAndDistance {
RefPtr<nsSHistory> mSHistory; RefPtr<nsSHistory> mSHistory;
nsCOMPtr<nsISHEntry> mEntry; nsCOMPtr<nsISHEntry> mEntry;
nsCOMPtr<nsIContentViewer> mViewer; nsCOMPtr<nsIContentViewer> mViewer;
RefPtr<nsFrameLoader> mFrameLoader;
uint32_t mLastTouched; uint32_t mLastTouched;
int32_t mDistance; int32_t mDistance;
}; };
@ -1540,14 +1392,12 @@ void nsSHistory::GloballyEvictContentViewers() {
nsCOMPtr<nsISHEntry> entry = shist->mEntries[i]; nsCOMPtr<nsISHEntry> entry = shist->mEntries[i];
nsCOMPtr<nsIContentViewer> contentViewer = entry->GetContentViewer(); nsCOMPtr<nsIContentViewer> contentViewer = entry->GetContentViewer();
bool found = false;
bool hasContentViewerOrFrameLoader = false;
if (contentViewer) { if (contentViewer) {
hasContentViewerOrFrameLoader = true;
// Because one content viewer might belong to multiple SHEntries, we // Because one content viewer might belong to multiple SHEntries, we
// have to search through shEntries to see if we already know // have to search through shEntries to see if we already know
// about this content viewer. If we find the viewer, update its // about this content viewer. If we find the viewer, update its
// distance from the SHistory's index and continue. // distance from the SHistory's index and continue.
bool found = false;
for (uint32_t j = 0; j < shEntries.Length(); j++) { for (uint32_t j = 0; j < shEntries.Length(); j++) {
EntryAndDistance& container = shEntries[j]; EntryAndDistance& container = shEntries[j];
if (container.mViewer == contentViewer) { if (container.mViewer == contentViewer) {
@ -1557,28 +1407,14 @@ void nsSHistory::GloballyEvictContentViewers() {
break; break;
} }
} }
} else if (nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(entry)) {
if (RefPtr<nsFrameLoader> frameLoader = she->GetFrameLoader()) {
hasContentViewerOrFrameLoader = true;
// Similar search as above but using frameloader.
for (uint32_t j = 0; j < shEntries.Length(); j++) {
EntryAndDistance& container = shEntries[j];
if (container.mFrameLoader == frameLoader) {
container.mDistance = std::min(container.mDistance,
DeprecatedAbs(i - shist->mIndex));
found = true;
break;
}
}
}
}
// If we didn't find a EntryAndDistance for this content viewer / // If we didn't find a EntryAndDistance for this content viewer, make a
// frameloader, make a new one. // new one.
if (hasContentViewerOrFrameLoader && !found) { if (!found) {
EntryAndDistance container(shist, entry, EntryAndDistance container(shist, entry,
DeprecatedAbs(i - shist->mIndex)); DeprecatedAbs(i - shist->mIndex));
shEntries.AppendElement(container); shEntries.AppendElement(container);
}
} }
} }

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

@ -154,7 +154,6 @@ class nsSHistory : public mozilla::LinkedListElement<nsSHistory>,
}; };
static void LoadURIs(nsTArray<LoadEntryResult>& aLoadResults); static void LoadURIs(nsTArray<LoadEntryResult>& aLoadResults);
static void LoadURIOrBFCache(LoadEntryResult& aLoadEntry);
// If this doesn't return an error then either aLoadResult is set to nothing, // If this doesn't return an error then either aLoadResult is set to nothing,
// in which case the caller should ignore the load, or it returns a valid // in which case the caller should ignore the load, or it returns a valid

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

@ -113,7 +113,6 @@
#include "mozilla/StaticPrefs_browser.h" #include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_docshell.h" #include "mozilla/StaticPrefs_docshell.h"
#include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_full_screen_api.h" #include "mozilla/StaticPrefs_full_screen_api.h"
#include "mozilla/StaticPrefs_layout.h" #include "mozilla/StaticPrefs_layout.h"
#include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_network.h"
@ -430,7 +429,6 @@
#define NS_MAX_DOCUMENT_WRITE_DEPTH 20 #define NS_MAX_DOCUMENT_WRITE_DEPTH 20
mozilla::LazyLogModule gPageCacheLog("PageCache"); mozilla::LazyLogModule gPageCacheLog("PageCache");
mozilla::LazyLogModule gSHIPBFCacheLog("SHIPBFCache");
mozilla::LazyLogModule gTimeoutDeferralLog("TimeoutDefer"); mozilla::LazyLogModule gTimeoutDeferralLog("TimeoutDefer");
mozilla::LazyLogModule gUseCountersLog("UseCounters"); mozilla::LazyLogModule gUseCountersLog("UseCounters");
@ -10636,8 +10634,7 @@ void Document::CollectDescendantDocuments(
} }
bool Document::CanSavePresentation(nsIRequest* aNewRequest, bool Document::CanSavePresentation(nsIRequest* aNewRequest,
uint16_t& aBFCacheCombo, uint16_t& aBFCacheCombo) {
bool aIncludeSubdocuments) {
bool ret = true; bool ret = true;
if (!IsBFCachingAllowed()) { if (!IsBFCachingAllowed()) {
@ -10766,16 +10763,16 @@ bool Document::CanSavePresentation(nsIRequest* aNewRequest,
ret = false; ret = false;
} }
if (aIncludeSubdocuments && mSubDocuments) { if (mSubDocuments) {
for (auto iter = mSubDocuments->Iter(); !iter.Done(); iter.Next()) { for (auto iter = mSubDocuments->Iter(); !iter.Done(); iter.Next()) {
auto entry = static_cast<SubDocMapEntry*>(iter.Get()); auto entry = static_cast<SubDocMapEntry*>(iter.Get());
Document* subdoc = entry->mSubDocument; Document* subdoc = entry->mSubDocument;
uint16_t subDocBFCacheCombo = 0; uint16_t subDocBFCacheCombo = 0;
// The aIgnoreRequest we were passed is only for us, so don't pass it on. // The aIgnoreRequest we were passed is only for us, so don't pass it on.
bool canCache = subdoc ? subdoc->CanSavePresentation( bool canCache =
nullptr, subDocBFCacheCombo, true) subdoc ? subdoc->CanSavePresentation(nullptr, subDocBFCacheCombo)
: false; : false;
if (!canCache) { if (!canCache) {
MOZ_LOG(gPageCacheLog, mozilla::LogLevel::Verbose, MOZ_LOG(gPageCacheLog, mozilla::LogLevel::Verbose,
("Save of %s blocked due to subdocument blocked", uri.get())); ("Save of %s blocked due to subdocument blocked", uri.get()));
@ -10785,15 +10782,13 @@ bool Document::CanSavePresentation(nsIRequest* aNewRequest,
} }
} }
if (!mozilla::BFCacheInParent()) { // BFCache is currently not compatible with remote subframes (bug 1609324)
// BFCache is currently not compatible with remote subframes (bug 1609324) if (RefPtr<BrowsingContext> browsingContext = GetBrowsingContext()) {
if (RefPtr<BrowsingContext> browsingContext = GetBrowsingContext()) { for (auto& child : browsingContext->Children()) {
for (auto& child : browsingContext->Children()) { if (!child->IsInProcess()) {
if (!child->IsInProcess()) { aBFCacheCombo |= BFCacheStatus::CONTAINS_REMOTE_SUBFRAMES;
aBFCacheCombo |= BFCacheStatus::CONTAINS_REMOTE_SUBFRAMES; ret = false;
ret = false; break;
break;
}
} }
} }
} }
@ -11112,15 +11107,6 @@ void Document::DispatchPageTransition(EventTarget* aDispatchTarget,
void Document::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget, void Document::OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
bool aOnlySystemGroup) { bool aOnlySystemGroup) {
if (MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug)) {
nsCString uri;
if (GetDocumentURI()) {
uri = GetDocumentURI()->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("Document::OnPageShow [%s] persisted=%i", uri.get(), aPersisted));
}
const bool inFrameLoaderSwap = !!aDispatchStartTarget; const bool inFrameLoaderSwap = !!aDispatchStartTarget;
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
inFrameLoaderSwap == inFrameLoaderSwap ==
@ -11197,15 +11183,6 @@ static void ClearPendingFullscreenRequests(Document* aDoc);
void Document::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget, void Document::OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget,
bool aOnlySystemGroup) { bool aOnlySystemGroup) {
if (MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug)) {
nsCString uri;
if (GetDocumentURI()) {
uri = GetDocumentURI()->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("Document::OnPageHide %s persisted=%i", uri.get(), aPersisted));
}
const bool inFrameLoaderSwap = !!aDispatchStartTarget; const bool inFrameLoaderSwap = !!aDispatchStartTarget;
MOZ_DIAGNOSTIC_ASSERT( MOZ_DIAGNOSTIC_ASSERT(
inFrameLoaderSwap == inFrameLoaderSwap ==

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

@ -2319,8 +2319,8 @@ class Document : public nsINode,
/** /**
* Check whether it is safe to cache the presentation of this document * Check whether it is safe to cache the presentation of this document
* and all of its subdocuments (depending on the 3rd param). This method * and all of its subdocuments. This method checks the following conditions
* checks the following conditions recursively: * recursively:
* - Some document types, such as plugin documents, cannot be safely cached. * - Some document types, such as plugin documents, cannot be safely cached.
* - If there are any pending requests, we don't allow the presentation * - If there are any pending requests, we don't allow the presentation
* to be cached. Ideally these requests would be suspended and resumed, * to be cached. Ideally these requests would be suspended and resumed,
@ -2338,8 +2338,7 @@ class Document : public nsINode,
* combination is when we try to BFCache aNewRequest * combination is when we try to BFCache aNewRequest
*/ */
virtual bool CanSavePresentation(nsIRequest* aNewRequest, virtual bool CanSavePresentation(nsIRequest* aNewRequest,
uint16_t& aBFCacheCombo, uint16_t& aBFCacheCombo);
bool aIncludeSubdocuments);
virtual nsresult Init(); virtual nsresult Init();

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

@ -193,17 +193,12 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mWillChangeProcess(false), mWillChangeProcess(false),
mObservingOwnerContent(false), mObservingOwnerContent(false),
mTabProcessCrashFired(false), mTabProcessCrashFired(false),
mNotifyingCrash(false) { mNotifyingCrash(false) {}
nsCOMPtr<nsFrameLoaderOwner> owner = do_QueryInterface(aOwner);
owner->AttachFrameLoader(this);
}
nsFrameLoader::~nsFrameLoader() { nsFrameLoader::~nsFrameLoader() {
if (mMessageManager) { if (mMessageManager) {
mMessageManager->Disconnect(); mMessageManager->Disconnect();
} }
MOZ_ASSERT(!mOwnerContent);
MOZ_RELEASE_ASSERT(mDestroyCalled); MOZ_RELEASE_ASSERT(mDestroyCalled);
} }
@ -457,9 +452,8 @@ already_AddRefed<nsFrameLoader> nsFrameLoader::Create(
/* static */ /* static */
already_AddRefed<nsFrameLoader> nsFrameLoader::Recreate( already_AddRefed<nsFrameLoader> nsFrameLoader::Recreate(
mozilla::dom::Element* aOwner, BrowsingContext* aContext, mozilla::dom::Element* aOwner, BrowsingContext* aContext,
BrowsingContextGroup* aSpecificGroup, BrowsingContextGroup* aSpecificGroup, bool aIsRemote, bool aNetworkCreated,
const RemotenessChangeOptions& aRemotenessOptions, bool aIsRemote, bool aPreserveContext) {
bool aNetworkCreated, bool aPreserveContext) {
NS_ENSURE_TRUE(aOwner, nullptr); NS_ENSURE_TRUE(aOwner, nullptr);
#ifdef DEBUG #ifdef DEBUG
@ -479,8 +473,7 @@ already_AddRefed<nsFrameLoader> nsFrameLoader::Recreate(
MOZ_ASSERT( MOZ_ASSERT(
XRE_IsParentProcess(), XRE_IsParentProcess(),
"Recreating browing contexts only supported in the parent process"); "Recreating browing contexts only supported in the parent process");
aContext->Canonical()->ReplacedBy(context->Canonical(), aContext->Canonical()->ReplacedBy(context->Canonical());
aRemotenessOptions);
} }
} }
NS_ENSURE_TRUE(context, nullptr); NS_ENSURE_TRUE(context, nullptr);
@ -1877,9 +1870,6 @@ void nsFrameLoader::StartDestroy(bool aForProcessSwitch) {
!doc->InUnlinkOrDeletion(); !doc->InUnlinkOrDeletion();
doc->SetSubDocumentFor(mOwnerContent, nullptr); doc->SetSubDocumentFor(mOwnerContent, nullptr);
MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved); MaybeUpdatePrimaryBrowserParent(eBrowserParentRemoved);
nsCOMPtr<nsFrameLoaderOwner> owner = do_QueryInterface(mOwnerContent);
owner->FrameLoaderDestroying(this);
SetOwnerContent(nullptr); SetOwnerContent(nullptr);
} }
@ -2067,20 +2057,8 @@ void nsFrameLoader::SetOwnerContent(Element* aContent) {
mObservingOwnerContent = false; mObservingOwnerContent = false;
mOwnerContent->RemoveMutationObserver(this); mOwnerContent->RemoveMutationObserver(this);
} }
// XXXBFCache Need to update also all the non-current FrameLoaders in the
// owner when moving a FrameLoader.
// This temporary setup doesn't crash, but behaves badly with bfcached docs.
if (RefPtr<nsFrameLoaderOwner> owner = do_QueryObject(mOwnerContent)) {
owner->DetachFrameLoader(this);
}
mOwnerContent = aContent; mOwnerContent = aContent;
if (RefPtr<nsFrameLoaderOwner> owner = do_QueryObject(mOwnerContent)) {
owner->AttachFrameLoader(this);
}
if (mSessionStoreListener && mOwnerContent) { if (mSessionStoreListener && mOwnerContent) {
// mOwnerContent will only be null when the frame loader is being destroyed, // mOwnerContent will only be null when the frame loader is being destroyed,
// so the session store listener will be destroyed along with it. // so the session store listener will be destroyed along with it.

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

@ -19,7 +19,6 @@
#include "mozilla/AlreadyAddRefed.h" #include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Nullable.h" #include "mozilla/dom/Nullable.h"
@ -72,7 +71,6 @@ class MutableTabContext;
class BrowserBridgeChild; class BrowserBridgeChild;
class RemoteBrowser; class RemoteBrowser;
struct RemotenessOptions; struct RemotenessOptions;
struct RemotenessChangeOptions;
namespace ipc { namespace ipc {
class StructuredCloneData; class StructuredCloneData;
@ -99,8 +97,7 @@ typedef struct _GtkWidget GtkWidget;
class nsFrameLoader final : public nsStubMutationObserver, class nsFrameLoader final : public nsStubMutationObserver,
public mozilla::dom::ipc::MessageManagerCallback, public mozilla::dom::ipc::MessageManagerCallback,
public nsWrapperCache, public nsWrapperCache {
public mozilla::LinkedListElement<nsFrameLoader> {
friend class AutoResetInShow; friend class AutoResetInShow;
friend class AutoResetInFrameSwap; friend class AutoResetInFrameSwap;
friend class nsFrameLoaderOwner; friend class nsFrameLoaderOwner;
@ -122,7 +119,6 @@ class nsFrameLoader final : public nsStubMutationObserver,
// FrameLoaders. // FrameLoaders.
static already_AddRefed<nsFrameLoader> Recreate( static already_AddRefed<nsFrameLoader> Recreate(
Element* aOwner, BrowsingContext* aContext, BrowsingContextGroup* aGroup, Element* aOwner, BrowsingContext* aContext, BrowsingContextGroup* aGroup,
const mozilla::dom::RemotenessChangeOptions& aRemotenessOptions,
bool aIsRemote, bool aNetworkCreated, bool aPreserveContext); bool aIsRemote, bool aNetworkCreated, bool aPreserveContext);
NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_FRAMELOADER_IID)

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

@ -11,8 +11,6 @@
#include "nsSubDocumentFrame.h" #include "nsSubDocumentFrame.h"
#include "nsQueryObject.h" #include "nsQueryObject.h"
#include "mozilla/AsyncEventDispatcher.h" #include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/Logging.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/FrameLoaderBinding.h" #include "mozilla/dom/FrameLoaderBinding.h"
#include "mozilla/dom/HTMLIFrameElement.h" #include "mozilla/dom/HTMLIFrameElement.h"
@ -25,8 +23,6 @@
#include "mozilla/StaticPrefs_fission.h" #include "mozilla/StaticPrefs_fission.h"
#include "mozilla/EventStateManager.h" #include "mozilla/EventStateManager.h"
extern mozilla::LazyLogModule gSHIPBFCacheLog;
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -91,8 +87,7 @@ nsFrameLoaderOwner::ShouldPreserveBrowsingContext(
void nsFrameLoaderOwner::ChangeRemotenessCommon( void nsFrameLoaderOwner::ChangeRemotenessCommon(
const ChangeRemotenessContextType& aContextType, const ChangeRemotenessContextType& aContextType,
const RemotenessChangeOptions& aOptions, bool aSwitchingInProgressLoad, bool aSwitchingInProgressLoad, bool aIsRemote, BrowsingContextGroup* aGroup,
bool aIsRemote, BrowsingContextGroup* aGroup,
std::function<void()>& aFrameLoaderInit, mozilla::ErrorResult& aRv) { std::function<void()>& aFrameLoaderInit, mozilla::ErrorResult& aRv) {
MOZ_ASSERT_IF(aGroup, aContextType != ChangeRemotenessContextType::PRESERVE); MOZ_ASSERT_IF(aGroup, aContextType != ChangeRemotenessContextType::PRESERVE);
@ -129,40 +124,19 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon(
// or want, so we use the initial (possibly pending) browsing context // or want, so we use the initial (possibly pending) browsing context
// directly, instead. // directly, instead.
bc = mFrameLoader->GetMaybePendingBrowsingContext(); bc = mFrameLoader->GetMaybePendingBrowsingContext();
if (aContextType == ChangeRemotenessContextType::PRESERVE) {
mFrameLoader->SetWillChangeProcess();
}
// Preserve the networkCreated status, as nsDocShells created after a
// process swap may shouldn't change their dynamically-created status.
networkCreated = mFrameLoader->IsNetworkCreated(); networkCreated = mFrameLoader->IsNetworkCreated();
mFrameLoader->Destroy(aSwitchingInProgressLoad);
MOZ_ASSERT_IF(aOptions.mTryUseBFCache, aOptions.mReplaceBrowsingContext); mFrameLoader = nullptr;
if (aOptions.mTryUseBFCache) {
if (bc) {
SessionHistoryEntry* she =
bc->Canonical()->GetActiveSessionHistoryEntry();
if (she) {
MOZ_LOG(
gSHIPBFCacheLog, LogLevel::Debug,
("nsFrameLoaderOwner::ChangeRemotenessCommon: store the old "
"page in bfcache"));
Unused << bc->SetIsInBFCache(true);
she->SetFrameLoader(mFrameLoader);
// Session history owns now the frameloader.
mFrameLoader = nullptr;
}
}
}
if (mFrameLoader) {
if (aContextType == ChangeRemotenessContextType::PRESERVE) {
mFrameLoader->SetWillChangeProcess();
}
// Preserve the networkCreated status, as nsDocShells created after a
// process swap may shouldn't change their dynamically-created status.
mFrameLoader->Destroy(aSwitchingInProgressLoad);
mFrameLoader = nullptr;
}
} }
mFrameLoader = nsFrameLoader::Recreate( mFrameLoader = nsFrameLoader::Recreate(
owner, bc, aGroup, aOptions, aIsRemote, networkCreated, owner, bc, aGroup, aIsRemote, networkCreated,
aContextType == ChangeRemotenessContextType::PRESERVE); aContextType == ChangeRemotenessContextType::PRESERVE);
if (NS_WARN_IF(!mFrameLoader)) { if (NS_WARN_IF(!mFrameLoader)) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
@ -178,38 +152,34 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon(
} }
} }
ChangeFrameLoaderCommon(owner);
}
void nsFrameLoaderOwner::ChangeFrameLoaderCommon(Element* aOwner) {
// Now that we've got a new FrameLoader, we need to reset our // Now that we've got a new FrameLoader, we need to reset our
// nsSubDocumentFrame to use the new FrameLoader. // nsSubDocumentFrame to use the new FrameLoader.
if (nsSubDocumentFrame* ourFrame = do_QueryFrame(aOwner->GetPrimaryFrame())) { if (nsSubDocumentFrame* ourFrame = do_QueryFrame(owner->GetPrimaryFrame())) {
ourFrame->ResetFrameLoader(); ourFrame->ResetFrameLoader();
} }
// If the element is focused, or the current mouse over target then // If the element is focused, or the current mouse over target then
// we need to update that state for the new BrowserParent too. // we need to update that state for the new BrowserParent too.
if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) { if (nsFocusManager* fm = nsFocusManager::GetFocusManager()) {
if (fm->GetFocusedElement() == aOwner) { if (fm->GetFocusedElement() == owner) {
fm->ActivateRemoteFrameIfNeeded(*aOwner, fm->ActivateRemoteFrameIfNeeded(*owner,
nsFocusManager::GenerateFocusActionId()); nsFocusManager::GenerateFocusActionId());
} }
} }
if (aOwner->GetPrimaryFrame()) { if (owner->GetPrimaryFrame()) {
EventStateManager* eventManager = EventStateManager* eventManager =
aOwner->GetPrimaryFrame()->PresContext()->EventStateManager(); owner->GetPrimaryFrame()->PresContext()->EventStateManager();
eventManager->RecomputeMouseEnterStateForRemoteFrame(*aOwner); eventManager->RecomputeMouseEnterStateForRemoteFrame(*owner);
} }
if (aOwner->IsXULElement()) { if (owner->IsXULElement()) {
// Assuming this element is a XULFrameElement, once we've reset our // Assuming this element is a XULFrameElement, once we've reset our
// FrameLoader, fire an event to act like we've recreated ourselves, similar // FrameLoader, fire an event to act like we've recreated ourselves, similar
// to what XULFrameElement does after rebinding to the tree. // to what XULFrameElement does after rebinding to the tree.
// ChromeOnlyDispatch is turns on to make sure this isn't fired into // ChromeOnlyDispatch is turns on to make sure this isn't fired into
// content. // content.
(new mozilla::AsyncEventDispatcher(aOwner, u"XULFrameLoaderCreated"_ns, (new mozilla::AsyncEventDispatcher(owner, u"XULFrameLoaderCreated"_ns,
mozilla::CanBubble::eYes, mozilla::CanBubble::eYes,
mozilla::ChromeOnlyDispatch::eYes)) mozilla::ChromeOnlyDispatch::eYes))
->RunDOMEventWhenSafe(); ->RunDOMEventWhenSafe();
@ -234,10 +204,8 @@ void nsFrameLoaderOwner::ChangeRemoteness(
auto shouldPreserve = ShouldPreserveBrowsingContext( auto shouldPreserve = ShouldPreserveBrowsingContext(
isRemote, /* replaceBrowsingContext */ false); isRemote, /* replaceBrowsingContext */ false);
RemotenessChangeOptions options; ChangeRemotenessCommon(shouldPreserve, aOptions.mSwitchingInProgressLoad,
ChangeRemotenessCommon(shouldPreserve, options, isRemote, /* group */ nullptr, frameLoaderInit, rv);
aOptions.mSwitchingInProgressLoad, isRemote,
/* group */ nullptr, frameLoaderInit, rv);
} }
void nsFrameLoaderOwner::ChangeRemotenessWithBridge(BrowserBridgeChild* aBridge, void nsFrameLoaderOwner::ChangeRemotenessWithBridge(BrowserBridgeChild* aBridge,
@ -255,18 +223,17 @@ void nsFrameLoaderOwner::ChangeRemotenessWithBridge(BrowserBridgeChild* aBridge,
mFrameLoader->mRemoteBrowser = host; mFrameLoader->mRemoteBrowser = host;
}; };
RemotenessChangeOptions options; ChangeRemotenessCommon(ChangeRemotenessContextType::PRESERVE,
ChangeRemotenessCommon(ChangeRemotenessContextType::PRESERVE, options,
/* inProgress */ true, /* inProgress */ true,
/* isRemote */ true, /* group */ nullptr, /* isRemote */ true, /* group */ nullptr,
frameLoaderInit, rv); frameLoaderInit, rv);
} }
void nsFrameLoaderOwner::ChangeRemotenessToProcess( void nsFrameLoaderOwner::ChangeRemotenessToProcess(
ContentParent* aContentParent, const RemotenessChangeOptions& aOptions, ContentParent* aContentParent, bool aReplaceBrowsingContext,
BrowsingContextGroup* aGroup, mozilla::ErrorResult& rv) { BrowsingContextGroup* aGroup, mozilla::ErrorResult& rv) {
MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT_IF(aGroup, aOptions.mReplaceBrowsingContext); MOZ_ASSERT_IF(aGroup, aReplaceBrowsingContext);
bool isRemote = aContentParent != nullptr; bool isRemote = aContentParent != nullptr;
std::function<void()> frameLoaderInit = [&] { std::function<void()> frameLoaderInit = [&] {
@ -277,9 +244,9 @@ void nsFrameLoaderOwner::ChangeRemotenessToProcess(
}; };
auto shouldPreserve = auto shouldPreserve =
ShouldPreserveBrowsingContext(isRemote, aOptions.mReplaceBrowsingContext); ShouldPreserveBrowsingContext(isRemote, aReplaceBrowsingContext);
ChangeRemotenessCommon(shouldPreserve, aOptions, /* inProgress */ true, ChangeRemotenessCommon(shouldPreserve, /* inProgress */ true, isRemote,
isRemote, aGroup, frameLoaderInit, rv); aGroup, frameLoaderInit, rv);
} }
void nsFrameLoaderOwner::SubframeCrashed() { void nsFrameLoaderOwner::SubframeCrashed() {
@ -306,47 +273,7 @@ void nsFrameLoaderOwner::SubframeCrashed() {
})); }));
}; };
RemotenessChangeOptions options; ChangeRemotenessCommon(ChangeRemotenessContextType::PRESERVE,
ChangeRemotenessCommon(ChangeRemotenessContextType::PRESERVE, options,
/* inProgress */ false, /* isRemote */ false, /* inProgress */ false, /* isRemote */ false,
/* group */ nullptr, frameLoaderInit, IgnoreErrors()); /* group */ nullptr, frameLoaderInit, IgnoreErrors());
} }
void nsFrameLoaderOwner::ReplaceFrameLoader(nsFrameLoader* aNewFrameLoader) {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("nsFrameLoaderOwner::ReplaceFrameLoader: Replace frameloader"));
mFrameLoader = aNewFrameLoader;
if (auto* browserParent = mFrameLoader->GetBrowserParent()) {
browserParent->AddWindowListeners();
browserParent->ResumeProgressEvents();
}
RefPtr<Element> owner = do_QueryObject(this);
ChangeFrameLoaderCommon(owner);
}
void nsFrameLoaderOwner::AttachFrameLoader(nsFrameLoader* aFrameLoader) {
mFrameLoaderList.insertBack(aFrameLoader);
}
void nsFrameLoaderOwner::DetachFrameLoader(nsFrameLoader* aFrameLoader) {
if (aFrameLoader->isInList()) {
MOZ_ASSERT(mFrameLoaderList.contains(aFrameLoader));
aFrameLoader->remove();
}
}
void nsFrameLoaderOwner::FrameLoaderDestroying(nsFrameLoader* aFrameLoader) {
if (aFrameLoader == mFrameLoader) {
while (!mFrameLoaderList.isEmpty()) {
RefPtr<nsFrameLoader> loader = mFrameLoaderList.popFirst();
if (loader != mFrameLoader) {
loader->Destroy();
}
}
} else {
DetachFrameLoader(aFrameLoader);
}
}

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

@ -18,9 +18,7 @@ class BrowsingContext;
class BrowsingContextGroup; class BrowsingContextGroup;
class BrowserBridgeChild; class BrowserBridgeChild;
class ContentParent; class ContentParent;
class Element;
struct RemotenessOptions; struct RemotenessOptions;
struct RemotenessChangeOptions;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
@ -73,19 +71,13 @@ class nsFrameLoaderOwner : public nsISupports {
// //
// If `aReplaceBrowsingContext` is set, BrowsingContext preservation will be // If `aReplaceBrowsingContext` is set, BrowsingContext preservation will be
// disabled for this process switch. // disabled for this process switch.
void ChangeRemotenessToProcess( void ChangeRemotenessToProcess(mozilla::dom::ContentParent* aContentParent,
mozilla::dom::ContentParent* aContentParent, bool aReplaceBrowsingContext,
const mozilla::dom::RemotenessChangeOptions& aOptions, mozilla::dom::BrowsingContextGroup* aGroup,
mozilla::dom::BrowsingContextGroup* aGroup, mozilla::ErrorResult& rv); mozilla::ErrorResult& rv);
void SubframeCrashed(); void SubframeCrashed();
void ReplaceFrameLoader(nsFrameLoader* aNewFrameLoader);
void AttachFrameLoader(nsFrameLoader* aFrameLoader);
void DetachFrameLoader(nsFrameLoader* aFrameLoader);
void FrameLoaderDestroying(nsFrameLoader* aFrameLoader);
private: private:
bool UseRemoteSubframes(); bool UseRemoteSubframes();
@ -102,23 +94,15 @@ class nsFrameLoaderOwner : public nsISupports {
ChangeRemotenessContextType ShouldPreserveBrowsingContext( ChangeRemotenessContextType ShouldPreserveBrowsingContext(
bool aIsRemote, bool aReplaceBrowsingContext); bool aIsRemote, bool aReplaceBrowsingContext);
void ChangeRemotenessCommon( void ChangeRemotenessCommon(const ChangeRemotenessContextType& aContextType,
const ChangeRemotenessContextType& aContextType, bool aSwitchingInProgressLoad, bool aIsRemote,
const mozilla::dom::RemotenessChangeOptions& aOptions, mozilla::dom::BrowsingContextGroup* aGroup,
bool aSwitchingInProgressLoad, bool aIsRemote, std::function<void()>& aFrameLoaderInit,
mozilla::dom::BrowsingContextGroup* aGroup, mozilla::ErrorResult& aRv);
std::function<void()>& aFrameLoaderInit, mozilla::ErrorResult& aRv);
void ChangeFrameLoaderCommon(mozilla::dom::Element* aOwner);
protected: protected:
virtual ~nsFrameLoaderOwner() = default; virtual ~nsFrameLoaderOwner() = default;
RefPtr<nsFrameLoader> mFrameLoader; RefPtr<nsFrameLoader> mFrameLoader;
// The list contains all the nsFrameLoaders created for this owner or moved
// from another nsFrameLoaderOwner which haven't been destroyed yet.
// In particular it contains all the nsFrameLoaders which are in bfcache.
mozilla::LinkedList<nsFrameLoader> mFrameLoaderList;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsFrameLoaderOwner, NS_FRAMELOADEROWNER_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsFrameLoaderOwner, NS_FRAMELOADEROWNER_IID)

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

@ -2419,13 +2419,11 @@ bool nsPIDOMWindowInner::IsSecureContext() const {
return nsGlobalWindowInner::Cast(this)->IsSecureContext(); return nsGlobalWindowInner::Cast(this)->IsSecureContext();
} }
void nsPIDOMWindowInner::Suspend(bool aIncludeSubWindows) { void nsPIDOMWindowInner::Suspend() {
nsGlobalWindowInner::Cast(this)->Suspend(aIncludeSubWindows); nsGlobalWindowInner::Cast(this)->Suspend();
} }
void nsPIDOMWindowInner::Resume(bool aIncludeSubWindows) { void nsPIDOMWindowInner::Resume() { nsGlobalWindowInner::Cast(this)->Resume(); }
nsGlobalWindowInner::Cast(this)->Resume(aIncludeSubWindows);
}
void nsPIDOMWindowInner::SyncStateFromParentWindow() { void nsPIDOMWindowInner::SyncStateFromParentWindow() {
nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow(); nsGlobalWindowInner::Cast(this)->SyncStateFromParentWindow();
@ -5443,7 +5441,7 @@ already_AddRefed<StorageEvent> nsGlobalWindowInner::CloneStorageEvent(
return event.forget(); return event.forget();
} }
void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) { void nsGlobalWindowInner::Suspend() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
// We can only safely suspend windows that are the current inner window. If // We can only safely suspend windows that are the current inner window. If
@ -5461,9 +5459,7 @@ void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
// All children are also suspended. This ensure mSuspendDepth is // All children are also suspended. This ensure mSuspendDepth is
// set properly and the timers are properly canceled for each child. // set properly and the timers are properly canceled for each child.
if (aIncludeSubWindows) { CallOnInProcessChildren(&nsGlobalWindowInner::Suspend);
CallOnInProcessChildren(&nsGlobalWindowInner::Suspend, aIncludeSubWindows);
}
mSuspendDepth += 1; mSuspendDepth += 1;
if (mSuspendDepth != 1) { if (mSuspendDepth != 1) {
@ -5495,7 +5491,7 @@ void nsGlobalWindowInner::Suspend(bool aIncludeSubWindows) {
} }
} }
void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) { void nsGlobalWindowInner::Resume() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
// We can only safely resume a window if its the current inner window. If // We can only safely resume a window if its the current inner window. If
@ -5510,9 +5506,7 @@ void nsGlobalWindowInner::Resume(bool aIncludeSubWindows) {
// Resume all children. This restores timers recursively canceled // Resume all children. This restores timers recursively canceled
// in Suspend() and ensures all children have the correct mSuspendDepth. // in Suspend() and ensures all children have the correct mSuspendDepth.
if (aIncludeSubWindows) { CallOnInProcessChildren(&nsGlobalWindowInner::Resume);
CallOnInProcessChildren(&nsGlobalWindowInner::Resume, aIncludeSubWindows);
}
if (mSuspendDepth == 0) { if (mSuspendDepth == 0) {
// Ignore if the window is not suspended. // Ignore if the window is not suspended.
@ -5562,23 +5556,20 @@ bool nsGlobalWindowInner::IsSuspended() const {
return mSuspendDepth != 0; return mSuspendDepth != 0;
} }
void nsGlobalWindowInner::Freeze(bool aIncludeSubWindows) { void nsGlobalWindowInner::Freeze() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
Suspend(aIncludeSubWindows); Suspend();
FreezeInternal(aIncludeSubWindows); FreezeInternal();
} }
void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) { void nsGlobalWindowInner::FreezeInternal() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow()); MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsSuspended()); MOZ_DIAGNOSTIC_ASSERT(IsSuspended());
HintIsLoading(false); HintIsLoading(false);
if (aIncludeSubWindows) { CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal);
CallOnInProcessChildren(&nsGlobalWindowInner::FreezeInternal,
aIncludeSubWindows);
}
mFreezeDepth += 1; mFreezeDepth += 1;
MOZ_ASSERT(mSuspendDepth >= mFreezeDepth); MOZ_ASSERT(mSuspendDepth >= mFreezeDepth);
@ -5601,21 +5592,18 @@ void nsGlobalWindowInner::FreezeInternal(bool aIncludeSubWindows) {
NotifyDOMWindowFrozen(this); NotifyDOMWindowFrozen(this);
} }
void nsGlobalWindowInner::Thaw(bool aIncludeSubWindows) { void nsGlobalWindowInner::Thaw() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
ThawInternal(aIncludeSubWindows); ThawInternal();
Resume(aIncludeSubWindows); Resume();
} }
void nsGlobalWindowInner::ThawInternal(bool aIncludeSubWindows) { void nsGlobalWindowInner::ThawInternal() {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow()); MOZ_DIAGNOSTIC_ASSERT(IsCurrentInnerWindow());
MOZ_DIAGNOSTIC_ASSERT(IsSuspended()); MOZ_DIAGNOSTIC_ASSERT(IsSuspended());
if (aIncludeSubWindows) { CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal);
CallOnInProcessChildren(&nsGlobalWindowInner::ThawInternal,
aIncludeSubWindows);
}
MOZ_ASSERT(mFreezeDepth != 0); MOZ_ASSERT(mFreezeDepth != 0);
mFreezeDepth -= 1; mFreezeDepth -= 1;

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

@ -310,19 +310,19 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
nsresult PostHandleEvent(mozilla::EventChainPostVisitor& aVisitor) override; nsresult PostHandleEvent(mozilla::EventChainPostVisitor& aVisitor) override;
void Suspend(bool aIncludeSubWindows = true); void Suspend();
void Resume(bool aIncludeSubWindows = true); void Resume();
virtual bool IsSuspended() const override; virtual bool IsSuspended() const override;
// Calling Freeze() on a window will automatically Suspend() it. In // Calling Freeze() on a window will automatically Suspend() it. In
// addition, the window and its children (if aIncludeSubWindows is true) are // addition, the window and its children are further treated as no longer
// further treated as no longer suitable for interaction with the user. For // suitable for interaction with the user. For example, it may be marked
// example, it may be marked non-visible, cannot be focused, etc. All worker // non-visible, cannot be focused, etc. All worker threads are also frozen
// threads are also frozen bringing them to a complete stop. A window can // bringing them to a complete stop. A window can have Freeze() called
// have Freeze() called multiple times and will only thaw after a matching // multiple times and will only thaw after a matching number of Thaw()
// number of Thaw() calls. // calls.
void Freeze(bool aIncludeSubWindows = true); void Freeze();
void Thaw(bool aIncludeSubWindows = true); void Thaw();
virtual bool IsFrozen() const override; virtual bool IsFrozen() const override;
void SyncStateFromParentWindow(); void SyncStateFromParentWindow();
@ -1064,8 +1064,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
return (aWindow->*aMethod)(aArgs...); return (aWindow->*aMethod)(aArgs...);
} }
void FreezeInternal(bool aIncludeSubWindows); void FreezeInternal();
void ThawInternal(bool aIncludeSubWindows); void ThawInternal();
mozilla::CallState ShouldReportForServiceWorkerScopeInternal( mozilla::CallState ShouldReportForServiceWorkerScopeInternal(
const nsACString& aScope, bool* aResultOut); const nsACString& aScope, bool* aResultOut);

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

@ -297,12 +297,12 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
// Calling suspend should prevent any asynchronous tasks from // Calling suspend should prevent any asynchronous tasks from
// executing javascript for this window. This means setTimeout, // executing javascript for this window. This means setTimeout,
// requestAnimationFrame, and events should not be fired. Suspending // requestAnimationFrame, and events should not be fired. Suspending
// a window maybe also suspends its children. Workers may // a window also suspends its children and workers. Workers may
// continue to perform computations in the background. A window // continue to perform computations in the background. A window
// can have Suspend() called multiple times and will only resume after // can have Suspend() called multiple times and will only resume after
// a matching number of Resume() calls. // a matching number of Resume() calls.
void Suspend(bool aIncludeSubWindows = true); void Suspend();
void Resume(bool aIncludeSubWindows = true); void Resume();
// Whether or not this window was suspended by the BrowserContextGroup // Whether or not this window was suspended by the BrowserContextGroup
bool GetWasSuspendedByGroup() const { return mWasSuspendedByGroup; } bool GetWasSuspendedByGroup() const { return mWasSuspendedByGroup; }

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

@ -39,8 +39,8 @@ class PluginDocument final : public MediaDocument, public nsIPluginDocument {
void SetScriptGlobalObject( void SetScriptGlobalObject(
nsIScriptGlobalObject* aScriptGlobalObject) override; nsIScriptGlobalObject* aScriptGlobalObject) override;
bool CanSavePresentation(nsIRequest* aNewRequest, uint16_t& aBFCacheStatus, bool CanSavePresentation(nsIRequest* aNewRequest,
bool aIncludeSubdocuments = true) override; uint16_t& aBFCacheStatus) override;
const nsCString& GetType() const { return mMimeType; } const nsCString& GetType() const { return mMimeType; }
Element* GetPluginContent() { return mPluginContent; } Element* GetPluginContent() { return mPluginContent; }
@ -135,8 +135,7 @@ void PluginDocument::SetScriptGlobalObject(
} }
bool PluginDocument::CanSavePresentation(nsIRequest* aNewRequest, bool PluginDocument::CanSavePresentation(nsIRequest* aNewRequest,
uint16_t& aBFCacheStatus, uint16_t& aBFCacheStatus) {
bool aIncludeSubdocuments) {
// Full-page plugins cannot be cached, currently, because we don't have // Full-page plugins cannot be cached, currently, because we don't have
// the stream listener data to feed to the plugin instance. // the stream listener data to feed to the plugin instance.
return false; return false;

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

@ -710,7 +710,6 @@ class BrowserParent final : public PBrowserParent,
// Suspend nsIWebProgressListener events. This is used to block any further // Suspend nsIWebProgressListener events. This is used to block any further
// progress events from the old process when process switching away. // progress events from the old process when process switching away.
void SuspendProgressEvents() { mSuspendedProgressEvents = true; } void SuspendProgressEvents() { mSuspendedProgressEvents = true; }
void ResumeProgressEvents() { mSuspendedProgressEvents = false; }
bool CanCancelContentJS(nsIRemoteTab::NavigationType aNavigationType, bool CanCancelContentJS(nsIRemoteTab::NavigationType aNavigationType,
int32_t aNavigationIndex, int32_t aNavigationIndex,

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

@ -28,7 +28,6 @@
#include "mozilla/Components.h" #include "mozilla/Components.h"
#include "mozilla/HangDetails.h" #include "mozilla/HangDetails.h"
#include "mozilla/LoadInfo.h" #include "mozilla/LoadInfo.h"
#include "mozilla/Logging.h"
#include "mozilla/LookAndFeel.h" #include "mozilla/LookAndFeel.h"
#include "mozilla/MemoryTelemetry.h" #include "mozilla/MemoryTelemetry.h"
#include "mozilla/NullPrincipal.h" #include "mozilla/NullPrincipal.h"
@ -42,7 +41,6 @@
#include "mozilla/SchedulerGroup.h" #include "mozilla/SchedulerGroup.h"
#include "mozilla/ScopeExit.h" #include "mozilla/ScopeExit.h"
#include "mozilla/SharedStyleSheetCache.h" #include "mozilla/SharedStyleSheetCache.h"
#include "mozilla/SimpleEnumerator.h"
#include "mozilla/SpinEventLoopUntil.h" #include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_fission.h" #include "mozilla/StaticPrefs_fission.h"
@ -110,7 +108,6 @@
#include "mozilla/media/MediaChild.h" #include "mozilla/media/MediaChild.h"
#include "mozilla/net/CaptivePortalService.h" #include "mozilla/net/CaptivePortalService.h"
#include "mozilla/net/CookieServiceChild.h" #include "mozilla/net/CookieServiceChild.h"
#include "mozilla/net/DocumentChannelChild.h"
#include "mozilla/net/HttpChannelChild.h" #include "mozilla/net/HttpChannelChild.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
#include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/plugins/PluginInstanceParent.h"
@ -123,9 +120,7 @@
#include "nsFocusManager.h" #include "nsFocusManager.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsIInputStreamChannel.h" #include "nsIInputStreamChannel.h"
#include "nsILoadGroup.h"
#include "nsIOpenWindowInfo.h" #include "nsIOpenWindowInfo.h"
#include "nsISimpleEnumerator.h"
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsIURIMutator.h" #include "nsIURIMutator.h"
#include "nsQueryObject.h" #include "nsQueryObject.h"
@ -295,8 +290,6 @@
# include "mozilla/CodeCoverageHandler.h" # include "mozilla/CodeCoverageHandler.h"
#endif #endif
extern mozilla::LazyLogModule gSHIPBFCacheLog;
using namespace mozilla; using namespace mozilla;
using namespace mozilla::docshell; using namespace mozilla::docshell;
using namespace mozilla::dom::ipc; using namespace mozilla::dom::ipc;
@ -4250,65 +4243,6 @@ mozilla::ipc::IPCResult ContentChild::RecvDispatchBeforeUnloadToSubtree(
return IPC_OK(); return IPC_OK();
} }
mozilla::ipc::IPCResult ContentChild::RecvCanSavePresentation(
const MaybeDiscarded<BrowsingContext>& aTopLevelContext,
Maybe<uint64_t> aDocumentChannelId,
CanSavePresentationResolver&& aResolver) {
if (aTopLevelContext.IsNullOrDiscarded()) {
aResolver(false);
return IPC_OK();
}
bool canSave = true;
// XXXBFCache pass the flags to telemetry.
uint16_t flags = 0;
BrowsingContext* browsingContext = aTopLevelContext.get();
browsingContext->PreOrderWalk([&](BrowsingContext* aContext) {
Document* doc = aContext->GetDocument();
if (doc) {
nsIRequest* request = nullptr;
if (aDocumentChannelId.isSome() && aContext->IsTop()) {
nsCOMPtr<nsILoadGroup> loadGroup = doc->GetDocumentLoadGroup();
if (loadGroup) {
nsCOMPtr<nsISimpleEnumerator> requests;
loadGroup->GetRequests(getter_AddRefs(requests));
bool hasMore = false;
if (NS_SUCCEEDED(requests->HasMoreElements(&hasMore)) && hasMore) {
// If there are any requests, the only one we allow with bfcache
// is the DocumentChannel request.
nsCOMPtr<nsISupports> elem;
requests->GetNext(getter_AddRefs(elem));
nsCOMPtr<nsIIdentChannel> identChannel = do_QueryInterface(elem);
if (identChannel &&
identChannel->ChannelId() == aDocumentChannelId.value()) {
request = identChannel;
}
}
}
}
// Go through also the subdocuments so that flags are collected.
bool canSaveDoc = doc->CanSavePresentation(request, flags, false);
canSave = canSaveDoc && canSave;
if (MOZ_LOG_TEST(gSHIPBFCacheLog, LogLevel::Debug)) {
nsAutoCString uri;
if (doc->GetDocumentURI()) {
uri = doc->GetDocumentURI()->GetSpecOrDefault();
}
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("ContentChild::RecvCanSavePresentation can save presentation "
"[%i] for [%s]",
canSaveDoc, uri.get()));
}
}
});
aResolver(canSave);
return IPC_OK();
}
/* static */ void ContentChild::DispatchBeforeUnloadToSubtree( /* static */ void ContentChild::DispatchBeforeUnloadToSubtree(
BrowsingContext* aStartingAt, BrowsingContext* aStartingAt,
const DispatchBeforeUnloadToSubtreeResolver& aResolver) { const DispatchBeforeUnloadToSubtreeResolver& aResolver) {

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

@ -824,11 +824,6 @@ class ContentChild final : public PContentChild,
const MaybeDiscarded<BrowsingContext>& aStartingAt, const MaybeDiscarded<BrowsingContext>& aStartingAt,
DispatchBeforeUnloadToSubtreeResolver&& aResolver); DispatchBeforeUnloadToSubtreeResolver&& aResolver);
mozilla::ipc::IPCResult RecvCanSavePresentation(
const MaybeDiscarded<BrowsingContext>& aTopLevelContext,
Maybe<uint64_t> aDocumentChannelId,
CanSavePresentationResolver&& aResolve);
public: public:
static void DispatchBeforeUnloadToSubtree( static void DispatchBeforeUnloadToSubtree(
BrowsingContext* aStartingAt, BrowsingContext* aStartingAt,

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

@ -3880,9 +3880,9 @@ mozilla::ipc::IPCResult ContentParent::RecvCloneDocumentTreeInto(
return IPC_OK(); return IPC_OK();
} }
RemotenessChangeOptions options; target
options.mRemoteType = cp->GetRemoteType(); ->ChangeRemoteness(cp->GetRemoteType(), /* aLoadID = */ 0,
target->ChangeRemoteness(options, /* aPendingSwitchId = */ 0) /* aReplaceBC = */ false, /* aSpecificGroupId = */ 0)
->Then( ->Then(
GetMainThreadSerialEventTarget(), __func__, GetMainThreadSerialEventTarget(), __func__,
[source = RefPtr{source}](BrowserParent* aBp) { [source = RefPtr{source}](BrowserParent* aBp) {

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

@ -9,7 +9,6 @@ include protocol PBrowser;
include protocol PCompositorManager; include protocol PCompositorManager;
include protocol PContentPermissionRequest; include protocol PContentPermissionRequest;
include protocol PCycleCollectWithLogs; include protocol PCycleCollectWithLogs;
include protocol PDocumentChannel;
include protocol PExternalHelperApp; include protocol PExternalHelperApp;
include protocol PHandlerService; include protocol PHandlerService;
include protocol PFileDescriptorSet; include protocol PFileDescriptorSet;
@ -946,9 +945,6 @@ child:
async DispatchBeforeUnloadToSubtree(MaybeDiscardedBrowsingContext aStartingAt) async DispatchBeforeUnloadToSubtree(MaybeDiscardedBrowsingContext aStartingAt)
returns (PermitUnloadResult result); returns (PermitUnloadResult result);
async CanSavePresentation(MaybeDiscardedBrowsingContext aTopLevelContext,
uint64_t? aDocumentChannelId) returns (bool success);
// Update the cached list of codec supported in the given process. // Update the cached list of codec supported in the given process.
async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported); async UpdateMediaCodecsSupported(RemoteDecodeIn aLocation, MediaCodecsSupported aSupported);

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

@ -48,10 +48,9 @@ void RecvPropagateBackgroundSessionStorageManager(
if (sManagers) { if (sManagers) {
if (RefPtr<BackgroundSessionStorageManager> mgr = if (RefPtr<BackgroundSessionStorageManager> mgr =
sManagers->Get(aCurrentTopContextId)) { sManagers->Get(aCurrentTopContextId)) {
// Because of bfcache, we may re-register aTargetTopContextId in // Assuming the target top browsing context should haven't been
// CanonicalBrowsingContext::ReplacedBy. // registered yet.
// XXXBFCache do we want to tweak this behavior and ensure this is MOZ_DIAGNOSTIC_ASSERT(!sManagers->Contains(aTargetTopContextId));
// called only once?
sManagers->InsertOrUpdate(aTargetTopContextId, std::move(mgr)); sManagers->InsertOrUpdate(aTargetTopContextId, std::move(mgr));
} }
} }

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

@ -9316,7 +9316,7 @@ static CallState FreezeSubDocument(Document& aDocument) {
return CallState::Continue; return CallState::Continue;
} }
void PresShell::Freeze(bool aIncludeSubDocuments) { void PresShell::Freeze() {
mUpdateApproximateFrameVisibilityEvent.Revoke(); mUpdateApproximateFrameVisibilityEvent.Revoke();
MaybeReleaseCapturingContent(); MaybeReleaseCapturingContent();
@ -9327,7 +9327,7 @@ void PresShell::Freeze(bool aIncludeSubDocuments) {
mPaintingSuppressed = true; mPaintingSuppressed = true;
if (aIncludeSubDocuments && mDocument) { if (mDocument) {
mDocument->EnumerateSubDocuments(FreezeSubDocument); mDocument->EnumerateSubDocuments(FreezeSubDocument);
} }
@ -9370,14 +9370,14 @@ void PresShell::FireOrClearDelayedEvents(bool aFireEvents) {
} }
} }
void PresShell::Thaw(bool aIncludeSubDocuments) { void PresShell::Thaw() {
nsPresContext* presContext = GetPresContext(); nsPresContext* presContext = GetPresContext();
if (presContext && if (presContext &&
presContext->RefreshDriver()->GetPresContext() == presContext) { presContext->RefreshDriver()->GetPresContext() == presContext) {
presContext->RefreshDriver()->Thaw(); presContext->RefreshDriver()->Thaw();
} }
if (aIncludeSubDocuments && mDocument) { if (mDocument) {
mDocument->EnumerateSubDocuments([](Document& aSubDoc) { mDocument->EnumerateSubDocuments([](Document& aSubDoc) {
if (PresShell* presShell = aSubDoc.GetPresShell()) { if (PresShell* presShell = aSubDoc.GetPresShell()) {
presShell->Thaw(); presShell->Thaw();

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

@ -743,7 +743,7 @@ class PresShell final : public nsStubDocumentObserver,
* state. * state.
* XXX this should include image animations * XXX this should include image animations
*/ */
void Freeze(bool aIncludeSubDocuments = true); void Freeze();
bool IsFrozen() { return mFrozen; } bool IsFrozen() { return mFrozen; }
/** /**
@ -751,7 +751,7 @@ class PresShell final : public nsStubDocumentObserver,
* presentations of subdocuments, then do a full invalidate of the content * presentations of subdocuments, then do a full invalidate of the content
* area. * area.
*/ */
void Thaw(bool aIncludeSubDocuments = true); void Thaw();
void FireOrClearDelayedEvents(bool aFireEvents); void FireOrClearDelayedEvents(bool aFireEvents);

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

@ -3749,13 +3749,6 @@
mirror: once mirror: once
do_not_use_directly: true do_not_use_directly: true
# If session history is stored in the parent process, enable bfcache for it.
- name: fission.bfcacheInParent
type: bool
value: false
mirror: always
do_not_use_directly: true
# Allow renaming of process names to the origin on nightly # Allow renaming of process names to the origin on nightly
# Setting this pref creates a privacy leak, but helps greatly with # Setting this pref creates a privacy leak, but helps greatly with
# debugging # debugging

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

@ -11,11 +11,9 @@
#include "mozilla/net/HttpBaseChannel.h" #include "mozilla/net/HttpBaseChannel.h"
#include "mozilla/net/NeckoChild.h" #include "mozilla/net/NeckoChild.h"
#include "mozilla/ScopeExit.h" #include "mozilla/ScopeExit.h"
#include "mozilla/StaticPrefs_fission.h"
#include "nsHashPropertyBag.h" #include "nsHashPropertyBag.h"
#include "nsIHttpChannelInternal.h" #include "nsIHttpChannelInternal.h"
#include "nsIObjectLoadingContent.h" #include "nsIObjectLoadingContent.h"
#include "nsIXULRuntime.h"
#include "nsIWritablePropertyBag.h" #include "nsIWritablePropertyBag.h"
using namespace mozilla::dom; using namespace mozilla::dom;
@ -176,14 +174,7 @@ IPCResult DocumentChannelChild::RecvDisconnectChildListeners(
// notify them of the failure. If this is a process switch, then we can just // notify them of the failure. If this is a process switch, then we can just
// ignore it silently, and trust that the switch will shut down our docshell // ignore it silently, and trust that the switch will shut down our docshell
// and cancel us when it's ready. // and cancel us when it's ready.
// XXXBFCache This should be fixed in some better way. if (!aSwitchedProcess) {
bool disconnectChildListeners = !aSwitchedProcess;
if (!disconnectChildListeners && mozilla::BFCacheInParent()) {
nsDocShell* shell = GetDocShell();
disconnectChildListeners = shell && shell->GetBrowsingContext() &&
shell->GetBrowsingContext()->IsTop();
}
if (disconnectChildListeners) {
DisconnectChildListeners(aStatus, aLoadGroupStatus); DisconnectChildListeners(aStatus, aLoadGroupStatus);
} }
return IPC_OK(); return IPC_OK();

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

@ -39,8 +39,7 @@ bool DocumentChannelParent::Init(dom::CanonicalBrowsingContext* aContext,
RefPtr<DocumentLoadListener::OpenPromise> promise; RefPtr<DocumentLoadListener::OpenPromise> promise;
if (loadState->GetChannelInitialized()) { if (loadState->GetChannelInitialized()) {
promise = DocumentLoadListener::ClaimParentLoad( promise = DocumentLoadListener::ClaimParentLoad(
getter_AddRefs(mDocumentLoadListener), loadState->GetLoadIdentifier(), getter_AddRefs(mDocumentLoadListener), loadState->GetLoadIdentifier());
Some(aArgs.channelId()));
} }
if (!promise) { if (!promise) {
bool isDocumentLoad = bool isDocumentLoad =

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

@ -46,7 +46,6 @@
#include "nsQueryObject.h" #include "nsQueryObject.h"
#include "nsRedirectHistoryEntry.h" #include "nsRedirectHistoryEntry.h"
#include "nsSandboxFlags.h" #include "nsSandboxFlags.h"
#include "nsSHistory.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "nsURILoader.h" #include "nsURILoader.h"
#include "nsWebNavigationInfo.h" #include "nsWebNavigationInfo.h"
@ -65,8 +64,6 @@
mozilla::LazyLogModule gDocumentChannelLog("DocumentChannel"); mozilla::LazyLogModule gDocumentChannelLog("DocumentChannel");
#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt) #define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
extern mozilla::LazyLogModule gSHIPBFCacheLog;
using namespace mozilla::dom; using namespace mozilla::dom;
namespace mozilla { namespace mozilla {
@ -523,7 +520,6 @@ auto DocumentLoadListener::Open(nsDocShellLoadState* aLoadState,
if (identChannel && aChannelId) { if (identChannel && aChannelId) {
Unused << identChannel->SetChannelId(*aChannelId); Unused << identChannel->SetChannelId(*aChannelId);
} }
mDocumentChannelId = aChannelId;
RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel); RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(mChannel);
if (httpChannelImpl) { if (httpChannelImpl) {
@ -908,8 +904,7 @@ void DocumentLoadListener::CleanupParentLoadAttempt(uint64_t aLoadIdent) {
} }
auto DocumentLoadListener::ClaimParentLoad(DocumentLoadListener** aListener, auto DocumentLoadListener::ClaimParentLoad(DocumentLoadListener** aListener,
uint64_t aLoadIdent, uint64_t aLoadIdent)
Maybe<uint64_t> aChannelId)
-> RefPtr<OpenPromise> { -> RefPtr<OpenPromise> {
nsCOMPtr<nsIRedirectChannelRegistrar> registrar = nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
RedirectChannelRegistrar::GetOrCreate(); RedirectChannelRegistrar::GetOrCreate();
@ -925,8 +920,6 @@ auto DocumentLoadListener::ClaimParentLoad(DocumentLoadListener** aListener,
return nullptr; return nullptr;
} }
loadListener->mDocumentChannelId = aChannelId;
MOZ_DIAGNOSTIC_ASSERT(loadListener->mOpenPromise); MOZ_DIAGNOSTIC_ASSERT(loadListener->mOpenPromise);
loadListener.forget(aListener); loadListener.forget(aListener);
@ -1497,7 +1490,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
// Determine what type of content process this load should finish in. // Determine what type of content process this load should finish in.
nsAutoCString preferredRemoteType(currentRemoteType); nsAutoCString preferredRemoteType(currentRemoteType);
RemotenessChangeOptions options; bool replaceBrowsingContext = false;
uint64_t specificGroupId = 0;
// If we're in a preloaded browser, force browsing context replacement to // If we're in a preloaded browser, force browsing context replacement to
// ensure the current process is re-selected. // ensure the current process is re-selected.
@ -1512,7 +1506,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
if (NS_SUCCEEDED(mChannel->GetOriginalURI(getter_AddRefs(originalURI))) && if (NS_SUCCEEDED(mChannel->GetOriginalURI(getter_AddRefs(originalURI))) &&
!originalURI->GetSpecOrDefault().EqualsLiteral("about:newtab")) { !originalURI->GetSpecOrDefault().EqualsLiteral("about:newtab")) {
LOG(("Process Switch: leaving preloaded browser")); LOG(("Process Switch: leaving preloaded browser"));
options.mReplaceBrowsingContext = true; replaceBrowsingContext = true;
browserElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::preloadedState, browserElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::preloadedState,
true); true);
} }
@ -1523,7 +1517,7 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
// Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers. // Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers.
{ {
bool isCOOPSwitch = HasCrossOriginOpenerPolicyMismatch(); bool isCOOPSwitch = HasCrossOriginOpenerPolicyMismatch();
options.mReplaceBrowsingContext |= isCOOPSwitch; replaceBrowsingContext |= isCOOPSwitch;
// Determine our COOP status, which will be used to determine our preferred // Determine our COOP status, which will be used to determine our preferred
// remote type. // remote type.
@ -1559,10 +1553,10 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
if (!parentWindow && browsingContext->Group()->Toplevels().Length() == 1) { if (!parentWindow && browsingContext->Group()->Toplevels().Length() == 1) {
if (IsLargeAllocationLoad(browsingContext, mChannel)) { if (IsLargeAllocationLoad(browsingContext, mChannel)) {
preferredRemoteType = LARGE_ALLOCATION_REMOTE_TYPE; preferredRemoteType = LARGE_ALLOCATION_REMOTE_TYPE;
options.mReplaceBrowsingContext = true; replaceBrowsingContext = true;
} else if (preferredRemoteType == LARGE_ALLOCATION_REMOTE_TYPE) { } else if (preferredRemoteType == LARGE_ALLOCATION_REMOTE_TYPE) {
preferredRemoteType = DEFAULT_REMOTE_TYPE; preferredRemoteType = DEFAULT_REMOTE_TYPE;
options.mReplaceBrowsingContext = true; replaceBrowsingContext = true;
} }
} }
@ -1580,8 +1574,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
if (browsingContext->Group()->Id() != if (browsingContext->Group()->Id() !=
addonPolicy->GetBrowsingContextGroupId()) { addonPolicy->GetBrowsingContextGroupId()) {
options.mReplaceBrowsingContext = true; replaceBrowsingContext = true;
options.mSpecificGroupId = addonPolicy->GetBrowsingContextGroupId(); specificGroupId = addonPolicy->GetBrowsingContextGroupId();
} }
} else { } else {
// As a temporary measure, extension iframes must be loaded within the // As a temporary measure, extension iframes must be loaded within the
@ -1609,10 +1603,11 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
currentPrincipal = wgp->DocumentPrincipal(); currentPrincipal = wgp->DocumentPrincipal();
} }
nsAutoCString remoteType;
rv = e10sUtils->GetRemoteTypeForPrincipal( rv = e10sUtils->GetRemoteTypeForPrincipal(
resultPrincipal, mChannelCreationURI, browsingContext->UseRemoteTabs(), resultPrincipal, mChannelCreationURI, browsingContext->UseRemoteTabs(),
browsingContext->UseRemoteSubframes(), preferredRemoteType, browsingContext->UseRemoteSubframes(), preferredRemoteType,
currentPrincipal, parentWindow, options.mRemoteType); currentPrincipal, parentWindow, remoteType);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
LOG(("Process Switch Abort: getRemoteTypeForPrincipal threw an exception")); LOG(("Process Switch Abort: getRemoteTypeForPrincipal threw an exception"));
return false; return false;
@ -1621,81 +1616,32 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
// If the final decision is to switch from an 'extension' remote type to any // If the final decision is to switch from an 'extension' remote type to any
// other remote type, ensure the browsing context is replaced so that we leave // other remote type, ensure the browsing context is replaced so that we leave
// the extension-specific BrowsingContextGroup. // the extension-specific BrowsingContextGroup.
if (!parentWindow && currentRemoteType != options.mRemoteType && if (!parentWindow && currentRemoteType != remoteType &&
currentRemoteType == EXTENSION_REMOTE_TYPE) { currentRemoteType == EXTENSION_REMOTE_TYPE) {
options.mReplaceBrowsingContext = true; replaceBrowsingContext = true;
}
if (mozilla::BFCacheInParent() && nsSHistory::GetMaxTotalViewers() > 0 &&
!parentWindow && !browsingContext->HadOriginalOpener() &&
browsingContext->Group()->Toplevels().Length() == 1 &&
!options.mRemoteType.IsEmpty() &&
browsingContext->GetHasLoadedNonInitialDocument() &&
mLoadStateLoadType != LOAD_ERROR_PAGE) {
options.mReplaceBrowsingContext = true;
options.mTryUseBFCache = true;
} }
LOG(("GetRemoteTypeForPrincipal -> current:%s remoteType:%s", LOG(("GetRemoteTypeForPrincipal -> current:%s remoteType:%s",
currentRemoteType.get(), options.mRemoteType.get())); currentRemoteType.get(), remoteType.get()));
// Check if a process switch is needed. // Check if a process switch is needed.
if (currentRemoteType == options.mRemoteType && if (currentRemoteType == remoteType && !replaceBrowsingContext) {
!options.mReplaceBrowsingContext) { LOG(("Process Switch Abort: type (%s) is compatible", remoteType.get()));
LOG(("Process Switch Abort: type (%s) is compatible",
options.mRemoteType.get()));
return false; return false;
} }
if (NS_WARN_IF(parentWindow && options.mRemoteType.IsEmpty())) { if (NS_WARN_IF(parentWindow && remoteType.IsEmpty())) {
LOG(("Process Switch Abort: non-remote target process for subframe")); LOG(("Process Switch Abort: non-remote target process for subframe"));
return false; return false;
} }
*aWillSwitchToRemote = !options.mRemoteType.IsEmpty(); *aWillSwitchToRemote = !remoteType.IsEmpty();
// If we're doing a document load, we can immediately perform a process // If we're doing a document load, we can immediately perform a process
// switch. // switch.
if (mIsDocumentLoad) { if (mIsDocumentLoad) {
if (options.mTryUseBFCache && wgp) { TriggerProcessSwitch(browsingContext, remoteType, replaceBrowsingContext,
if (RefPtr<BrowserParent> browserParent = wgp->GetBrowserParent()) { specificGroupId);
nsTArray<RefPtr<PContentParent::CanSavePresentationPromise>>
canSavePromises;
browsingContext->Group()->EachParent([&](ContentParent* aParent) {
RefPtr<PContentParent::CanSavePresentationPromise> canSave =
aParent->SendCanSavePresentation(browsingContext,
mDocumentChannelId);
canSavePromises.AppendElement(canSave);
});
PContentParent::CanSavePresentationPromise::All(
GetCurrentSerialEventTarget(), canSavePromises)
->Then(
GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}, browsingContext,
options](const nsTArray<bool> aCanSaves) mutable {
bool canSave = !aCanSaves.Contains(false);
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("DocumentLoadListener::MaybeTriggerProcessSwitch "
"saving presentation=%i",
canSave));
options.mTryUseBFCache = canSave;
self->TriggerProcessSwitch(browsingContext, options);
},
[self = RefPtr{this}, browsingContext,
options](ipc::ResponseRejectReason) mutable {
MOZ_LOG(gSHIPBFCacheLog, LogLevel::Debug,
("DocumentLoadListener::MaybeTriggerProcessSwitch "
"error in trying to save presentation"));
options.mTryUseBFCache = false;
self->TriggerProcessSwitch(browsingContext, options);
});
return true;
}
}
options.mTryUseBFCache = false;
TriggerProcessSwitch(browsingContext, options);
return true; return true;
} }
@ -1714,8 +1660,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
mObjectUpgradeHandler->UpgradeObjectLoad()->Then( mObjectUpgradeHandler->UpgradeObjectLoad()->Then(
GetMainThreadSerialEventTarget(), __func__, GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}, options, [self = RefPtr{this}, remoteType, replaceBrowsingContext, specificGroupId,
wgp](const RefPtr<CanonicalBrowsingContext>& aBrowsingContext) mutable { wgp](const RefPtr<CanonicalBrowsingContext>& aBrowsingContext) {
if (aBrowsingContext->IsDiscarded() || if (aBrowsingContext->IsDiscarded() ||
wgp != aBrowsingContext->GetParentWindowContext()) { wgp != aBrowsingContext->GetParentWindowContext()) {
LOG( LOG(
@ -1726,7 +1672,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
} }
LOG(("Process Switch: Upgraded Object to Document Load")); LOG(("Process Switch: Upgraded Object to Document Load"));
self->TriggerProcessSwitch(aBrowsingContext, options); self->TriggerProcessSwitch(aBrowsingContext, remoteType,
replaceBrowsingContext, specificGroupId);
}, },
[self = RefPtr{this}](nsresult aStatusCode) { [self = RefPtr{this}](nsresult aStatusCode) {
MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error"); MOZ_ASSERT(NS_FAILED(aStatusCode), "Status should be error");
@ -1736,8 +1683,8 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch(
} }
void DocumentLoadListener::TriggerProcessSwitch( void DocumentLoadListener::TriggerProcessSwitch(
CanonicalBrowsingContext* aContext, CanonicalBrowsingContext* aContext, const nsCString& aRemoteType,
const RemotenessChangeOptions& aOptions) { bool aReplaceBrowsingContext, uint64_t aSpecificGroupId) {
nsAutoCString currentRemoteType(NOT_REMOTE_TYPE); nsAutoCString currentRemoteType(NOT_REMOTE_TYPE);
if (RefPtr<ContentParent> contentParent = aContext->GetContentParent()) { if (RefPtr<ContentParent> contentParent = aContext->GetContentParent()) {
currentRemoteType = contentParent->GetRemoteType(); currentRemoteType = contentParent->GetRemoteType();
@ -1745,7 +1692,7 @@ void DocumentLoadListener::TriggerProcessSwitch(
MOZ_ASSERT_IF(currentRemoteType.IsEmpty(), !OtherPid()); MOZ_ASSERT_IF(currentRemoteType.IsEmpty(), !OtherPid());
LOG(("Process Switch: Changing Remoteness from '%s' to '%s'", LOG(("Process Switch: Changing Remoteness from '%s' to '%s'",
currentRemoteType.get(), aOptions.mRemoteType.get())); currentRemoteType.get(), aRemoteType.get()));
// We're now committing to a process switch, so we can disconnect from // We're now committing to a process switch, so we can disconnect from
// the listeners in the old process. // the listeners in the old process.
@ -1763,7 +1710,9 @@ void DocumentLoadListener::TriggerProcessSwitch(
DisconnectListeners(NS_BINDING_ABORTED, NS_BINDING_ABORTED, true); DisconnectListeners(NS_BINDING_ABORTED, NS_BINDING_ABORTED, true);
LOG(("Process Switch: Calling ChangeRemoteness")); LOG(("Process Switch: Calling ChangeRemoteness"));
aContext->ChangeRemoteness(aOptions, mLoadIdentifier) aContext
->ChangeRemoteness(aRemoteType, mLoadIdentifier, aReplaceBrowsingContext,
aSpecificGroupId)
->Then( ->Then(
GetMainThreadSerialEventTarget(), __func__, GetMainThreadSerialEventTarget(), __func__,
[self = RefPtr{this}](BrowserParent* aBrowserParent) { [self = RefPtr{this}](BrowserParent* aBrowserParent) {

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

@ -36,8 +36,7 @@
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class CanonicalBrowsingContext; class CanonicalBrowsingContext;
struct RemotenessChangeOptions; }
} // namespace dom
namespace net { namespace net {
using ChildEndpointPromise = using ChildEndpointPromise =
MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>; MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>;
@ -195,8 +194,7 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// Looks up aLoadIdent to find the associated, cleans up the registration // Looks up aLoadIdent to find the associated, cleans up the registration
static RefPtr<OpenPromise> ClaimParentLoad(DocumentLoadListener** aListener, static RefPtr<OpenPromise> ClaimParentLoad(DocumentLoadListener** aListener,
uint64_t aLoadIdent, uint64_t aLoadIdent);
Maybe<uint64_t> aChannelId);
// Called by the DocumentChannelParent if actor got destroyed or the parent // Called by the DocumentChannelParent if actor got destroyed or the parent
// channel got deleted. // channel got deleted.
@ -322,7 +320,9 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
// and that the new remote type will be something other than NOT_REMOTE // and that the new remote type will be something other than NOT_REMOTE
bool MaybeTriggerProcessSwitch(bool* aWillSwitchToRemote); bool MaybeTriggerProcessSwitch(bool* aWillSwitchToRemote);
void TriggerProcessSwitch(dom::CanonicalBrowsingContext* aContext, void TriggerProcessSwitch(dom::CanonicalBrowsingContext* aContext,
const dom::RemotenessChangeOptions& aOptions); const nsCString& aRemoteType,
bool aReplaceBrowsingContext,
uint64_t aSpecificGroupId);
// A helper for TriggerRedirectToRealChannel that abstracts over // A helper for TriggerRedirectToRealChannel that abstracts over
// the same-process and cross-process switch cases and returns // the same-process and cross-process switch cases and returns
@ -465,8 +465,6 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
nsCOMPtr<nsIChannel> mChannel; nsCOMPtr<nsIChannel> mChannel;
Maybe<uint64_t> mDocumentChannelId;
// An instance of ParentChannelListener that we use as a listener // An instance of ParentChannelListener that we use as a listener
// between mChannel (and any future redirected mChannels) and us. // between mChannel (and any future redirected mChannels) and us.
// This handles service worker interception, and retargetting // This handles service worker interception, and retargetting

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

@ -1245,9 +1245,6 @@ nsresult nsWindowWatcher::OpenWindowInternal(
} }
if (uriToLoad && aNavigate) { if (uriToLoad && aNavigate) {
// XXXBFCache Per spec this should effectively use
// LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL when noopener is passed to
// window.open(). Bug 1694993.
loadState->SetLoadFlags( loadState->SetLoadFlags(
windowIsNew windowIsNew
? static_cast<uint32_t>(nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD) ? static_cast<uint32_t>(nsIWebNavigation::LOAD_FLAGS_FIRST_LOAD)

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

@ -754,11 +754,6 @@ bool SessionHistoryInParent() {
fission_sessionHistoryInParent_AtStartup_DoNotUseDirectly(); fission_sessionHistoryInParent_AtStartup_DoNotUseDirectly();
} }
bool BFCacheInParent() {
return SessionHistoryInParent() &&
StaticPrefs::fission_bfcacheInParent_DoNotUseDirectly();
}
} // namespace mozilla } // namespace mozilla
/** /**

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

@ -25,10 +25,6 @@ bool FissionAutostart();
// Returns true if fission.sessionHistoryInParent or FissionAutostart() is true. // Returns true if fission.sessionHistoryInParent or FissionAutostart() is true.
bool SessionHistoryInParent(); bool SessionHistoryInParent();
// Returns true if SessionHistoryInParent() returns true and
// fission.bfcacheInParent is true.
bool BFCacheInParent();
} }
%} %}