author | Peter Van der Beken <peterv@propagandism.org> |
Mon, 30 Sep 2019 15:25:53 +0200 | |
changeset 500510 | f24cad095172ebf36649a02a37dbdbbb3712f89c |
parent 500509 | 325fca25e08dd2757735a17a8b8a6c7ce98f53ac |
child 500511 | dfd20e536b859a800d854a8bc69d4c84d60689e9 |
push id | 114165 |
push user | pvanderbeken@mozilla.com |
push date | Wed, 06 Nov 2019 09:18:40 +0000 |
treeherder | mozilla-inbound@db1ddab2985d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nika |
bugs | 1583321 |
milestone | 72.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
new file mode 100644 --- /dev/null +++ b/docshell/shistory/MaybeNewPSHEntry.cpp @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/MaybeNewPSHEntry.h" +#include "mozilla/dom/PContentParent.h" +#include "mozilla/dom/SHEntryChild.h" +#include "mozilla/dom/SHEntryParent.h" + +namespace mozilla { +namespace ipc { + +template <> +struct IPDLParamTraits<dom::NewPSHEntry> { + static void Write(IPC::Message* aMsg, IProtocol* aActor, + dom::NewPSHEntry&& aEntry) { + MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!"); + + WriteIPDLParam(aMsg, aActor, std::move(aEntry.mEndpoint)); + WriteIPDLParam(aMsg, aActor, aEntry.mSharedID); + } + + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, dom::NewPSHEntry* aEntry) { + MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!"); + + return ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mEndpoint) && + ReadIPDLParam(aMsg, aIter, aActor, &aEntry->mSharedID); + } +}; + +/* static */ +void IPDLParamTraits<dom::CrossProcessSHEntry*>::Write( + IPC::Message* aMsg, IProtocol* aActor, dom::CrossProcessSHEntry* aEntry) { + MOZ_RELEASE_ASSERT(aActor->GetSide() == ParentSide, "wrong side!"); + MOZ_DIAGNOSTIC_ASSERT(aActor->ToplevelProtocol()->GetProtocolId() == + PContentMsgStart); + + dom::MaybeNewPSHEntryParent entry(static_cast<dom::PSHEntryParent*>(nullptr)); + if (aEntry) { + entry = static_cast<dom::LegacySHEntry*>(aEntry)->GetOrCreateActor( + static_cast<dom::PContentParent*>(aActor->ToplevelProtocol())); + } + + WriteIPDLParam(aMsg, aActor, std::move(entry)); +} + +/* static */ +bool IPDLParamTraits<dom::CrossProcessSHEntry*>::Read( + const IPC::Message* aMsg, PickleIterator* aIter, + mozilla::ipc::IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry) { + MOZ_RELEASE_ASSERT(aActor->GetSide() == ChildSide, "wrong side!"); + + dom::MaybeNewPSHEntryChild actor(static_cast<dom::PSHEntryChild*>(nullptr)); + if (!ReadIPDLParam(aMsg, aIter, aActor, &actor)) { + aActor->FatalError("Error deserializing MaybeNewPSHEntry"); + return false; + } + + return actor.match( + [&](dom::PSHEntryChild*& entry) { + *aEntry = static_cast<dom::SHEntryChild*>(entry); + return true; + }, + [&](dom::NewPSHEntry& newEntry) { + RefPtr<dom::SHEntryChild> entry = + new dom::SHEntryChild(newEntry.mSharedID); + dom::ContentChild::GetSingleton()->BindPSHEntryEndpoint( + std::move(newEntry.mEndpoint), do_AddRef(entry).take()); + *aEntry = entry.forget(); + return true; + }); +} + +} // namespace ipc +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/docshell/shistory/MaybeNewPSHEntry.h @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_MaybeNewPSHEntry_h +#define mozilla_dom_MaybeNewPSHEntry_h + +#include "ipc/IPCMessageUtils.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/Variant.h" +#include "mozilla/ipc/IPDLParamTraits.h" +#include "mozilla/ipc/ProtocolUtils.h" + +namespace mozilla { +namespace dom { + +class LegacySHEntry; +class PSHEntryChild; +class PSHEntryParent; +class SHEntryChild; + +struct NewPSHEntry final { + mozilla::ipc::ManagedEndpoint<PSHEntryChild> mEndpoint; + uint64_t mSharedID; +}; + +typedef Variant<PSHEntryParent*, NewPSHEntry> MaybeNewPSHEntryParent; +typedef Variant<PSHEntryChild*, NewPSHEntry> MaybeNewPSHEntryChild; + +// Any IPDL protocol trying to pass this (as argument or return value) needs to +// be managed by PContent. +class CrossProcessSHEntry { + NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING + + SHEntryChild* ToSHEntryChild(); +}; + +} // namespace dom + +namespace ipc { + +template <> +struct IPDLParamTraits<dom::CrossProcessSHEntry*> { + static void Write(IPC::Message* aMsg, IProtocol* aActor, + dom::CrossProcessSHEntry* aEntry); + + static bool Read(const IPC::Message* aMsg, PickleIterator* aIter, + IProtocol* aActor, RefPtr<dom::CrossProcessSHEntry>* aEntry); +}; + +} // namespace ipc +} // namespace mozilla + +#endif /* mozilla_dom_MaybeNewPSHEntry_h */
deleted file mode 100644 --- a/docshell/shistory/NewPSHEntry.ipdlh +++ /dev/null @@ -1,27 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include protocol PSHEntry; - -namespace mozilla { -namespace dom { - -union PSHEntryOrSharedID -{ - PSHEntry; - uint64_t; -}; - -struct NewPSHEntry { - ManagedEndpoint<PSHEntryChild> endpoint; - uint64_t sharedID; -}; - -union MaybeNewPSHEntry { - nullable PSHEntry; - NewPSHEntry; -}; - -} // namespace dom -} // namespace mozilla
--- a/docshell/shistory/PSHEntry.ipdl +++ b/docshell/shistory/PSHEntry.ipdl @@ -1,26 +1,28 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ include protocol PContent; include protocol PSHistory; include DOMTypes; -include NewPSHEntry; +using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h"; using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h"; using struct nsID from "nsID.h"; using nsIntRect from "nsRect.h"; namespace mozilla { namespace dom { sync protocol PSHEntry { + // IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being + // the manager. manager PContent; parent: sync GetURI() returns (nsIURI uri); async SetURI(nsIURI uri); sync GetOriginalURI() returns (nsIURI originalUri); async SetOriginalURI(nsIURI originalUri); sync GetResultPrincipalURI() returns (nsIURI resultPrincipalUri); @@ -32,17 +34,17 @@ parent: sync GetIsSubFrame() returns (bool isSubFrame); async SetIsSubFrame(bool isSubFrame); sync GetReferrerInfo() returns (nsIReferrerInfo referrerInfo); async SetReferrerInfo(nsIReferrerInfo referrerInfo); sync GetSticky() returns (bool sticky); async SetSticky(bool sticky); sync GetPostData() returns (nsIInputStream postData); async SetPostData(nsIInputStream postData); - sync GetParent() returns (MaybeNewPSHEntry parentEntry); + sync GetParent() returns (CrossProcessSHEntry parentEntry); async SetParent(nullable PSHEntry parentEntry); sync GetLoadType() returns (uint32_t loadType); async SetLoadType(uint32_t loadType); sync GetID() returns (uint32_t id); async SetID(uint32_t id); sync GetCacheKey() returns (uint32_t cacheKey); async SetCacheKey(uint32_t cacheKey); sync GetExpirationStatus() returns (bool expirationStatus); @@ -95,18 +97,18 @@ parent: sync HasDynamicallyAddedChild() returns (bool hasDynamicallyAddedChild); sync AdoptBFCacheEntry(PSHEntry entry) returns (nsresult result); async AbandonBFCacheEntry(uint64_t aNewSharedID); sync SharesDocumentWith(PSHEntry entry) returns (bool sharesDocumentWith, nsresult result); async SetLoadTypeAsHistory(); sync AddChild(nullable PSHEntry childEntry, int32_t offset, bool useRemoteSubframes) returns (nsresult result); sync RemoveChild(PSHEntry childEntry) returns (nsresult result); - sync GetChildAt(int32_t index) returns (MaybeNewPSHEntry childEntry); - sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (MaybeNewPSHEntry childEntry); + sync GetChildAt(int32_t index) returns (CrossProcessSHEntry childEntry); + sync GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t childOffset) returns (CrossProcessSHEntry childEntry); sync ReplaceChild(PSHEntry newChildEntry) returns (nsresult result); async ClearEntry(uint64_t aNewSharedID); sync CreateLoadInfo() returns (nsDocShellLoadState loadState); sync __delete__(); }; } // namespace dom
--- a/docshell/shistory/PSHistory.ipdl +++ b/docshell/shistory/PSHistory.ipdl @@ -1,65 +1,68 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ include protocol PContent; include protocol PSHEntry; include DOMTypes; -include NewPSHEntry; using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h"; +using refcounted class mozilla::dom::CrossProcessSHEntry from "mozilla/dom/MaybeNewPSHEntry.h"; using refcounted class nsDocShellLoadState from "mozilla/dom/DocShellMessageUtils.h"; using struct nsID from "nsID.h"; using struct mozilla::null_t from "ipc/IPCMessageUtils.h"; namespace mozilla { namespace dom { struct LoadSHEntryData { - MaybeNewPSHEntry shEntry; + CrossProcessSHEntry shEntry; BrowsingContext browsingContext; nsDocShellLoadState loadState; }; union LoadSHEntryResult { nsresult; LoadSHEntryData; }; sync protocol PSHistory { + // IPDLParamTraits<dom::CrossProcessSHEntry*>::Write relies on PContent being + // the manager. manager PContent; parent: sync GetCount() returns (int32_t count); sync GetIndex() returns (int32_t index); sync SetIndex(int32_t index) returns (nsresult result); sync GetRequestedIndex() returns (int32_t index); async InternalSetRequestedIndex(int32_t index); - sync GetEntryAtIndex(int32_t index) returns (nsresult result, MaybeNewPSHEntry entry); + sync GetEntryAtIndex(int32_t index) returns (nsresult result, CrossProcessSHEntry entry); sync PurgeHistory(int32_t numEntries) returns (nsresult result); sync ReloadCurrentEntry() returns (LoadSHEntryResult load); sync GotoIndex(int32_t index) returns (LoadSHEntryResult load); sync GetIndexOfEntry(PSHEntry entry) returns (int32_t index); sync AddEntry(PSHEntry entry, bool persist) returns (nsresult result, int32_t entriesPurged); async UpdateIndex(); sync ReplaceEntry(int32_t index, PSHEntry entry) returns (nsresult result); sync NotifyOnHistoryReload() returns (bool ok); async EvictOutOfRangeContentViewers(int32_t index); async EvictAllContentViewers(); async RemoveDynEntries(int32_t index, PSHEntry entry); sync RemoveEntries(nsID[] ids, int32_t index) returns (bool didRemove); async RemoveFrameEntries(PSHEntry entry); sync Reload(uint32_t reloadFlags) returns (LoadSHEntryResult load); - sync GetAllEntries() returns (MaybeNewPSHEntry[] entries); - sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry) returns (MaybeNewPSHEntry entries, int32_t startIndex); + sync GetAllEntries() returns (CrossProcessSHEntry[] entries); + sync FindEntryForBFCache(uint64_t sharedID, bool includeCurrentEntry) + returns (CrossProcessSHEntry entries, int32_t startIndex); async Evict(PSHEntry[] entry); async EnsureCorrectEntryAtCurrIndex(PSHEntry entry); async EvictContentViewersOrReplaceEntry(nullable PSHEntry newSHEntry, bool replace); async NotifyListenersContentViewerEvicted(uint32_t numEvicted); async __delete__(); }; } // namespace dom
--- a/docshell/shistory/SHEntryChild.cpp +++ b/docshell/shistory/SHEntryChild.cpp @@ -2,16 +2,18 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SHEntryChild.h" #include "SHistoryChild.h" #include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticPrefs_docshell.h" +#include "mozilla/dom/MaybeNewPSHEntry.h" #include "nsDocShellEditorData.h" #include "nsDocShellLoadState.h" #include "nsIContentViewer.h" #include "nsILayoutHistoryState.h" #include "nsIMutableArray.h" #include "nsStructuredCloneContainer.h" namespace mozilla { @@ -588,22 +590,22 @@ SHEntryChild::Clone(nsISHEntry** aResult NS_IF_ADDREF(*aResult = static_cast<SHEntryChild*>( ContentChild::GetSingleton()->SendPSHEntryConstructor( this))); return NS_OK; } NS_IMETHODIMP SHEntryChild::GetParent(nsISHEntry** aResult) { - MaybeNewPSHEntry parent; + RefPtr<CrossProcessSHEntry> parent; if (!SendGetParent(&parent)) { return NS_ERROR_FAILURE; } - *aResult = SHEntryChild::GetOrCreate(parent).take(); + *aResult = parent ? do_AddRef(parent->ToSHEntryChild()).take() : nullptr; return NS_OK; } NS_IMETHODIMP SHEntryChild::SetParent(nsISHEntry* aParent) { return SendSetParent(static_cast<SHEntryChild*>(aParent)) ? NS_OK : NS_ERROR_FAILURE; } @@ -803,31 +805,31 @@ SHEntryChild::RemoveChild(nsISHEntry* aC nsresult rv; return aChild && SendRemoveChild(static_cast<SHEntryChild*>(aChild), &rv) ? rv : NS_ERROR_FAILURE; } NS_IMETHODIMP SHEntryChild::GetChildAt(int32_t aIndex, nsISHEntry** aResult) { - MaybeNewPSHEntry child; + RefPtr<CrossProcessSHEntry> child; if (!SendGetChildAt(aIndex, &child)) { return NS_ERROR_FAILURE; } - *aResult = SHEntryChild::GetOrCreate(child).take(); + *aResult = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr; return NS_OK; } NS_IMETHODIMP_(void) SHEntryChild::GetChildSHEntryIfHasNoDynamicallyAddedChild(int32_t aChildOffset, nsISHEntry** aChild) { - MaybeNewPSHEntry child; + RefPtr<CrossProcessSHEntry> child; SendGetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset, &child); - *aChild = SHEntryChild::GetOrCreate(child).take(); + *aChild = child ? do_AddRef(child->ToSHEntryChild()).take() : nullptr; } NS_IMETHODIMP SHEntryChild::ReplaceChild(nsISHEntry* aNewEntry) { nsresult rv; return SendReplaceChild(static_cast<SHEntryChild*>(aNewEntry), &rv) ? rv : NS_ERROR_FAILURE; @@ -1007,25 +1009,10 @@ void SHEntryChild::EvictContentViewer() // document teardown is able to correctly persist the state. mShared->NotifyListenersContentViewerEvicted(); SetContentViewer(nullptr); SyncPresentationState(); viewer->Destroy(); } } -/* static */ -already_AddRefed<SHEntryChild> SHEntryChild::GetOrCreate( - MaybeNewPSHEntry& aEntry) { - RefPtr<SHEntryChild> entry; - if (aEntry.type() == MaybeNewPSHEntry::TNewPSHEntry) { - NewPSHEntry& newEntry = aEntry.get_NewPSHEntry(); - entry = new SHEntryChild(newEntry.sharedID()); - ContentChild::GetSingleton()->BindPSHEntryEndpoint( - std::move(newEntry.endpoint()), do_AddRef(entry).take()); - } else { - entry = static_cast<SHEntryChild*>(aEntry.get_PSHEntryChild()); - } - return entry.forget(); -} - } // namespace dom } // namespace mozilla
--- a/docshell/shistory/SHEntryChild.h +++ b/docshell/shistory/SHEntryChild.h @@ -3,16 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_SHEntryChild_h #define mozilla_dom_SHEntryChild_h #include "mozilla/dom/PSHEntryChild.h" +#include "mozilla/dom/MaybeNewPSHEntry.h" #include "nsContentUtils.h" #include "nsExpirationTracker.h" #include "nsIBFCacheEntry.h" #include "nsISHEntry.h" #include "nsRect.h" #include "nsSHEntryShared.h" #include "nsStubMutationObserver.h" @@ -79,41 +80,47 @@ class SHEntryChildShared final : public uint64_t mID; RefPtr<SHistoryChild> mSHistory; }; /** * Session history entry actor for the child process. */ -class SHEntryChild final : public PSHEntryChild, public nsISHEntry { +class SHEntryChild final : public PSHEntryChild, + public nsISHEntry, + public CrossProcessSHEntry { friend class PSHEntryChild; + using PSHEntryChild::CrossProcessSHEntry; public: explicit SHEntryChild(const SHEntryChild* aClone) : mShared(aClone->mShared.get()), mIPCActorDeleted(false) {} explicit SHEntryChild(uint64_t aSharedID) : mShared(SHEntryChildShared::GetOrCreate(aSharedID)), mIPCActorDeleted(false) {} NS_DECL_ISUPPORTS NS_DECL_NSISHENTRY void EvictContentViewer(); - static already_AddRefed<SHEntryChild> GetOrCreate(MaybeNewPSHEntry& aEntry); - protected: void ActorDestroy(ActorDestroyReason aWhy) override { mIPCActorDeleted = true; } private: ~SHEntryChild() = default; RefPtr<SHEntryChildShared> mShared; bool mIPCActorDeleted; }; +inline SHEntryChild* CrossProcessSHEntry::ToSHEntryChild() { + MOZ_ASSERT(XRE_IsContentProcess(), "Wrong side!"); + return static_cast<SHEntryChild*>(this); +} + } // namespace dom } // namespace mozilla #endif /* mozilla_dom_SHEntryChild_h */
--- a/docshell/shistory/SHEntryParent.cpp +++ b/docshell/shistory/SHEntryParent.cpp @@ -2,16 +2,17 @@ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SHEntryParent.h" #include "SHistoryParent.h" #include "mozilla/dom/ContentParent.h" +#include "mozilla/dom/MaybeNewPSHEntry.h" #include "nsStructuredCloneContainer.h" namespace mozilla { namespace dom { SHEntrySharedParent::SHEntrySharedParent(PContentParent* aContentParent, uint64_t aSharedID) : SHEntrySharedParentState(aSharedID), mContentParent(aContentParent) {} @@ -19,31 +20,32 @@ SHEntrySharedParent::SHEntrySharedParent void SHEntrySharedParent::Destroy() { if (mContentParent && !static_cast<ContentParent*>(mContentParent.get())->IsDestroyed()) { Unused << mContentParent->SendDestroySHEntrySharedState(mID); } SHEntrySharedParentState::Destroy(); } +NS_IMPL_ISUPPORTS_INHERITED0(LegacySHEntry, nsSHEntry) + SHEntryParent* LegacySHEntry::CreateActor() { MOZ_ASSERT(!mActor); mActor = new SHEntryParent(this); return mActor; } -void LegacySHEntry::GetOrCreateActor(PContentParent* aContentParent, - MaybeNewPSHEntry& aEntry) { - if (!mActor) { - mActor = new SHEntryParent(this); - aEntry = - NewPSHEntry(aContentParent->OpenPSHEntryEndpoint(mActor), mShared->mID); - } else { - aEntry = mActor; +MaybeNewPSHEntryParent LegacySHEntry::GetOrCreateActor( + PContentParent* aContentParent) { + if (mActor) { + return AsVariant(static_cast<PSHEntryParent*>(mActor)); } + + return AsVariant(NewPSHEntry{ + aContentParent->OpenPSHEntryEndpoint(CreateActor()), mShared->mID}); } void LegacySHEntry::AbandonBFCacheEntry(uint64_t aNewSharedID) { PContentParent* contentParent = static_cast<SHEntrySharedParent*>(mShared.get())->GetContentParent(); RefPtr<SHEntrySharedParent> shared = new SHEntrySharedParent(contentParent, aNewSharedID); shared->CopyFrom(mShared); @@ -151,19 +153,19 @@ bool SHEntryParent::RecvGetPostData(RefP } bool SHEntryParent::RecvSetPostData(nsIInputStream* aPostData) { DebugOnly<nsresult> rv = mEntry->SetPostData(aPostData); MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail."); return true; } -bool SHEntryParent::RecvGetParent(MaybeNewPSHEntry* aParentEntry) { +bool SHEntryParent::RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry) { nsCOMPtr<nsISHEntry> parent = mEntry->GetParent(); - GetOrCreate(parent, aParentEntry); + *aParentEntry = parent.forget().downcast<LegacySHEntry>(); return true; } bool SHEntryParent::RecvSetParent(PSHEntryParent* aParentEntry) { DebugOnly<nsresult> rv = mEntry->SetParent( aParentEntry ? static_cast<SHEntryParent*>(aParentEntry)->mEntry.get() : nullptr); MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail."); @@ -502,50 +504,41 @@ bool SHEntryParent::RecvAddChild(PSHEntr } bool SHEntryParent::RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult) { *aResult = mEntry->RemoveChild(static_cast<SHEntryParent*>(aChild)->mEntry); return true; } bool SHEntryParent::RecvGetChildAt(const int32_t& aIndex, - MaybeNewPSHEntry* aChild) { + RefPtr<CrossProcessSHEntry>* aChild) { nsCOMPtr<nsISHEntry> child; DebugOnly<nsresult> rv = mEntry->GetChildAt(aIndex, getter_AddRefs(child)); MOZ_ASSERT(NS_SUCCEEDED(rv), "Didn't expect this to fail."); - GetOrCreate(child, aChild); + *aChild = child.forget().downcast<LegacySHEntry>(); return true; } bool SHEntryParent::RecvGetChildSHEntryIfHasNoDynamicallyAddedChild( - const int32_t& aChildOffset, MaybeNewPSHEntry* aChild) { + const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild) { nsCOMPtr<nsISHEntry> child; mEntry->GetChildSHEntryIfHasNoDynamicallyAddedChild(aChildOffset, getter_AddRefs(child)); - GetOrCreate(child, aChild); + *aChild = child.forget().downcast<LegacySHEntry>(); return true; } bool SHEntryParent::RecvReplaceChild(PSHEntryParent* aNewChild, nsresult* aResult) { *aResult = mEntry->ReplaceChild(static_cast<SHEntryParent*>(aNewChild)->mEntry); return true; } -void SHEntryParent::GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry, - MaybeNewPSHEntry& aResult) { - if (aSHEntry) { - static_cast<LegacySHEntry*>(aSHEntry)->GetOrCreateActor(aManager, aResult); - } else { - aResult = (PSHEntryParent*)nullptr; - } -} - bool SHEntryParent::RecvClearEntry(const uint64_t& aNewSharedID) { mEntry->ClearEntry(); mEntry->AbandonBFCacheEntry(aNewSharedID); return true; } bool SHEntryParent::RecvCreateLoadInfo( RefPtr<nsDocShellLoadState>* aLoadState) {
--- a/docshell/shistory/SHEntryParent.h +++ b/docshell/shistory/SHEntryParent.h @@ -3,16 +3,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_SHistoryEntry_h #define mozilla_dom_SHistoryEntry_h #include "mozilla/dom/PSHEntryParent.h" +#include "mozilla/dom/MaybeNewPSHEntry.h" #include "mozilla/WeakPtr.h" #include "nsSHEntry.h" #include "nsSHEntryShared.h" namespace mozilla { namespace dom { class PContentParent; @@ -36,40 +37,43 @@ class SHEntrySharedParent : public SHEnt /** * Session history entry implementation based on the legacy implementation that * used to live in the child process. Ideally this wouldn't implement nsISHEntry * (it should only ever be accessed by SHEntryParent and LegacySHistory). * The actor is (re)created as needed, whenever we need to return an entry to * the child process. The lifetime is determined by the child side. */ -class LegacySHEntry final : public nsSHEntry { +class LegacySHEntry final : public nsSHEntry, public CrossProcessSHEntry { public: LegacySHEntry(PContentParent* aParent, uint64_t aSharedID) : nsSHEntry(new SHEntrySharedParent(aParent, aSharedID)), mActor(nullptr) {} explicit LegacySHEntry(const LegacySHEntry& aEntry) : nsSHEntry(aEntry), mActor(nullptr) {} - void GetOrCreateActor(PContentParent* aContentParent, - MaybeNewPSHEntry& aEntry); + NS_DECL_ISUPPORTS_INHERITED + + MaybeNewPSHEntryParent GetOrCreateActor(PContentParent* aContentParent); using nsSHEntry::AbandonBFCacheEntry; void AbandonBFCacheEntry(uint64_t aNewSharedID); uint64_t GetSharedStateID() const { return mShared->GetID(); } dom::SHEntrySharedParentState* GetSharedState() const { return mShared.get(); } private: friend class SHEntryParent; friend class ContentParent; + ~LegacySHEntry() {} + SHEntryParent* CreateActor(); SHEntryParent* mActor; }; /** * Session history entry actor for the parent process. Forwards to the legacy * implementation that used to live in the child process (see LegacySHEntry). @@ -78,19 +82,16 @@ class SHEntryParent final : public PSHEn friend class PSHEntryParent; friend class SHistoryParent; friend class ContentParent; public: explicit SHEntryParent(LegacySHEntry* aEntry) : PSHEntryParent(), mEntry(aEntry) {} - static void GetOrCreate(PContentParent* aManager, nsISHEntry* aSHEntry, - MaybeNewPSHEntry& aResult); - LegacySHEntry* GetSHEntry() { return mEntry; } protected: void ActorDestroy(ActorDestroyReason aWhy) override; private: bool RecvGetURI(RefPtr<nsIURI>* aURI); bool RecvSetURI(nsIURI* aURI); @@ -105,17 +106,17 @@ class SHEntryParent final : public PSHEn bool RecvGetIsSubFrame(bool* aIsSubFrame); bool RecvSetIsSubFrame(const bool& aIsSubFrame); bool RecvGetReferrerInfo(RefPtr<nsIReferrerInfo>* aReferrerInfo); bool RecvSetReferrerInfo(nsIReferrerInfo* aReferrerInfo); bool RecvGetSticky(bool* aSticky); bool RecvSetSticky(const bool& aSticky); bool RecvGetPostData(RefPtr<nsIInputStream>* aPostData); bool RecvSetPostData(nsIInputStream* aPostData); - bool RecvGetParent(MaybeNewPSHEntry* aParentEntry); + bool RecvGetParent(RefPtr<CrossProcessSHEntry>* aParentEntry); bool RecvSetParent(PSHEntryParent* aParentEntry); bool RecvGetLoadType(uint32_t* aLoadType); bool RecvSetLoadType(const uint32_t& aLoadType); bool RecvGetID(uint32_t* aID); bool RecvSetID(const uint32_t& aID); bool RecvGetCacheKey(uint32_t* aCacheKey); bool RecvSetCacheKey(const uint32_t& aCacheKey); bool RecvGetExpirationStatus(bool* aExpirationStatus); @@ -175,25 +176,23 @@ class SHEntryParent final : public PSHEn bool RecvAdoptBFCacheEntry(PSHEntryParent* aEntry, nsresult* aResult); bool RecvAbandonBFCacheEntry(const uint64_t& aNewSharedID); bool RecvSharesDocumentWith(PSHEntryParent* aEntry, bool* aSharesDocumentWith, nsresult* aResult); bool RecvSetLoadTypeAsHistory(); bool RecvAddChild(PSHEntryParent* aChild, const int32_t& aOffset, const bool& aUseRemoteSubframes, nsresult* aResult); bool RecvRemoveChild(PSHEntryParent* aChild, nsresult* aResult); - bool RecvGetChildAt(const int32_t& aIndex, MaybeNewPSHEntry* aChild); + bool RecvGetChildAt(const int32_t& aIndex, + RefPtr<CrossProcessSHEntry>* aChild); bool RecvGetChildSHEntryIfHasNoDynamicallyAddedChild( - const int32_t& aChildOffset, MaybeNewPSHEntry* aChild); + const int32_t& aChildOffset, RefPtr<CrossProcessSHEntry>* aChild); bool RecvReplaceChild(PSHEntryParent* aNewChild, nsresult* aResult); bool RecvClearEntry(const uint64_t& aNewSharedID); - void GetOrCreate(nsISHEntry* aSHEntry, MaybeNewPSHEntry* aResult) { - GetOrCreate(Manager(), aSHEntry, *aResult); - } bool RecvCreateLoadInfo(RefPtr<nsDocShellLoadState>* aLoadState); RefPtr<LegacySHEntry> mEntry; }; } // namespace dom } // namespace mozilla
--- a/docshell/shistory/SHistoryChild.cpp +++ b/docshell/shistory/SHistoryChild.cpp @@ -90,26 +90,25 @@ SHistoryChild::GetRequestedIndex(int32_t NS_IMETHODIMP_(void) SHistoryChild::InternalSetRequestedIndex(int32_t aRequestedIndex) { SendInternalSetRequestedIndex(aRequestedIndex); } NS_IMETHODIMP SHistoryChild::GetEntryAtIndex(int32_t aIndex, nsISHEntry** aResult) { nsresult rv; - MaybeNewPSHEntry entry; + RefPtr<CrossProcessSHEntry> entry; if (!SendGetEntryAtIndex(aIndex, &rv, &entry)) { return NS_ERROR_FAILURE; } - RefPtr<SHEntryChild> child; - if (NS_SUCCEEDED(rv)) { - child = SHEntryChild::GetOrCreate(entry); - } - child.forget(aResult); - return rv; + NS_ENSURE_SUCCESS(rv, rv); + + *aResult = entry ? do_AddRef(entry->ToSHEntryChild()).take() : nullptr; + + return NS_OK; } NS_IMETHODIMP SHistoryChild::PurgeHistory(int32_t aNumEntries) { nsresult rv; if (!SendPurgeHistory(aNumEntries, &rv)) { return NS_ERROR_FAILURE; } @@ -240,43 +239,43 @@ SHistoryChild::EvictOutOfRangeContentVie // compare content viewers so we don't evict live content viewers). return SendEvictOutOfRangeContentViewers(aIndex) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP SHistoryChild::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aBFEntry) { SHEntryChildShared* shared = static_cast<SHEntryChildShared*>(aBFEntry); - MaybeNewPSHEntry entry; + RefPtr<CrossProcessSHEntry> entry; int32_t index; if (!SendFindEntryForBFCache(shared->GetID(), false, &entry, &index)) { return NS_ERROR_FAILURE; } - RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry); - if (shEntry) { + RefPtr<SHEntryChild> shEntry; + if (entry && (shEntry = entry->ToSHEntryChild())) { shEntry->EvictContentViewer(); SendEvict(nsTArray<PSHEntryChild*>({shEntry.get()})); } return NS_OK; } NS_IMETHODIMP SHistoryChild::EvictAllContentViewers(void) { - nsTArray<MaybeNewPSHEntry> entries; + nsTArray<RefPtr<CrossProcessSHEntry>> entries; if (!SendGetAllEntries(&entries)) { return NS_ERROR_FAILURE; } // Keep a strong reference to all the entries, we're going to send the array // back to the parent! nsTArray<RefPtr<SHEntryChild>> shEntries(entries.Length()); - for (MaybeNewPSHEntry& entry : entries) { - RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry); + for (RefPtr<CrossProcessSHEntry>& entry : entries) { + RefPtr<SHEntryChild> shEntry = entry->ToSHEntryChild(); shEntry->EvictContentViewer(); shEntries.AppendElement(shEntry.forget()); } nsTArray<PSHEntryChild*> pshEntries; pshEntries.AppendElements(shEntries); SendEvict(pshEntries); return NS_OK; @@ -313,26 +312,26 @@ SHistoryChild::RemoveDynEntries(int32_t NS_IMETHODIMP_(void) SHistoryChild::EnsureCorrectEntryAtCurrIndex(nsISHEntry* aEntry) { SendEnsureCorrectEntryAtCurrIndex(static_cast<SHEntryChild*>(aEntry)); } NS_IMETHODIMP_(void) SHistoryChild::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aBFEntry) { - MaybeNewPSHEntry entry; + RefPtr<CrossProcessSHEntry> entry; int32_t index; if (!SendFindEntryForBFCache( static_cast<SHEntryChildShared*>(aBFEntry)->GetID(), true, &entry, &index)) { return; } - RefPtr<SHEntryChild> shEntry = SHEntryChild::GetOrCreate(entry); - if (shEntry) { + RefPtr<SHEntryChild> shEntry; + if (entry && (shEntry = entry->ToSHEntryChild())) { RemoveDynEntries(index, shEntry); } } NS_IMETHODIMP_(void) SHistoryChild::RemoveEntries(nsTArray<nsID>& aIDs, int32_t aStartIndex) { bool didRemove = false; if (SendRemoveEntries(aIDs, aStartIndex, &didRemove) && didRemove && @@ -359,17 +358,20 @@ SHistoryChild::Reload(uint32_t aReloadFl return LoadURI(loadResult); } nsresult SHistoryChild::LoadURI(LoadSHEntryData& aLoadData) { nsCOMPtr<nsIDocShell> docShell = aLoadData.browsingContext()->GetDocShell(); NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE); - RefPtr<SHEntryChild> entry = SHEntryChild::GetOrCreate(aLoadData.shEntry()); + RefPtr<SHEntryChild> entry; + if (aLoadData.shEntry()) { + entry = aLoadData.shEntry()->ToSHEntryChild(); + } // FIXME Should this be sent through IPC? aLoadData.loadState()->SetSHEntry(entry); return docShell->LoadURI(aLoadData.loadState(), false); } } // namespace dom } // namespace mozilla
--- a/docshell/shistory/SHistoryParent.cpp +++ b/docshell/shistory/SHistoryParent.cpp @@ -22,21 +22,19 @@ LegacySHistory::LegacySHistory(Canonical mIsRemote = true; aRootBC->SetSessionHistory(this); } static void FillInLoadResult(PContentParent* aManager, nsresult aRv, const nsSHistory::LoadEntryResult& aLoadResult, LoadSHEntryResult* aResult) { if (NS_SUCCEEDED(aRv)) { - MaybeNewPSHEntry entry; - static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry()) - ->GetOrCreateActor(aManager, entry); - *aResult = LoadSHEntryData(std::move(entry), aLoadResult.mBrowsingContext, - aLoadResult.mLoadState); + *aResult = LoadSHEntryData( + static_cast<LegacySHEntry*>(aLoadResult.mLoadState->SHEntry()), + aLoadResult.mBrowsingContext, aLoadResult.mLoadState); } else { *aResult = aRv; } } SHistoryParent::SHistoryParent(CanonicalBrowsingContext* aContext) : mContext(aContext), mHistory(new LegacySHistory(aContext, nsID())) {} @@ -62,37 +60,35 @@ bool SHistoryParent::RecvGetRequestedInd } bool SHistoryParent::RecvInternalSetRequestedIndex(int32_t aIndex) { mHistory->InternalSetRequestedIndex(aIndex); return true; } bool SHistoryParent::RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult, - MaybeNewPSHEntry* aEntry) { + RefPtr<CrossProcessSHEntry>* aEntry) { nsCOMPtr<nsISHEntry> entry; *aResult = mHistory->GetEntryAtIndex(aIndex, getter_AddRefs(entry)); - SHEntryParent::GetOrCreate(Manager(), entry, *aEntry); + *aEntry = entry.forget().downcast<LegacySHEntry>(); return true; } bool SHistoryParent::RecvPurgeHistory(int32_t aNumEntries, nsresult* aResult) { *aResult = mHistory->PurgeHistory(aNumEntries); return true; } bool SHistoryParent::RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult) { nsSHistory::LoadEntryResult loadResult; nsresult rv = mHistory->ReloadCurrentEntry(loadResult); if (NS_SUCCEEDED(rv)) { - MaybeNewPSHEntry entry; - SHEntryParent::GetOrCreate(Manager(), loadResult.mLoadState->SHEntry(), - entry); *aLoadResult = LoadSHEntryData( - std::move(entry), loadResult.mBrowsingContext, loadResult.mLoadState); + static_cast<LegacySHEntry*>(loadResult.mLoadState->SHEntry()), + loadResult.mBrowsingContext, loadResult.mLoadState); } else { *aLoadResult = rv; } return true; } bool SHistoryParent::RecvGotoIndex(int32_t aIndex, LoadSHEntryResult* aLoadResult) { @@ -180,54 +176,53 @@ bool SHistoryParent::RecvRemoveFrameEntr bool SHistoryParent::RecvReload(const uint32_t& aReloadFlags, LoadSHEntryResult* aLoadResult) { nsSHistory::LoadEntryResult loadResult; nsresult rv = mHistory->Reload(aReloadFlags, loadResult); FillInLoadResult(Manager(), rv, loadResult, aLoadResult); return true; } -bool SHistoryParent::RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries) { +bool SHistoryParent::RecvGetAllEntries( + nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries) { nsTArray<nsCOMPtr<nsISHEntry>>& entries = mHistory->Entries(); uint32_t length = entries.Length(); aEntries->AppendElements(length); for (uint32_t i = 0; i < length; ++i) { - SHEntryParent::GetOrCreate(Manager(), entries[i].get(), - aEntries->ElementAt(i)); + aEntries->ElementAt(i) = static_cast<LegacySHEntry*>(entries[i].get()); } return true; } -bool SHistoryParent::RecvFindEntryForBFCache(const uint64_t& aSharedID, - const bool& aIncludeCurrentEntry, - MaybeNewPSHEntry* aEntry, - int32_t* aIndex) { +bool SHistoryParent::RecvFindEntryForBFCache( + const uint64_t& aSharedID, const bool& aIncludeCurrentEntry, + RefPtr<CrossProcessSHEntry>* aEntry, int32_t* aIndex) { int32_t currentIndex; mHistory->GetIndex(¤tIndex); int32_t startSafeIndex, endSafeIndex; mHistory->WindowIndices(currentIndex, &startSafeIndex, &endSafeIndex); for (int32_t i = startSafeIndex; i <= endSafeIndex; ++i) { nsCOMPtr<nsISHEntry> entry; nsresult rv = mHistory->GetEntryAtIndex(i, getter_AddRefs(entry)); NS_ENSURE_SUCCESS(rv, false); - if (static_cast<LegacySHEntry*>(entry.get())->GetSharedStateID() == - aSharedID) { + RefPtr<LegacySHEntry> shEntry = entry.forget().downcast<LegacySHEntry>(); + if (shEntry->GetSharedStateID() == aSharedID) { if (!aIncludeCurrentEntry && i == currentIndex) { - *aEntry = (PSHEntryParent*)nullptr; + *aEntry = nullptr; *aIndex = -1; } else { - SHEntryParent::GetOrCreate(Manager(), entry, *aEntry); + *aEntry = shEntry.forget(); *aIndex = i; } return true; } } - *aEntry = (PSHEntryParent*)nullptr; + *aEntry = nullptr; *aIndex = -1; return true; } bool SHistoryParent::RecvEvict(nsTArray<PSHEntryParent*>&& aEntries) { for (PSHEntryParent* entry : aEntries) { int32_t index = mHistory->GetIndexOfEntry(static_cast<SHEntryParent*>(entry)->mEntry);
--- a/docshell/shistory/SHistoryParent.h +++ b/docshell/shistory/SHistoryParent.h @@ -50,17 +50,17 @@ class SHistoryParent final : public PSHi private: bool RecvGetCount(int32_t* aCount); bool RecvGetIndex(int32_t* aIndex); bool RecvSetIndex(int32_t aIndex, nsresult* aResult); bool RecvGetRequestedIndex(int32_t* aIndex); bool RecvInternalSetRequestedIndex(int32_t aIndex); bool RecvGetEntryAtIndex(int32_t aIndex, nsresult* aResult, - MaybeNewPSHEntry* aEntry); + RefPtr<CrossProcessSHEntry>* aEntry); bool RecvPurgeHistory(int32_t aNumEntries, nsresult* aResult); bool RecvReloadCurrentEntry(LoadSHEntryResult* aLoadResult); bool RecvGotoIndex(int32_t aIndex, LoadSHEntryResult* aLoadResult); bool RecvGetIndexOfEntry(PSHEntryParent* aEntry, int32_t* aIndex); bool RecvAddEntry(PSHEntryParent* aEntry, bool aPersist, nsresult* aResult, int32_t* aEntriesPurged); bool RecvUpdateIndex(); bool RecvReplaceEntry(int32_t aIndex, PSHEntryParent* aEntry, @@ -68,20 +68,21 @@ class SHistoryParent final : public PSHi bool RecvNotifyOnHistoryReload(bool* aOk); bool RecvEvictOutOfRangeContentViewers(int32_t aIndex); bool RecvEvictAllContentViewers(); bool RecvRemoveDynEntries(int32_t aIndex, PSHEntryParent* aEntry); bool RecvRemoveEntries(nsTArray<nsID>&& ids, int32_t aIndex, bool* aDidRemove); bool RecvRemoveFrameEntries(PSHEntryParent* aEntry); bool RecvReload(const uint32_t& aReloadFlags, LoadSHEntryResult* aLoadResult); - bool RecvGetAllEntries(nsTArray<MaybeNewPSHEntry>* aEntries); + bool RecvGetAllEntries(nsTArray<RefPtr<CrossProcessSHEntry>>* aEntries); bool RecvFindEntryForBFCache(const uint64_t& aSharedID, const bool& aIncludeCurrentEntry, - MaybeNewPSHEntry* aEntry, int32_t* aIndex); + RefPtr<CrossProcessSHEntry>* aEntry, + int32_t* aIndex); bool RecvEvict(nsTArray<PSHEntryParent*>&& aEntries); bool RecvEnsureCorrectEntryAtCurrIndex(PSHEntryParent* aEntry); bool RecvEvictContentViewersOrReplaceEntry(PSHEntryParent* aNewSHEntry, bool aReplace); bool RecvNotifyListenersContentViewerEvicted(uint32_t aNumEvicted); RefPtr<CanonicalBrowsingContext> mContext; RefPtr<LegacySHistory> mHistory;
--- a/docshell/shistory/moz.build +++ b/docshell/shistory/moz.build @@ -9,38 +9,39 @@ XPIDL_SOURCES += [ 'nsISHEntry.idl', 'nsISHistory.idl', 'nsISHistoryListener.idl', ] XPIDL_MODULE = 'shistory' IPDL_SOURCES += [ - 'NewPSHEntry.ipdlh', 'PSHEntry.ipdl', 'PSHistory.ipdl', ] EXPORTS += [ 'nsSHEntry.h', 'nsSHEntryShared.h', 'nsSHistory.h', ] EXPORTS.mozilla.dom += [ 'ChildSHistory.h', + 'MaybeNewPSHEntry.h', 'ParentSHistory.h', 'SHEntryChild.h', 'SHEntryParent.h', 'SHistoryChild.h', 'SHistoryParent.h', ] UNIFIED_SOURCES += [ 'ChildSHistory.cpp', + 'MaybeNewPSHEntry.cpp', 'nsSHEntry.cpp', 'nsSHEntryShared.cpp', 'nsSHistory.cpp', 'ParentSHistory.cpp', 'SHEntryChild.cpp', 'SHEntryParent.cpp', 'SHistoryChild.cpp', 'SHistoryParent.cpp',
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -61,17 +61,16 @@ include PBackgroundSharedTypes; include PContentPermission; include ServiceWorkerConfiguration; include GraphicsMessages; include MemoryReportTypes; include ClientIPCTypes; include HangTypes; include PrefsTypes; include NeckoChannelParams; -include NewPSHEntry; #if defined(MOZ_SANDBOX) && defined(MOZ_DEBUG) && defined(ENABLE_TESTS) include protocol PSandboxTesting; #endif using refcounted class nsIDOMGeoPosition from "nsGeoPositionIPCSerialiser.h"; using refcounted class nsIAlertNotification from "mozilla/AlertNotificationIPCSerializer.h"; @@ -327,16 +326,22 @@ struct PostMessageData nsString targetOrigin; nsIURI targetOriginURI; nsIPrincipal callerPrincipal; nsIPrincipal subjectPrincipal; nsIURI callerDocumentURI; bool isFromPrivateWindow; }; +union PSHEntryOrSharedID +{ + PSHEntry; + uint64_t; +}; + /** * The PContent protocol is a top-level protocol between the UI process * and a content process. There is exactly one PContentParent/PContentChild pair * for each content process. */ nested(upto inside_cpow) sync protocol PContent { manages PBrowser;