Commit 8ed0cb2e authored by Peter Van der Beken's avatar Peter Van der Beken
Browse files

Bug 1588491 - Associate session history entries with a session history object...

Bug 1588491 - Associate session history entries with a session history object from creation. Continue to allow docshells to create session history entries even if the root docshell doesn't have a session history object. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D50574

--HG--
extra : rebase_source : 0381ae4297820f92caa5a77f588c9372093c8315
extra : source : ebb01f79e94a182e4886c4af5b0f27f5b7a41c4e
extra : histedit_source : 4010d5a26f2fad681984e76718112d657d2e5fa1
parent b6d4b5e9
......@@ -11333,13 +11333,9 @@ nsresult nsDocShell::AddToSessionHistory(
NS_ENSURE_TRUE(webnav, NS_ERROR_FAILURE);
RefPtr<ChildSHistory> shistory = webnav->GetSessionHistory();
NS_ENSURE_TRUE(shistory, NS_ERROR_FAILURE);
shistory->LegacySHistory()->CreateEntry(getter_AddRefs(entry));
if (!entry) {
return NS_ERROR_OUT_OF_MEMORY;
}
entry = CreateSHEntryForDocShell(shistory ? shistory->LegacySHistory()
: nullptr);
NS_ENSURE_TRUE(entry, NS_ERROR_FAILURE);
}
// Get the post data & referrer
......
......@@ -125,5 +125,17 @@ nsISupports* ChildSHistory::GetParentObject() const {
return ToSupports(mm);
}
already_AddRefed<nsISHEntry> CreateSHEntryForDocShell(nsISHistory* aSHistory) {
uint64_t sharedID = SHEntryChildShared::CreateSharedID();
if (XRE_IsContentProcess() && StaticPrefs::fission_sessionHistoryInParent()) {
return do_AddRef(static_cast<SHEntryChild*>(
ContentChild::GetSingleton()->SendPSHEntryConstructor(
static_cast<SHistoryChild*>(aSHistory), sharedID)));
}
nsCOMPtr<nsISHEntry> entry = new nsLegacySHEntry(aSHistory, sharedID);
return entry.forget();
}
} // namespace dom
} // namespace mozilla
......@@ -108,6 +108,8 @@ class ChildSHistory : public nsISupports, public nsWrapperCache {
mozilla::LinkedList<PendingAsyncHistoryNavigation> mPendingNavigations;
};
already_AddRefed<nsISHEntry> CreateSHEntryForDocShell(nsISHistory* aSHistory);
} // namespace dom
} // namespace mozilla
......
......@@ -19,6 +19,7 @@ struct IPDLParamTraits<dom::NewPSHEntry> {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!");
WriteIPDLParam(aMsg, aActor, std::move(aEntry.mEndpoint));
WriteIPDLParam(aMsg, aActor, aEntry.mSHistoryParent);
WriteIPDLParam(aMsg, aActor, aEntry.mSharedID);
}
......@@ -27,6 +28,7 @@ struct IPDLParamTraits<dom::NewPSHEntry> {
MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!");
return ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mEndpoint) &&
ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mSHistoryChild) &&
ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mSharedID);
}
};
......@@ -65,8 +67,9 @@ bool IPDLParamTraits<dom::CrossProcessSHEntry*>::Read(
return true;
},
[&](dom::NewPSHEntry& newEntry) {
RefPtr<dom::SHEntryChild> entry =
new dom::SHEntryChild(newEntry.mSharedID);
RefPtr<dom::SHEntryChild> entry = new dom::SHEntryChild(
static_cast<dom::SHistoryChild*>(newEntry.mSHistoryChild),
newEntry.mSharedID);
dom::ContentChild::GetSingleton()->BindPSHEntryEndpoint(
std::move(newEntry.mEndpoint), do_AddRef(entry).take());
*aEntry = entry.forget();
......
......@@ -23,6 +23,8 @@ class SHEntryChild;
struct NewPSHEntry final {
mozilla::ipc::ManagedEndpoint<PSHEntryChild> mEndpoint;
PSHistoryParent* mSHistoryParent;
PSHistoryChild* mSHistoryChild;
uint64_t mSharedID;
};
......
......@@ -32,14 +32,15 @@ void SHEntryChildShared::Init() {
}
/* static */
SHEntryChildShared* SHEntryChildShared::GetOrCreate(uint64_t aSharedID) {
SHEntryChildShared* SHEntryChildShared::GetOrCreate(SHistoryChild* aSHistory,
uint64_t aSharedID) {
MOZ_DIAGNOSTIC_ASSERT(
sSHEntryChildSharedTable,
"SHEntryChildShared::Init should have created the table.");
RefPtr<SHEntryChildShared>& shared =
sSHEntryChildSharedTable->GetOrInsert(aSharedID);
if (!shared) {
shared = new SHEntryChildShared(aSharedID);
shared = new SHEntryChildShared(aSHistory, aSharedID);
}
return shared;
}
......@@ -81,7 +82,8 @@ void SHEntryChildShared::EvictContentViewers(
}
}
SHEntryChildShared::SHEntryChildShared(uint64_t aID) : mID(aID) {}
SHEntryChildShared::SHEntryChildShared(SHistoryChild* aSHistory, uint64_t aID)
: mID(aID), mSHistory(aSHistory) {}
SHEntryChildShared::~SHEntryChildShared() {
// The destruction can be caused by either the entry is removed from session
......@@ -105,7 +107,7 @@ NS_IMPL_ISUPPORTS(SHEntryChildShared, nsIBFCacheEntry, nsIMutationObserver)
already_AddRefed<SHEntryChildShared> SHEntryChildShared::Duplicate() {
RefPtr<SHEntryChildShared> newEntry = new SHEntryChildShared(
mozilla::dom::SHEntryChildShared::CreateSharedID());
mSHistory, mozilla::dom::SHEntryChildShared::CreateSharedID());
newEntry->CopyFrom(this);
return newEntry.forget();
}
......
......@@ -37,7 +37,8 @@ class SHEntryChildShared final : public nsIBFCacheEntry,
public:
static void Init();
static SHEntryChildShared* GetOrCreate(uint64_t aSharedID);
static SHEntryChildShared* GetOrCreate(SHistoryChild* aSHistory,
uint64_t aSharedID);
static void Remove(uint64_t aSharedID);
static uint64_t CreateSharedID() {
......@@ -65,7 +66,7 @@ class SHEntryChildShared final : public nsIBFCacheEntry,
private:
static uint64_t sNextSharedID;
explicit SHEntryChildShared(uint64_t aID);
SHEntryChildShared(SHistoryChild* aSHistory, uint64_t aID);
~SHEntryChildShared();
friend class SHEntryChild;
......@@ -94,8 +95,8 @@ class SHEntryChild final : public PSHEntryChild,
public:
explicit SHEntryChild(const SHEntryChild* aClone)
: mShared(aClone->mShared.get()), mIPCActorDeleted(false) {}
explicit SHEntryChild(uint64_t aSharedID)
: mShared(SHEntryChildShared::GetOrCreate(aSharedID)),
SHEntryChild(SHistoryChild* aSHistory, uint64_t aSharedID)
: mShared(SHEntryChildShared::GetOrCreate(aSHistory, aSharedID)),
mIPCActorDeleted(false) {}
NS_DECL_ISUPPORTS
......
......@@ -46,8 +46,11 @@ MaybeNewPSHEntryParent LegacySHEntry::GetOrCreateActor(
return AsVariant(static_cast<PSHEntryParent*>(mActor));
}
return AsVariant(NewPSHEntry{
aContentParent->OpenPSHEntryEndpoint(CreateActor()), mShared->mID});
nsCOMPtr<nsISHistory> shistory = do_QueryReferent(mShared->mSHistory);
return AsVariant(
NewPSHEntry{aContentParent->OpenPSHEntryEndpoint(CreateActor()),
static_cast<LegacySHistory*>(shistory.get())->GetActor(),
nullptr, mShared->mID});
}
void LegacySHEntry::AbandonBFCacheEntry(uint64_t aNewSharedID) {
......
......@@ -16,9 +16,10 @@ extern mozilla::LazyLogModule gSHistoryLog;
namespace mozilla {
namespace dom {
LegacySHistory::LegacySHistory(CanonicalBrowsingContext* aRootBC,
LegacySHistory::LegacySHistory(SHistoryParent* aSHistoryParent,
CanonicalBrowsingContext* aRootBC,
const nsID& aDocShellID)
: nsSHistory(aRootBC, aDocShellID) {
: nsSHistory(aRootBC, aDocShellID), mSHistoryParent(aSHistoryParent) {
mIsRemote = true;
aRootBC->SetSessionHistory(this);
}
......@@ -36,9 +37,9 @@ static void FillInLoadResult(PContentParent* aManager, nsresult aRv,
}
SHistoryParent::SHistoryParent(CanonicalBrowsingContext* aContext)
: mHistory(new LegacySHistory(aContext, nsID())) {}
: mHistory(new LegacySHistory(this, aContext, nsID())) {}
SHistoryParent::~SHistoryParent() {}
SHistoryParent::~SHistoryParent() { mHistory->mSHistoryParent = nullptr; }
SHEntryParent* SHistoryParent::CreateEntry(
PContentParent* aContentParent, PSHistoryParent* aSHistoryParent,
......
......@@ -24,14 +24,20 @@ class SHistoryParent;
*/
class LegacySHistory final : public nsSHistory {
private:
friend class SHistoryParent;
virtual ~LegacySHistory() {}
void EvictOutOfRangeWindowContentViewers(int32_t aIndex) override;
SHistoryParent* mSHistoryParent;
public:
LegacySHistory(CanonicalBrowsingContext* aRootBC, const nsID& aDocShellID);
LegacySHistory(SHistoryParent* aSHistoryParent,
CanonicalBrowsingContext* aRootBC, const nsID& aDocShellID);
NS_IMETHOD CreateEntry(nsISHEntry** aEntry) override;
SHistoryParent* GetActor() { return mSHistoryParent; }
};
/**
......@@ -39,6 +45,7 @@ class LegacySHistory final : public nsSHistory {
* implementation that used to live in the child process (see LegacySHistory).
*/
class SHistoryParent final : public PSHistoryParent {
friend class LegacySHistory;
friend class PSHistoryParent;
friend class SHEntryParent;
......
......@@ -1038,7 +1038,7 @@ void nsSHEntry::EvictContentViewer() {
}
}
nsLegacySHEntry::nsLegacySHEntry(nsSHistory* aHistory, uint64_t aID)
nsLegacySHEntry::nsLegacySHEntry(nsISHistory* aHistory, uint64_t aID)
: nsSHEntry(new nsSHEntryShared(aHistory, aID)) {}
NS_IMETHODIMP
......
......@@ -79,7 +79,7 @@ class nsSHEntry : public nsISHEntry {
*/
class nsLegacySHEntry final : public nsSHEntry {
public:
explicit nsLegacySHEntry(nsSHistory* aHistory, uint64_t aID);
explicit nsLegacySHEntry(nsISHistory* aHistory, uint64_t aID);
explicit nsLegacySHEntry(const nsLegacySHEntry& aOther) : nsSHEntry(aOther) {}
NS_IMETHOD GetContentViewer(nsIContentViewer** aResult) override;
......
......@@ -25,7 +25,7 @@ namespace dom = mozilla::dom;
namespace mozilla {
namespace dom {
SHEntrySharedParentState::SHEntrySharedParentState(nsSHistory* aSHistory,
SHEntrySharedParentState::SHEntrySharedParentState(nsISHistory* aSHistory,
uint64_t aID)
: SHEntrySharedParentState(nsWeakPtr(do_GetWeakReference(aSHistory)).get(),
aID) {}
......
......@@ -53,10 +53,10 @@ class SHEntrySharedParentState {
void NotifyListenersContentViewerEvicted();
protected:
SHEntrySharedParentState(nsSHistory* aSHistory, uint64_t aID);
SHEntrySharedParentState(nsISHistory* aSHistory, uint64_t aID);
SHEntrySharedParentState(SHEntrySharedParentState* aDuplicate, uint64_t aID)
: SHEntrySharedParentState(aDuplicate->mSHistory, aID) {}
SHEntrySharedParentState(nsIWeakReference* aDuplicate, uint64_t aID);
SHEntrySharedParentState(nsIWeakReference* aSHistory, uint64_t aID);
virtual ~SHEntrySharedParentState();
NS_INLINE_DECL_VIRTUAL_REFCOUNTING_WITH_DESTROY(SHEntrySharedParentState,
Destroy())
......
......@@ -3485,7 +3485,8 @@ PSHEntryChild* ContentChild::AllocPSHEntryChild(
// DeallocPSHEntryChild) if that is the only remaining reference.
RefPtr<SHEntryChild> child;
if (aEntryOrSharedID.type() == PSHEntryOrSharedID::Tuint64_t) {
child = new SHEntryChild(aEntryOrSharedID.get_uint64_t());
child = new SHEntryChild(static_cast<SHistoryChild*>(aSHistory),
aEntryOrSharedID.get_uint64_t());
} else {
child = new SHEntryChild(
static_cast<const SHEntryChild*>(aEntryOrSharedID.get_PSHEntryChild()));
......
......@@ -928,7 +928,7 @@ parent:
async PSHistory(BrowsingContext aContext);
// Clone from entry or use shared id.
sync PSHEntry(PSHistory shistory, PSHEntryOrSharedID entryOrSharedID);
sync PSHEntry(nullable PSHistory shistory, PSHEntryOrSharedID entryOrSharedID);
async PBenchmarkStorage();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment