Bug 1675820 - Part 4: Track WindowGlobalChild in WindowContext, r=kmag

This allows for the WindowGlobalChild getter in WindowContext to be acquired
more efficiently without performing hashtable lookups, and should generally
simplify things.

The patch also removes the unnecessary XRE_IsContentProcess assertions, and
removes the global hashtable for tracking WindowGlobalChild instances which is
no longer necessary.

Differential Revision: https://phabricator.services.mozilla.com/D108120
This commit is contained in:
Nika Layzell 2021-03-18 19:24:50 +00:00
Родитель 81bbd0a146
Коммит 0f7f0e91a0
5 изменённых файлов: 36 добавлений и 65 удалений

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

@ -68,11 +68,7 @@ bool WindowContext::IsCached() const {
}
nsGlobalWindowInner* WindowContext::GetInnerWindow() const {
if (mInProcess) {
// FIXME: Replace this with something more efficient.
return nsGlobalWindowInner::GetInnerWindowWithId(mInnerWindowId);
}
return nullptr;
return mWindowGlobalChild ? mWindowGlobalChild->GetWindowGlobal() : nullptr;
}
Document* WindowContext::GetDocument() const {
@ -85,13 +81,6 @@ Document* WindowContext::GetExtantDoc() const {
return innerWindow ? innerWindow->GetExtantDoc() : nullptr;
}
WindowGlobalChild* WindowContext::GetWindowGlobalChild() const {
MOZ_ASSERT(XRE_IsContentProcess());
NS_ENSURE_TRUE(XRE_IsContentProcess(), nullptr);
nsGlobalWindowInner* innerWindow = GetInnerWindow();
return innerWindow ? innerWindow->GetWindowGlobalChild() : nullptr;
}
WindowContext* WindowContext::GetParentWindowContext() {
return mBrowsingContext->GetParentWindowContext();
}
@ -156,7 +145,7 @@ void WindowContext::SendCommitTransaction(ContentChild* aChild,
}
bool WindowContext::CheckOnlyOwningProcessCanSet(ContentParent* aSource) {
if (mInProcess) {
if (IsInProcess()) {
return true;
}
@ -286,12 +275,12 @@ void WindowContext::DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
}
void WindowContext::DidSet(FieldIndex<IDX_UserActivationState>) {
MOZ_ASSERT_IF(!mInProcess, mUserGestureStart.IsNull());
MOZ_ASSERT_IF(!IsInProcess(), mUserGestureStart.IsNull());
USER_ACTIVATION_LOG("Set user gesture activation %" PRIu8
" for %s browsing context 0x%08" PRIx64,
static_cast<uint8_t>(GetUserActivationState()),
XRE_IsParentProcess() ? "Parent" : "Child", Id());
if (mInProcess) {
if (IsInProcess()) {
USER_ACTIVATION_LOG(
"Set user gesture start time for %s browsing context 0x%08" PRIx64,
XRE_IsParentProcess() ? "Parent" : "Child", Id());
@ -336,9 +325,8 @@ void WindowContext::CreateFromIPC(IPCInitializer&& aInit) {
return;
}
RefPtr<WindowContext> context =
new WindowContext(bc, aInit.mInnerWindowId, aInit.mOuterWindowId,
/* aInProcess */ false, std::move(aInit.mFields));
RefPtr<WindowContext> context = new WindowContext(
bc, aInit.mInnerWindowId, aInit.mOuterWindowId, std::move(aInit.mFields));
context->Init();
}
@ -410,7 +398,7 @@ bool WindowContext::HasBeenUserGestureActivated() {
}
bool WindowContext::HasValidTransientUserGestureActivation() {
MOZ_ASSERT(mInProcess);
MOZ_ASSERT(IsInProcess());
if (GetUserActivationState() != UserActivation::State::FullActivated) {
MOZ_ASSERT(mUserGestureStart.IsNull(),
@ -430,7 +418,7 @@ bool WindowContext::HasValidTransientUserGestureActivation() {
}
bool WindowContext::ConsumeTransientUserGestureActivation() {
MOZ_ASSERT(mInProcess);
MOZ_ASSERT(IsInProcess());
MOZ_ASSERT(!IsCached());
if (!HasValidTransientUserGestureActivation()) {
@ -473,12 +461,11 @@ WindowContext::IPCInitializer WindowContext::GetIPCInitializer() {
WindowContext::WindowContext(BrowsingContext* aBrowsingContext,
uint64_t aInnerWindowId, uint64_t aOuterWindowId,
bool aInProcess, FieldValues&& aInit)
FieldValues&& aInit)
: mFields(std::move(aInit)),
mInnerWindowId(aInnerWindowId),
mOuterWindowId(aOuterWindowId),
mBrowsingContext(aBrowsingContext),
mInProcess(aInProcess) {
mBrowsingContext(aBrowsingContext) {
MOZ_ASSERT(mBrowsingContext);
MOZ_ASSERT(mInnerWindowId);
MOZ_ASSERT(mOuterWindowId);
@ -511,12 +498,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WindowContext)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindowGlobalChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WindowContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowsingContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindowGlobalChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

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

@ -107,7 +107,7 @@ class WindowContext : public nsISupports, public nsWrapperCache {
bool IsCached() const;
bool IsInProcess() const { return mInProcess; }
bool IsInProcess() const { return mWindowGlobalChild; }
bool HasBeforeUnload() const { return GetHasBeforeUnload(); }
@ -117,7 +117,7 @@ class WindowContext : public nsISupports, public nsWrapperCache {
Document* GetDocument() const;
Document* GetExtantDoc() const;
WindowGlobalChild* GetWindowGlobalChild() const;
WindowGlobalChild* GetWindowGlobalChild() const { return mWindowGlobalChild; }
// Get the parent WindowContext of this WindowContext, taking the BFCache into
// account. This will not cross chrome/content <browser> boundaries.
@ -183,8 +183,7 @@ class WindowContext : public nsISupports, public nsWrapperCache {
protected:
WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
uint64_t aOuterWindowId, bool aInProcess,
FieldValues&& aFields);
uint64_t aOuterWindowId, FieldValues&& aFields);
virtual ~WindowContext();
virtual void Init();
@ -287,6 +286,7 @@ class WindowContext : public nsISupports, public nsWrapperCache {
const uint64_t mInnerWindowId;
const uint64_t mOuterWindowId;
RefPtr<BrowsingContext> mBrowsingContext;
RefPtr<WindowGlobalChild> mWindowGlobalChild;
// --- NEVER CHANGE `mChildren` DIRECTLY! ---
// Changes to this list need to be synchronized to the list within our
@ -295,7 +295,6 @@ class WindowContext : public nsISupports, public nsWrapperCache {
nsTArray<RefPtr<BrowsingContext>> mChildren;
bool mIsDiscarded = false;
bool mInProcess = false;
// The start time of user gesture, this is only available if the window
// context is in process.

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

@ -50,9 +50,6 @@ using namespace mozilla::dom::ipc;
namespace mozilla::dom {
typedef nsRefPtrHashtable<nsUint64HashKey, WindowGlobalChild> WGCByIdMap;
static StaticAutoPtr<WGCByIdMap> gWindowGlobalChildById;
WindowGlobalChild::WindowGlobalChild(dom::WindowContext* aWindowContext,
nsIPrincipal* aPrincipal,
nsIURI* aDocumentURI)
@ -148,33 +145,23 @@ already_AddRefed<WindowGlobalChild> WindowGlobalChild::CreateDisconnected(
// Create our new WindowContext
if (XRE_IsParentProcess()) {
windowContext =
WindowGlobalParent::CreateDisconnected(aInit, /* aInProcess */ true);
windowContext = WindowGlobalParent::CreateDisconnected(aInit);
} else {
dom::WindowContext::FieldValues fields = aInit.context().mFields;
windowContext =
new dom::WindowContext(browsingContext, aInit.context().mInnerWindowId,
aInit.context().mOuterWindowId,
/* aInProcess */ true, std::move(fields));
windowContext = new dom::WindowContext(
browsingContext, aInit.context().mInnerWindowId,
aInit.context().mOuterWindowId, std::move(fields));
}
RefPtr<WindowGlobalChild> windowChild = new WindowGlobalChild(
windowContext, aInit.principal(), aInit.documentURI());
windowContext->mWindowGlobalChild = windowChild;
return windowChild.forget();
}
void WindowGlobalChild::Init() {
MOZ_ASSERT(mWindowContext->mWindowGlobalChild == this);
mWindowContext->Init();
// Register this WindowGlobal in the gWindowGlobalParentsById map.
if (!gWindowGlobalChildById) {
gWindowGlobalChildById = new WGCByIdMap();
ClearOnShutdown(&gWindowGlobalChildById);
}
gWindowGlobalChildById->WithEntryHandle(InnerWindowId(), [&](auto&& entry) {
MOZ_RELEASE_ASSERT(!entry, "Duplicate WindowGlobalChild entry for ID!");
entry.Insert(this);
});
}
void WindowGlobalChild::InitWindowGlobal(nsGlobalWindowInner* aWindow) {
@ -264,10 +251,11 @@ void WindowGlobalChild::OnNewDocument(Document* aDocument) {
/* static */
already_AddRefed<WindowGlobalChild> WindowGlobalChild::GetByInnerWindowId(
uint64_t aInnerWindowId) {
if (!gWindowGlobalChildById) {
return nullptr;
if (RefPtr<dom::WindowContext> context =
dom::WindowContext::GetById(aInnerWindowId)) {
return do_AddRef(context->GetWindowGlobalChild());
}
return gWindowGlobalChildById->Get(aInnerWindowId);
return nullptr;
}
dom::BrowsingContext* WindowGlobalChild::BrowsingContext() {
@ -645,8 +633,6 @@ void WindowGlobalChild::ActorDestroy(ActorDestroyReason aWhy) {
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript(),
"Destroying WindowGlobalChild can run script");
gWindowGlobalChildById->Remove(InnerWindowId());
// If our WindowContext hasn't been marked as discarded yet, ensure it's
// marked as discarded at this point.
mWindowContext->Discard();
@ -676,10 +662,7 @@ bool WindowGlobalChild::SameOriginWithTop() {
return IsSameOriginWith(WindowContext()->TopWindowContext());
}
WindowGlobalChild::~WindowGlobalChild() {
MOZ_ASSERT(!gWindowGlobalChildById ||
!gWindowGlobalChildById->Contains(InnerWindowId()));
}
WindowGlobalChild::~WindowGlobalChild() = default;
JSObject* WindowGlobalChild::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) {
@ -691,7 +674,7 @@ nsISupports* WindowGlobalChild::GetParentObject() {
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WindowGlobalChild, mWindowGlobal,
mContainerFeaturePolicy)
mContainerFeaturePolicy, mWindowContext)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WindowGlobalChild)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY

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

@ -69,9 +69,9 @@ namespace mozilla::dom {
WindowGlobalParent::WindowGlobalParent(
CanonicalBrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
uint64_t aOuterWindowId, bool aInProcess, FieldValues&& aInit)
uint64_t aOuterWindowId, FieldValues&& aInit)
: WindowContext(aBrowsingContext, aInnerWindowId, aOuterWindowId,
aInProcess, std::move(aInit)),
std::move(aInit)),
mIsInitialDocument(false),
mSandboxFlags(0),
mDocumentHasLoaded(false),
@ -82,7 +82,7 @@ WindowGlobalParent::WindowGlobalParent(
}
already_AddRefed<WindowGlobalParent> WindowGlobalParent::CreateDisconnected(
const WindowGlobalInit& aInit, bool aInProcess) {
const WindowGlobalInit& aInit) {
RefPtr<CanonicalBrowsingContext> browsingContext =
CanonicalBrowsingContext::Get(aInit.context().mBrowsingContextId);
if (NS_WARN_IF(!browsingContext)) {
@ -94,9 +94,9 @@ already_AddRefed<WindowGlobalParent> WindowGlobalParent::CreateDisconnected(
MOZ_RELEASE_ASSERT(!wgp, "Creating duplicate WindowGlobalParent");
FieldValues fields(aInit.context().mFields);
wgp = new WindowGlobalParent(browsingContext, aInit.context().mInnerWindowId,
aInit.context().mOuterWindowId, aInProcess,
std::move(fields));
wgp =
new WindowGlobalParent(browsingContext, aInit.context().mInnerWindowId,
aInit.context().mOuterWindowId, std::move(fields));
wgp->mDocumentPrincipal = aInit.principal();
wgp->mDocumentURI = aInit.documentURI();
wgp->mBlockAllMixedContent = aInit.blockAllMixedContent();

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

@ -153,7 +153,7 @@ class WindowGlobalParent final : public WindowContext,
already_AddRefed<Promise> GetSecurityInfo(ErrorResult& aRv);
static already_AddRefed<WindowGlobalParent> CreateDisconnected(
const WindowGlobalInit& aInit, bool aInProcess = false);
const WindowGlobalInit& aInit);
// Initialize the mFrameLoader fields for a created WindowGlobalParent. Must
// be called after setting the Manager actor.
@ -264,7 +264,7 @@ class WindowGlobalParent final : public WindowContext,
private:
WindowGlobalParent(CanonicalBrowsingContext* aBrowsingContext,
uint64_t aInnerWindowId, uint64_t aOuterWindowId,
bool aInProcess, FieldValues&& aInit);
FieldValues&& aInit);
~WindowGlobalParent();