Bug 1649131 - Store some data in a pseudo shared state in the child process. r=smaug

The entries in the parent process stores some data in a shared state for some of
the entries that share a document. We also need to store some of this data in
the info objects in the child process, but it doesn't make sense to have it be
shared: the data shouldn't be mutated in the child process, and we probably only
have one of the info objects anyway. This adds a structure that holds the shared
data for an info object in the child process, but without actually sharing it.
As we use info objects in both parent and child, we hold a void pointer that's a
strong reference to a shared state in the parent process, and an owning pointer
to the pseudo-shared state in the child process.

Differential Revision: https://phabricator.services.mozilla.com/D87038
This commit is contained in:
Peter Van der Beken 2020-08-23 17:36:10 +00:00
Родитель 1caf077d0b
Коммит e08ef28207
5 изменённых файлов: 260 добавлений и 120 удалений

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

@ -23,15 +23,16 @@ SessionHistoryInfo::SessionHistoryInfo(nsDocShellLoadState* aLoadState,
mReferrerInfo(aLoadState->GetReferrerInfo()),
mPostData(aLoadState->PostDataStream()),
mLoadType(aLoadState->LoadType()),
mScrollPositionX(0),
mScrollPositionY(0),
mSrcdocData(aLoadState->SrcdocData()),
mBaseURI(aLoadState->BaseURI()),
mLoadReplace(aLoadState->LoadReplace()),
mURIWasModified(false),
/* FIXME Should this be aLoadState->IsSrcdocLoad()? */
mIsSrcdocEntry(!aLoadState->SrcdocData().IsEmpty()),
mScrollRestorationIsManual(false) {
mSharedState(SharedState::Create(
aLoadState->TriggeringPrincipal(), aLoadState->PrincipalToInherit(),
aLoadState->PartitionedPrincipalToInherit(), aLoadState->Csp(),
/* FIXME Is this correct? */
aLoadState->TypeHint())) {
MaybeUpdateTitleFromURI();
bool isNoStore = false;
if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) {
@ -50,6 +51,79 @@ void SessionHistoryInfo::MaybeUpdateTitleFromURI() {
}
}
nsILayoutHistoryState* SessionHistoryInfo::GetLayoutHistoryState() {
return mSharedState.Get()->mLayoutHistoryState;
}
void SessionHistoryInfo::SetLayoutHistoryState(nsILayoutHistoryState* aState) {
mSharedState.Get()->mLayoutHistoryState = aState;
}
/* static */
SessionHistoryInfo::SharedState SessionHistoryInfo::SharedState::Create(
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit,
nsIPrincipal* aPartitionedPrincipalToInherit,
nsIContentSecurityPolicy* aCsp, const nsACString& aContentType) {
if (XRE_IsParentProcess()) {
return SharedState(new SHEntrySharedParentState(
aTriggeringPrincipal, aPrincipalToInherit,
aPartitionedPrincipalToInherit, aCsp, aContentType));
}
// FIXME Pass the correct ID!!!
return SharedState(MakeUnique<SHEntrySharedState>(
0, aTriggeringPrincipal, aPrincipalToInherit,
aPartitionedPrincipalToInherit, aCsp, aContentType));
}
SessionHistoryInfo::SharedState::SharedState() {
if (XRE_IsParentProcess()) {
new (&mParent)
RefPtr<SHEntrySharedParentState>(new SHEntrySharedParentState());
} else {
new (&mChild)
UniquePtr<SHEntrySharedState>(MakeUnique<SHEntrySharedState>());
}
}
SessionHistoryInfo::SharedState::SharedState(
const SessionHistoryInfo::SharedState& aOther) {
if (XRE_IsParentProcess()) {
new (&mParent) RefPtr<SHEntrySharedParentState>(aOther.mParent);
} else {
new (&mChild) UniquePtr<SHEntrySharedState>(
MakeUnique<SHEntrySharedState>(*aOther.mChild));
}
}
SessionHistoryInfo::SharedState::~SharedState() {
if (XRE_IsParentProcess()) {
mParent
.RefPtr<SHEntrySharedParentState>::~RefPtr<SHEntrySharedParentState>();
} else {
mChild.UniquePtr<SHEntrySharedState>::~UniquePtr<SHEntrySharedState>();
}
}
SessionHistoryInfo::SharedState& SessionHistoryInfo::SharedState::operator=(
const SessionHistoryInfo::SharedState& aOther) {
if (this != &aOther) {
if (XRE_IsParentProcess()) {
mParent = aOther.mParent;
} else {
mChild = MakeUnique<SHEntrySharedState>(*aOther.mChild);
}
}
return *this;
}
SHEntrySharedState* SessionHistoryInfo::SharedState::Get() const {
if (XRE_IsParentProcess()) {
return mParent;
}
return mChild.get();
}
static uint64_t gLoadingSessionHistoryInfoLoadId = 0;
nsDataHashtable<nsUint64HashKey, SessionHistoryEntry*>*
@ -86,22 +160,11 @@ void SessionHistoryEntry::RemoveLoadId(uint64_t aLoadId) {
}
SessionHistoryEntry::SessionHistoryEntry()
: mInfo(new SessionHistoryInfo()),
mSharedInfo(new SHEntrySharedParentState()),
mID(++gEntryID) {}
: mInfo(new SessionHistoryInfo()), mID(++gEntryID) {}
SessionHistoryEntry::SessionHistoryEntry(nsDocShellLoadState* aLoadState,
nsIChannel* aChannel)
: mInfo(new SessionHistoryInfo(aLoadState, aChannel)),
mSharedInfo(new SHEntrySharedParentState()),
mID(++gEntryID) {
mSharedInfo->mTriggeringPrincipal = aLoadState->TriggeringPrincipal();
mSharedInfo->mPrincipalToInherit = aLoadState->PrincipalToInherit();
mSharedInfo->mPartitionedPrincipalToInherit =
aLoadState->PartitionedPrincipalToInherit();
mSharedInfo->mCsp = aLoadState->Csp();
// FIXME Set remaining shared fields!
}
: mInfo(new SessionHistoryInfo(aLoadState, aChannel)), mID(++gEntryID) {}
SessionHistoryEntry::~SessionHistoryEntry() {
if (sLoadIdToEntry) {
@ -181,13 +244,13 @@ SessionHistoryEntry::SetTitle(const nsAString& aTitle) {
NS_IMETHODIMP
SessionHistoryEntry::GetIsSubFrame(bool* aIsSubFrame) {
*aIsSubFrame = mSharedInfo->mIsFrameNavigation;
*aIsSubFrame = SharedInfo()->mIsFrameNavigation;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetIsSubFrame(bool aIsSubFrame) {
mSharedInfo->mIsFrameNavigation = aIsSubFrame;
SharedInfo()->mIsFrameNavigation = aIsSubFrame;
return NS_OK;
}
@ -232,13 +295,13 @@ SessionHistoryEntry::SetContentViewer(nsIContentViewer* aContentViewer) {
NS_IMETHODIMP
SessionHistoryEntry::GetSticky(bool* aSticky) {
*aSticky = mSharedInfo->mSticky;
*aSticky = SharedInfo()->mSticky;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetSticky(bool aSticky) {
mSharedInfo->mSticky = aSticky;
SharedInfo()->mSticky = aSticky;
return NS_OK;
}
@ -283,7 +346,7 @@ NS_IMETHODIMP
SessionHistoryEntry::GetLayoutHistoryState(
nsILayoutHistoryState** aLayoutHistoryState) {
nsCOMPtr<nsILayoutHistoryState> layoutHistoryState =
mSharedInfo->mLayoutHistoryState;
SharedInfo()->mLayoutHistoryState;
layoutHistoryState.forget(aLayoutHistoryState);
return NS_OK;
}
@ -291,7 +354,7 @@ SessionHistoryEntry::GetLayoutHistoryState(
NS_IMETHODIMP
SessionHistoryEntry::SetLayoutHistoryState(
nsILayoutHistoryState* aLayoutHistoryState) {
mSharedInfo->mLayoutHistoryState = aLayoutHistoryState;
SharedInfo()->mLayoutHistoryState = aLayoutHistoryState;
return NS_OK;
}
@ -334,37 +397,37 @@ SessionHistoryEntry::SetID(uint32_t aID) {
NS_IMETHODIMP
SessionHistoryEntry::GetCacheKey(uint32_t* aCacheKey) {
*aCacheKey = mSharedInfo->mCacheKey;
*aCacheKey = SharedInfo()->mCacheKey;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetCacheKey(uint32_t aCacheKey) {
mSharedInfo->mCacheKey = aCacheKey;
SharedInfo()->mCacheKey = aCacheKey;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::GetSaveLayoutStateFlag(bool* aSaveLayoutStateFlag) {
*aSaveLayoutStateFlag = mSharedInfo->mSaveLayoutState;
*aSaveLayoutStateFlag = SharedInfo()->mSaveLayoutState;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetSaveLayoutStateFlag(bool aSaveLayoutStateFlag) {
mSharedInfo->mSaveLayoutState = aSaveLayoutStateFlag;
SharedInfo()->mSaveLayoutState = aSaveLayoutStateFlag;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::GetContentType(nsACString& aContentType) {
aContentType = mSharedInfo->mContentType;
aContentType = SharedInfo()->mContentType;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetContentType(const nsACString& aContentType) {
mSharedInfo->mContentType = aContentType;
SharedInfo()->mContentType = aContentType;
return NS_OK;
}
@ -384,7 +447,7 @@ NS_IMETHODIMP
SessionHistoryEntry::GetTriggeringPrincipal(
nsIPrincipal** aTriggeringPrincipal) {
nsCOMPtr<nsIPrincipal> triggeringPrincipal =
mSharedInfo->mTriggeringPrincipal;
SharedInfo()->mTriggeringPrincipal;
triggeringPrincipal.forget(aTriggeringPrincipal);
return NS_OK;
}
@ -392,20 +455,20 @@ SessionHistoryEntry::GetTriggeringPrincipal(
NS_IMETHODIMP
SessionHistoryEntry::SetTriggeringPrincipal(
nsIPrincipal* aTriggeringPrincipal) {
mSharedInfo->mTriggeringPrincipal = aTriggeringPrincipal;
SharedInfo()->mTriggeringPrincipal = aTriggeringPrincipal;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) {
nsCOMPtr<nsIPrincipal> principalToInherit = mSharedInfo->mPrincipalToInherit;
nsCOMPtr<nsIPrincipal> principalToInherit = SharedInfo()->mPrincipalToInherit;
principalToInherit.forget(aPrincipalToInherit);
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) {
mSharedInfo->mPrincipalToInherit = aPrincipalToInherit;
SharedInfo()->mPrincipalToInherit = aPrincipalToInherit;
return NS_OK;
}
@ -413,7 +476,7 @@ NS_IMETHODIMP
SessionHistoryEntry::GetPartitionedPrincipalToInherit(
nsIPrincipal** aPartitionedPrincipalToInherit) {
nsCOMPtr<nsIPrincipal> partitionedPrincipalToInherit =
mSharedInfo->mPartitionedPrincipalToInherit;
SharedInfo()->mPartitionedPrincipalToInherit;
partitionedPrincipalToInherit.forget(aPartitionedPrincipalToInherit);
return NS_OK;
}
@ -421,20 +484,20 @@ SessionHistoryEntry::GetPartitionedPrincipalToInherit(
NS_IMETHODIMP
SessionHistoryEntry::SetPartitionedPrincipalToInherit(
nsIPrincipal* aPartitionedPrincipalToInherit) {
mSharedInfo->mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit;
SharedInfo()->mPartitionedPrincipalToInherit = aPartitionedPrincipalToInherit;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::GetCsp(nsIContentSecurityPolicy** aCsp) {
nsCOMPtr<nsIContentSecurityPolicy> csp = mSharedInfo->mCsp;
nsCOMPtr<nsIContentSecurityPolicy> csp = SharedInfo()->mCsp;
csp.forget(aCsp);
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetCsp(nsIContentSecurityPolicy* aCsp) {
mSharedInfo->mCsp = aCsp;
SharedInfo()->mCsp = aCsp;
return NS_OK;
}
@ -452,7 +515,7 @@ SessionHistoryEntry::SetStateData(nsIStructuredCloneContainer* aStateData) {
}
const nsID& SessionHistoryEntry::DocshellID() const {
return mSharedInfo->mDocShellID;
return SharedInfo()->mDocShellID;
}
NS_IMETHODIMP
@ -463,7 +526,7 @@ SessionHistoryEntry::GetDocshellID(nsID& aDocshellID) {
NS_IMETHODIMP
SessionHistoryEntry::SetDocshellID(const nsID& aDocshellID) {
mSharedInfo->mDocShellID = aDocshellID;
SharedInfo()->mDocShellID = aDocshellID;
return NS_OK;
}
@ -521,7 +584,7 @@ SessionHistoryEntry::GetLoadedInThisProcess(bool* aLoadedInThisProcess) {
NS_IMETHODIMP
SessionHistoryEntry::GetShistory(nsISHistory** aShistory) {
nsCOMPtr<nsISHistory> sHistory = do_QueryReferent(mSharedInfo->mSHistory);
nsCOMPtr<nsISHistory> sHistory = do_QueryReferent(SharedInfo()->mSHistory);
sHistory.forget(aShistory);
return NS_OK;
}
@ -530,20 +593,20 @@ NS_IMETHODIMP
SessionHistoryEntry::SetShistory(nsISHistory* aShistory) {
nsWeakPtr shistory = do_GetWeakReference(aShistory);
// mSHistory can not be changed once it's set
MOZ_ASSERT(!mSharedInfo->mSHistory || (mSharedInfo->mSHistory == shistory));
mSharedInfo->mSHistory = shistory;
MOZ_ASSERT(!SharedInfo()->mSHistory || (SharedInfo()->mSHistory == shistory));
SharedInfo()->mSHistory = shistory;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::GetLastTouched(uint32_t* aLastTouched) {
*aLastTouched = mSharedInfo->mLastTouched;
*aLastTouched = SharedInfo()->mLastTouched;
return NS_OK;
}
NS_IMETHODIMP
SessionHistoryEntry::SetLastTouched(uint32_t aLastTouched) {
mSharedInfo->mLastTouched = aLastTouched;
SharedInfo()->mLastTouched = aLastTouched;
return NS_OK;
}
@ -581,12 +644,12 @@ SessionHistoryEntry::SetScrollPosition(int32_t aX, int32_t aY) {
NS_IMETHODIMP_(void)
SessionHistoryEntry::GetViewerBounds(nsIntRect& bounds) {
bounds = mSharedInfo->mViewerBounds;
bounds = SharedInfo()->mViewerBounds;
}
NS_IMETHODIMP_(void)
SessionHistoryEntry::SetViewerBounds(const nsIntRect& bounds) {
mSharedInfo->mViewerBounds = bounds;
SharedInfo()->mViewerBounds = bounds;
}
NS_IMETHODIMP_(void)
@ -614,7 +677,7 @@ SessionHistoryEntry::SyncPresentationState() {
NS_IMETHODIMP
SessionHistoryEntry::InitLayoutHistoryState(
nsILayoutHistoryState** aLayoutHistoryState) {
if (!mSharedInfo->mLayoutHistoryState) {
if (!SharedInfo()->mLayoutHistoryState) {
nsCOMPtr<nsILayoutHistoryState> historyState;
historyState = NS_NewLayoutHistoryState();
SetLayoutHistoryState(historyState);
@ -662,7 +725,7 @@ SessionHistoryEntry::HasDetachedEditor() {
NS_IMETHODIMP_(bool)
SessionHistoryEntry::IsDynamicallyAdded() {
return mSharedInfo->mDynamicallyCreated;
return SharedInfo()->mDynamicallyCreated;
}
NS_IMETHODIMP
@ -910,12 +973,12 @@ SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) {
loadState->SetPostDataStream(mInfo->mPostData);
loadState->SetReferrerInfo(mInfo->mReferrerInfo);
loadState->SetTypeHint(mSharedInfo->mContentType);
loadState->SetTriggeringPrincipal(mSharedInfo->mTriggeringPrincipal);
loadState->SetPrincipalToInherit(mSharedInfo->mPrincipalToInherit);
loadState->SetTypeHint(SharedInfo()->mContentType);
loadState->SetTriggeringPrincipal(SharedInfo()->mTriggeringPrincipal);
loadState->SetPrincipalToInherit(SharedInfo()->mPrincipalToInherit);
loadState->SetPartitionedPrincipalToInherit(
mSharedInfo->mPartitionedPrincipalToInherit);
loadState->SetCsp(mSharedInfo->mCsp);
SharedInfo()->mPartitionedPrincipalToInherit);
loadState->SetCsp(SharedInfo()->mCsp);
// Do not inherit principal from document (security-critical!);
uint32_t flags = nsDocShell::InternalLoad::INTERNAL_LOAD_FLAGS_NONE;
@ -946,7 +1009,7 @@ SessionHistoryEntry::CreateLoadInfo(nsDocShellLoadState** aLoadState) {
NS_IMETHODIMP
SessionHistoryEntry::GetBfcacheID(uint64_t* aBfcacheID) {
*aBfcacheID = mSharedInfo->mID;
*aBfcacheID = SharedInfo()->mId;
return NS_OK;
}
@ -957,15 +1020,8 @@ SessionHistoryEntry::SyncTreesForSubframeNavigation(
NS_WARNING("Need to implement this");
}
void SessionHistoryEntry::MaybeSynchronizeSharedStateToInfo(
nsISHEntry* aEntry) {
nsCOMPtr<SessionHistoryEntry> entry = do_QueryInterface(aEntry);
if (!entry) {
return;
}
entry->mInfo->mCacheKey = entry->mSharedInfo->mCacheKey;
// XXX Add other member variables which live in mSharedInfo.
SHEntrySharedParentState* SessionHistoryEntry::SharedInfo() const {
return static_cast<SHEntrySharedParentState*>(mInfo->mSharedState.Get());
}
} // namespace dom
@ -1003,12 +1059,20 @@ void IPDLParamTraits<dom::LoadingSessionHistoryInfo>::Write(
WriteIPDLParam(aMsg, aActor, stateData);
WriteIPDLParam(aMsg, aActor, info.mSrcdocData);
WriteIPDLParam(aMsg, aActor, info.mBaseURI);
WriteIPDLParam(aMsg, aActor, info.mLayoutHistoryState);
WriteIPDLParam(aMsg, aActor, info.mLoadReplace);
WriteIPDLParam(aMsg, aActor, info.mURIWasModified);
WriteIPDLParam(aMsg, aActor, info.mIsSrcdocEntry);
WriteIPDLParam(aMsg, aActor, info.mScrollRestorationIsManual);
WriteIPDLParam(aMsg, aActor, info.mPersist);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mId);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mTriggeringPrincipal);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mPrincipalToInherit);
WriteIPDLParam(aMsg, aActor,
info.mSharedState.Get()->mPartitionedPrincipalToInherit);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCsp);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mContentType);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mLayoutHistoryState);
WriteIPDLParam(aMsg, aActor, info.mSharedState.Get()->mCacheKey);
WriteIPDLParam(aMsg, aActor, aParam.mLoadId);
WriteIPDLParam(aMsg, aActor, aParam.mLoadIsFromSessionHistory);
WriteIPDLParam(aMsg, aActor, aParam.mRequestedIndex);
@ -1021,6 +1085,7 @@ bool IPDLParamTraits<dom::LoadingSessionHistoryInfo>::Read(
Maybe<dom::ClonedMessageData> stateData;
dom::SessionHistoryInfo& info = aResult->mInfo;
uint64_t sharedId;
if (!ReadIPDLParam(aMsg, aIter, aActor, &info.mURI) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mOriginalURI) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mResultPrincipalURI) ||
@ -1033,20 +1098,38 @@ bool IPDLParamTraits<dom::LoadingSessionHistoryInfo>::Read(
!ReadIPDLParam(aMsg, aIter, aActor, &stateData) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mSrcdocData) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mBaseURI) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mLayoutHistoryState) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mLoadReplace) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mURIWasModified) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mIsSrcdocEntry) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mScrollRestorationIsManual) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mPersist) ||
!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&aResult->mLoadIsFromSessionHistory) ||
!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) ||
!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSessionHistoryLength)) {
!ReadIPDLParam(aMsg, aIter, aActor, &sharedId)) {
aActor->FatalError("Error reading fields for SessionHistoryInfo");
return false;
}
// FIXME If we're in the parent we should probably look up the sharedstate
// by id and reuse it, and only create a new one when there is no
// existing sharedstate.
info.mSharedState.Get()->mId = sharedId;
if (!ReadIPDLParam(aMsg, aIter, aActor,
&info.mSharedState.Get()->mTriggeringPrincipal) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&info.mSharedState.Get()->mPrincipalToInherit) ||
!ReadIPDLParam(
aMsg, aIter, aActor,
&info.mSharedState.Get()->mPartitionedPrincipalToInherit) ||
!ReadIPDLParam(aMsg, aIter, aActor, &info.mSharedState.Get()->mCsp) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&info.mSharedState.Get()->mContentType) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&info.mSharedState.Get()->mLayoutHistoryState) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&info.mSharedState.Get()->mCacheKey)) {
aActor->FatalError("Error reading fields for SessionHistoryInfo");
return false;
}
if (stateData.isSome()) {
info.mStateData = new nsStructuredCloneContainer();
if (aActor->GetSide() == ChildSide) {
@ -1056,6 +1139,16 @@ bool IPDLParamTraits<dom::LoadingSessionHistoryInfo>::Read(
}
}
MOZ_ASSERT_IF(stateData.isNothing(), !info.mStateData);
if (!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mLoadId) ||
!ReadIPDLParam(aMsg, aIter, aActor,
&aResult->mLoadIsFromSessionHistory) ||
!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mRequestedIndex) ||
!ReadIPDLParam(aMsg, aIter, aActor, &aResult->mSessionHistoryLength)) {
aActor->FatalError("Error reading fields for LoadingSessionHistoryInfo");
return false;
}
return true;
}

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

@ -10,6 +10,7 @@
#include "mozilla/UniquePtr.h"
#include "nsILayoutHistoryState.h"
#include "nsISHEntry.h"
#include "nsSHEntryShared.h"
#include "nsStructuredCloneContainer.h"
#include "nsDataHashtable.h"
@ -32,6 +33,7 @@ class SHEntrySharedParentState;
class SessionHistoryInfo {
public:
SessionHistoryInfo() = default;
SessionHistoryInfo(const SessionHistoryInfo& aInfo) = default;
SessionHistoryInfo(nsDocShellLoadState* aLoadState, nsIChannel* aChannel);
bool operator==(const SessionHistoryInfo& aInfo) const {
@ -53,17 +55,12 @@ class SessionHistoryInfo {
mScrollRestorationIsManual = aIsManual;
}
void SetCacheKey(uint32_t aCacheKey) { mCacheKey = aCacheKey; }
nsIURI* GetURI() const { return mURI; }
bool GetURIWasModified() const { return mURIWasModified; }
nsILayoutHistoryState* GetLayoutHistoryState() { return mLayoutHistoryState; }
void SetLayoutHistoryState(nsILayoutHistoryState* aState) {
mLayoutHistoryState = aState;
}
nsILayoutHistoryState* GetLayoutHistoryState();
void SetLayoutHistoryState(nsILayoutHistoryState* aState);
private:
friend class SessionHistoryEntry;
@ -83,19 +80,42 @@ class SessionHistoryInfo {
RefPtr<nsStructuredCloneContainer> mStateData;
nsString mSrcdocData;
nsCOMPtr<nsIURI> mBaseURI;
// mLayoutHistoryState is used to serialize layout history state across
// IPC. In the parent process this is then synchronized to
// SHEntrySharedParentState::mLayoutHistoryState
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
// mCacheKey is handled similar way to mLayoutHistoryState.
uint32_t mCacheKey = 0;
bool mLoadReplace = false;
bool mURIWasModified = false;
bool mIsSrcdocEntry = false;
bool mScrollRestorationIsManual = false;
bool mPersist = false;
union SharedState {
SharedState();
explicit SharedState(const SharedState& aOther);
~SharedState();
SharedState& operator=(const SharedState& aOther);
SHEntrySharedState* Get() const;
static SharedState Create(nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aPrincipalToInherit,
nsIPrincipal* aPartitionedPrincipalToInherit,
nsIContentSecurityPolicy* aCsp,
const nsACString& aContentType);
private:
explicit SharedState(SHEntrySharedParentState* aParent)
: mParent(aParent) {}
explicit SharedState(UniquePtr<SHEntrySharedState>&& aChild)
: mChild(std::move(aChild)) {}
// In the parent process this holds a strong reference to the refcounted
// SHEntrySharedParentState. In the child processes this holds an owning
// pointer to a SHEntrySharedState.
RefPtr<SHEntrySharedParentState> mParent;
UniquePtr<SHEntrySharedState> mChild;
};
SharedState mSharedState;
};
struct LoadingSessionHistoryInfo {
@ -139,6 +159,8 @@ class SessionHistoryEntry : public nsISHEntry {
const SessionHistoryInfo& Info() const { return *mInfo; }
SHEntrySharedParentState* SharedInfo() const;
void AddChild(SessionHistoryEntry* aChild, int32_t aOffset,
bool aUseRemoteSubframes);
void RemoveChild(SessionHistoryEntry* aChild);
@ -152,8 +174,6 @@ class SessionHistoryEntry : public nsISHEntry {
static SessionHistoryEntry* GetByLoadId(uint64_t aLoadId);
static void RemoveLoadId(uint64_t aLoadId);
static void MaybeSynchronizeSharedStateToInfo(nsISHEntry* aEntry);
private:
friend struct LoadingSessionHistoryInfo;
virtual ~SessionHistoryEntry();
@ -161,7 +181,6 @@ class SessionHistoryEntry : public nsISHEntry {
const nsID& DocshellID() const;
UniquePtr<SessionHistoryInfo> mInfo;
RefPtr<SHEntrySharedParentState> mSharedInfo;
nsISHEntry* mParent = nullptr;
uint32_t mID;
nsTArray<RefPtr<SessionHistoryEntry>> mChildren;

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

@ -28,17 +28,13 @@ uint64_t gSHEntrySharedID = 0;
namespace mozilla {
namespace dom {
SHEntrySharedParentState::SHEntrySharedParentState()
: mDocShellID({0}),
mViewerBounds(0, 0, 0, 0),
mCacheKey(0),
mLastTouched(0),
mID(++gSHEntrySharedID),
mIsFrameNavigation(false),
mSticky(true),
mDynamicallyCreated(false),
mExpired(false),
mSaveLayoutState(true) {}
SHEntrySharedParentState::SHEntrySharedParentState(
nsIPrincipal* aTriggeringPrincipal, nsIPrincipal* aPrincipalToInherit,
nsIPrincipal* aPartitionedPrincipalToInherit,
nsIContentSecurityPolicy* aCsp, const nsACString& aContentType)
: SHEntrySharedState(++gSHEntrySharedID, aTriggeringPrincipal,
aPrincipalToInherit, aPartitionedPrincipalToInherit,
aCsp, aContentType) {}
SHEntrySharedParentState::~SHEntrySharedParentState() {}

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

@ -43,17 +43,60 @@ namespace mozilla {
namespace dom {
class Document;
/**
* SHEntrySharedState holds shared state both in the child process and in the
* parent process.
*/
struct SHEntrySharedState {
SHEntrySharedState() = default;
SHEntrySharedState(const SHEntrySharedState& aState) = default;
SHEntrySharedState(uint64_t aId, nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aPrincipalToInherit,
nsIPrincipal* aPartitionedPrincipalToInherit,
nsIContentSecurityPolicy* aCsp,
const nsACString& aContentType)
: mId(aId),
mTriggeringPrincipal(aTriggeringPrincipal),
mPrincipalToInherit(aPrincipalToInherit),
mPartitionedPrincipalToInherit(aPartitionedPrincipalToInherit),
mCsp(aCsp),
mContentType(aContentType) {}
// These members aren't copied by SHEntrySharedParentState::CopyFrom() because
// they're specific to a particular content viewer.
uint64_t mId = 0;
// These members are copied by SHEntrySharedParentState::CopyFrom(). If you
// add a member here, be sure to update the CopyFrom() implementation.
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
nsCOMPtr<nsIPrincipal> mPartitionedPrincipalToInherit;
nsCOMPtr<nsIContentSecurityPolicy> mCsp;
nsCString mContentType;
// Child side updates layout history state when page is being unloaded or
// moved to bfcache.
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
uint32_t mCacheKey = 0;
};
/**
* SHEntrySharedParentState holds the shared state that can live in the parent
* process.
*/
class SHEntrySharedParentState {
class SHEntrySharedParentState : public SHEntrySharedState {
public:
uint64_t GetID() const { return mID; }
friend class SessionHistoryInfo;
uint64_t GetID() const { return mId; }
void NotifyListenersContentViewerEvicted();
SHEntrySharedParentState();
SHEntrySharedParentState() = default;
SHEntrySharedParentState(nsIPrincipal* aTriggeringPrincipal,
nsIPrincipal* aPrincipalToInherit,
nsIPrincipal* aPartitionedPrincipalToInherit,
nsIContentSecurityPolicy* aCsp,
const nsACString& aContentType);
protected:
virtual ~SHEntrySharedParentState();
@ -66,34 +109,24 @@ class SHEntrySharedParentState {
// These members are copied by SHEntrySharedParentState::CopyFrom(). If you
// add a member here, be sure to update the CopyFrom() implementation.
nsID mDocShellID;
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
nsCOMPtr<nsIPrincipal> mPartitionedPrincipalToInherit;
nsCOMPtr<nsIContentSecurityPolicy> mCsp;
// Child side updates layout history state when page is being unloaded or
// moved to bfcache.
nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
nsCString mContentType;
nsID mDocShellID{};
nsIntRect mViewerBounds;
nsIntRect mViewerBounds{0, 0, 0, 0};
uint32_t mCacheKey;
uint32_t mLastTouched;
uint32_t mLastTouched = 0;
// These members aren't copied by SHEntrySharedParentState::CopyFrom() because
// they're specific to a particular content viewer.
uint64_t mID;
nsWeakPtr mSHistory;
bool mIsFrameNavigation;
bool mSticky;
bool mDynamicallyCreated;
bool mIsFrameNavigation = false;
bool mSticky = true;
bool mDynamicallyCreated = false;
// This flag is about necko cache, not bfcache.
bool mExpired;
bool mExpired = false;
bool mSaveLayoutState;
bool mSaveLayoutState = true;
};
/**

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

@ -1729,7 +1729,6 @@ void nsSHistory::InitiateLoad(nsISHEntry* aFrameEntry,
loadState->SetLoadType(aLoadType);
SessionHistoryEntry::MaybeSynchronizeSharedStateToInfo(aFrameEntry);
loadState->SetSHEntry(aFrameEntry);
loadState->SetLoadIsFromSessionHistory(mRequestedIndex, Length());