Bug 1516240 - Part 3: Directly pass BrowsingContext over IPC when possible, r=farre
authorNika Layzell <nika@thelayzells.com>
Wed, 13 Feb 2019 21:02:55 +0000
changeset 458958 324d25d3f933
parent 458957 e4bc2ad58acf
child 458959 53d7d4732ab9
push id35552
push usershindli@mozilla.com
push dateThu, 14 Feb 2019 04:39:44 +0000
treeherdermozilla-central@c6829642e2d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1516240
milestone67.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
Bug 1516240 - Part 3: Directly pass BrowsingContext over IPC when possible, r=farre This patch changes the logic such that we use the new direct BrowsingContext ParamTraits implementation when possible, and avoids doing manual lookups. Depends on D19178 Differential Revision: https://phabricator.services.mozilla.com/D19179
docshell/base/BrowsingContext.cpp
docshell/base/BrowsingContext.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/DOMTypes.ipdlh
dom/ipc/PBrowser.ipdl
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
dom/ipc/WindowGlobalChild.cpp
dom/ipc/WindowGlobalParent.cpp
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -59,18 +59,17 @@ static void Sync(BrowsingContext* aBrows
   if (!XRE_IsContentProcess()) {
     return;
   }
 
   auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
   RefPtr<BrowsingContext> parent = aBrowsingContext->GetParent();
   BrowsingContext* opener = aBrowsingContext->GetOpener();
-  cc->SendAttachBrowsingContext(BrowsingContextId(parent ? parent->Id() : 0),
-                                BrowsingContextId(opener ? opener->Id() : 0),
+  cc->SendAttachBrowsingContext(parent, opener,
                                 BrowsingContextId(aBrowsingContext->Id()),
                                 aBrowsingContext->Name());
 }
 
 BrowsingContext* BrowsingContext::TopLevelBrowsingContext() {
   BrowsingContext* bc = this;
   while (bc->mParent) {
     bc = bc->mParent;
@@ -98,16 +97,20 @@ BrowsingContext* BrowsingContext::TopLev
     uint64_t aId) {
   if (BrowsingContextMap<WeakPtr>::Ptr abc = sBrowsingContexts->lookup(aId)) {
     return do_AddRef(abc->value().get());
   }
 
   return nullptr;
 }
 
+CanonicalBrowsingContext* BrowsingContext::Canonical() {
+  return CanonicalBrowsingContext::Cast(this);
+}
+
 /* static */ already_AddRefed<BrowsingContext> BrowsingContext::Create(
     BrowsingContext* aParent, BrowsingContext* aOpener, const nsAString& aName,
     Type aType) {
   MOZ_DIAGNOSTIC_ASSERT(!aParent || aParent->mType == aType);
 
   uint64_t id = nsContentUtils::GenerateBrowsingContextId();
 
   MOZ_LOG(GetLog(), LogLevel::Debug,
@@ -233,18 +236,17 @@ void BrowsingContext::Detach() {
   Group()->Unregister(this);
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
   auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
-  cc->SendDetachBrowsingContext(BrowsingContextId(Id()),
-                                false /* aMoveToBFCache */);
+  cc->SendDetachBrowsingContext(this, false /* aMoveToBFCache */);
 }
 
 void BrowsingContext::CacheChildren() {
   if (mChildren.IsEmpty()) {
     return;
   }
 
   MOZ_LOG(GetLog(), LogLevel::Debug,
@@ -259,18 +261,17 @@ void BrowsingContext::CacheChildren() {
   mChildren.Clear();
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
   auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
-  cc->SendDetachBrowsingContext(BrowsingContextId(Id()),
-                                true /* aMoveToBFCache */);
+  cc->SendDetachBrowsingContext(this, true /* aMoveToBFCache */);
 }
 
 bool BrowsingContext::IsCached() { return sCachedBrowsingContexts->has(Id()); }
 
 void BrowsingContext::GetChildren(
     nsTArray<RefPtr<BrowsingContext>>& aChildren) {
   MOZ_ALWAYS_TRUE(aChildren.AppendElements(mChildren));
 }
@@ -283,18 +284,17 @@ void BrowsingContext::SetOpener(Browsing
   mOpener = aOpener;
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
   auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
-  cc->SendSetOpenerBrowsingContext(
-      BrowsingContextId(Id()), BrowsingContextId(aOpener ? aOpener->Id() : 0));
+  cc->SendSetOpenerBrowsingContext(this, aOpener);
 }
 
 BrowsingContext::~BrowsingContext() {
   MOZ_DIAGNOSTIC_ASSERT(!mParent || !mParent->mChildren.Contains(this));
   MOZ_DIAGNOSTIC_ASSERT(!mGroup || !mGroup->Toplevels().Contains(this));
   MOZ_DIAGNOSTIC_ASSERT(!sCachedBrowsingContexts ||
                         !sCachedBrowsingContexts->has(Id()));
 
@@ -321,34 +321,34 @@ void BrowsingContext::NotifyUserGestureA
                       topLevelBC->Id());
   topLevelBC->SetUserGestureActivation();
 
   if (!XRE_IsContentProcess()) {
     return;
   }
   auto cc = ContentChild::GetSingleton();
   MOZ_ASSERT(cc);
-  cc->SendSetUserGestureActivation(BrowsingContextId(topLevelBC->Id()), true);
+  cc->SendSetUserGestureActivation(topLevelBC, true);
 }
 
 void BrowsingContext::NotifyResetUserGestureActivation() {
   // We would reset the user gesture activation flag on the top level browsing
   // context, which would automatically be sync to other top level browsing
   // contexts which are in the different process.
   RefPtr<BrowsingContext> topLevelBC = TopLevelBrowsingContext();
   USER_ACTIVATION_LOG("Get top level browsing context 0x%08" PRIx64,
                       topLevelBC->Id());
   topLevelBC->ResetUserGestureActivation();
 
   if (!XRE_IsContentProcess()) {
     return;
   }
   auto cc = ContentChild::GetSingleton();
   MOZ_ASSERT(cc);
-  cc->SendSetUserGestureActivation(BrowsingContextId(topLevelBC->Id()), false);
+  cc->SendSetUserGestureActivation(topLevelBC, false);
 }
 
 void BrowsingContext::SetUserGestureActivation() {
   MOZ_ASSERT(!mParent, "Set user activation flag on non top-level context!");
   USER_ACTIVATION_LOG(
       "Set user gesture activation for browsing context 0x%08" PRIx64, Id());
   mIsActivatedByUserGesture = true;
 }
@@ -392,28 +392,27 @@ void BrowsingContext::Location(JSContext
                                OOMReporter& aError) {}
 
 void BrowsingContext::Close(CallerType aCallerType, ErrorResult& aError) {
   // FIXME We need to set mClosed, but only once we're sending the
   //       DOMWindowClose event (which happens in the process where the
   //       document for this browsing context is loaded).
   //       See https://bugzilla.mozilla.org/show_bug.cgi?id=1516343.
   ContentChild* cc = ContentChild::GetSingleton();
-  cc->SendWindowClose(BrowsingContextId(mBrowsingContextId),
-                      aCallerType == CallerType::System);
+  cc->SendWindowClose(this, aCallerType == CallerType::System);
 }
 
 void BrowsingContext::Focus(ErrorResult& aError) {
   ContentChild* cc = ContentChild::GetSingleton();
-  cc->SendWindowFocus(BrowsingContextId(mBrowsingContextId));
+  cc->SendWindowFocus(this);
 }
 
 void BrowsingContext::Blur(ErrorResult& aError) {
   ContentChild* cc = ContentChild::GetSingleton();
-  cc->SendWindowBlur(BrowsingContextId(mBrowsingContextId));
+  cc->SendWindowBlur(this);
 }
 
 Nullable<WindowProxyHolder> BrowsingContext::GetTop(ErrorResult& aError) {
   // We never return null or throw an error, but the implementation in
   // nsGlobalWindow does and we need to use the same signature.
   return WindowProxyHolder(TopLevelBrowsingContext());
 }
 
@@ -455,17 +454,17 @@ void BrowsingContext::PostMessageMoz(JSC
   if (!nsGlobalWindowOuter::GatherPostMessageData(
           aCx, aTargetOrigin, getter_AddRefs(sourceBc), data.origin(),
           getter_AddRefs(data.targetOriginURI()),
           getter_AddRefs(data.callerPrincipal()),
           getter_AddRefs(callerInnerWindow),
           getter_AddRefs(data.callerDocumentURI()), aError)) {
     return;
   }
-  data.source() = BrowsingContextId(sourceBc->Id());
+  data.source() = sourceBc;
   data.isFromPrivateWindow() =
       callerInnerWindow &&
       nsScriptErrorBase::ComputeIsFromPrivateWindow(callerInnerWindow);
 
   JS::Rooted<JS::Value> transferArray(aCx);
   aError = nsContentUtils::CreateJSValueFromSequenceOfObject(aCx, aTransfer,
                                                              &transferArray);
   if (NS_WARN_IF(aError.Failed())) {
@@ -480,18 +479,17 @@ void BrowsingContext::PostMessageMoz(JSC
 
   ContentChild* cc = ContentChild::GetSingleton();
   ClonedMessageData messageData;
   if (!message.BuildClonedMessageDataForChild(cc, messageData)) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
-  cc->SendWindowPostMessage(BrowsingContextId(mBrowsingContextId), messageData,
-                            data);
+  cc->SendWindowPostMessage(this, messageData, data);
 }
 
 void BrowsingContext::PostMessageMoz(JSContext* aCx,
                                      JS::Handle<JS::Value> aMessage,
                                      const WindowPostMessageOptions& aOptions,
                                      nsIPrincipal& aSubjectPrincipal,
                                      ErrorResult& aError) {
   PostMessageMoz(aCx, aMessage, aOptions.mTargetOrigin, aOptions.mTransfer,
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -37,16 +37,17 @@ class IProtocol;
 
 template <typename T>
 struct IPDLParamTraits;
 }  // namespace ipc
 
 namespace dom {
 
 class BrowsingContextGroup;
+class CanonicalBrowsingContext;
 class ContentParent;
 template <typename>
 struct Nullable;
 template <typename T>
 class Sequence;
 struct WindowPostMessageOptions;
 class WindowProxyHolder;
 
@@ -88,16 +89,19 @@ class BrowsingContext : public nsWrapper
                                                   const nsAString& aName,
                                                   Type aType);
 
   // Create a BrowsingContext object from over IPC.
   static already_AddRefed<BrowsingContext> CreateFromIPC(
       BrowsingContext* aParent, BrowsingContext* aOpener,
       const nsAString& aName, uint64_t aId, ContentParent* aOriginProcess);
 
+  // Cast this object to a canonical browsing context, and return it.
+  CanonicalBrowsingContext* Canonical();
+
   // Get the DocShell for this BrowsingContext if it is in-process, or
   // null if it's not.
   nsIDocShell* GetDocShell() { return mDocShell; }
   void SetDocShell(nsIDocShell* aDocShell);
 
   // Get the outer window object for this BrowsingContext if it is in-process
   // and still has a docshell, or null otherwise.
   nsPIDOMWindowOuter* GetDOMWindow() const {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3585,90 +3585,76 @@ PContentChild::Result ContentChild::OnMe
 
     LSObject::OnSyncMessageHandled();
   }
 
   return result;
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvWindowClose(
-    const BrowsingContextId& aContextId, const bool& aTrustedCaller) {
-  RefPtr<BrowsingContext> bc = BrowsingContext::Get(aContextId);
-  if (!bc) {
+    BrowsingContext* aContext, bool aTrustedCaller) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ChildIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ChildIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
-  nsCOMPtr<nsPIDOMWindowOuter> window = bc->GetDOMWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
   nsGlobalWindowOuter::Cast(window)->CloseOuter(aTrustedCaller);
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult ContentChild::RecvWindowFocus(
-    const BrowsingContextId& aContextId) {
-  RefPtr<BrowsingContext> bc = BrowsingContext::Get(aContextId);
-  if (!bc) {
+mozilla::ipc::IPCResult ContentChild::RecvWindowFocus(BrowsingContext* aContext) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ChildIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ChildIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
-  nsCOMPtr<nsPIDOMWindowOuter> window = bc->GetDOMWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
   nsGlobalWindowOuter::Cast(window)->FocusOuter();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvWindowBlur(
-    const BrowsingContextId& aContextId) {
-  RefPtr<BrowsingContext> bc = BrowsingContext::Get(aContextId);
-  if (!bc) {
+    BrowsingContext* aContext) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ChildIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ChildIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
-  nsCOMPtr<nsPIDOMWindowOuter> window = bc->GetDOMWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> window = aContext->GetDOMWindow();
   nsGlobalWindowOuter::Cast(window)->BlurOuter();
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentChild::RecvWindowPostMessage(
-    const BrowsingContextId& aContextId, const ClonedMessageData& aMessage,
+    BrowsingContext* aContext, const ClonedMessageData& aMessage,
     const PostMessageData& aData) {
-  RefPtr<BrowsingContext> bc = BrowsingContext::Get(aContextId);
-  if (!bc) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ChildIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ChildIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
   RefPtr<nsGlobalWindowOuter> window =
-      nsGlobalWindowOuter::Cast(bc->GetDOMWindow());
+      nsGlobalWindowOuter::Cast(aContext->GetDOMWindow());
   nsCOMPtr<nsIPrincipal> providedPrincipal;
   if (!window->GetPrincipalForPostMessage(
           aData.targetOrigin(), aData.targetOriginURI(),
           aData.callerPrincipal(), *aData.subjectPrincipal(),
           getter_AddRefs(providedPrincipal))) {
     return IPC_OK();
   }
 
-  RefPtr<BrowsingContext> sourceBc = BrowsingContext::Get(aData.source());
+  RefPtr<BrowsingContext> sourceBc = aData.source();
   if (!sourceBc) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ChildIPC: Trying to use a dead or detached context 0x%08" PRIx64,
-             (uint64_t)aData.source()));
+            ("ChildIPC: Trying to use a dead or detached context"));
     return IPC_OK();
   }
 
   // Create and asynchronously dispatch a runnable which will handle actual DOM
   // event creation and dispatch.
   RefPtr<PostMessageEvent> event = new PostMessageEvent(
       sourceBc, aData.origin(), window, providedPrincipal,
       aData.callerDocumentURI(), aData.isFromPrivateWindow());
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -709,22 +709,22 @@ class ContentChild final : public PConte
   virtual already_AddRefed<nsIEventTarget> GetConstructedEventTarget(
       const Message& aMsg) override;
 
   virtual already_AddRefed<nsIEventTarget> GetSpecificMessageEventTarget(
       const Message& aMsg) override;
 
   virtual void OnChannelReceivedMessage(const Message& aMsg) override;
 
-  mozilla::ipc::IPCResult RecvWindowClose(const BrowsingContextId& aContextId,
-                                          const bool& aTrustedCaller);
-  mozilla::ipc::IPCResult RecvWindowFocus(const BrowsingContextId& aContextId);
-  mozilla::ipc::IPCResult RecvWindowBlur(const BrowsingContextId& aContextId);
+  mozilla::ipc::IPCResult RecvWindowClose(BrowsingContext* aContext,
+                                          bool aTrustedCaller);
+  mozilla::ipc::IPCResult RecvWindowFocus(BrowsingContext* aContext);
+  mozilla::ipc::IPCResult RecvWindowBlur(BrowsingContext* aContext);
   mozilla::ipc::IPCResult RecvWindowPostMessage(
-      const BrowsingContextId& aContextId, const ClonedMessageData& aMessage,
+      BrowsingContext* aContext, const ClonedMessageData& aMessage,
       const PostMessageData& aData);
 
 #ifdef NIGHTLY_BUILD
   virtual PContentChild::Result OnMessageReceived(const Message& aMsg) override;
 #else
   using PContentChild::OnMessageReceived;
 #endif
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5604,165 +5604,128 @@ ContentParent::RecvFirstPartyStorageAcce
 
 mozilla::ipc::IPCResult ContentParent::RecvStoreUserInteractionAsPermission(
     const Principal& aPrincipal) {
   AntiTrackingCommon::StoreUserInteractionFor(aPrincipal);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvAttachBrowsingContext(
-    const BrowsingContextId& aParentId, const BrowsingContextId& aOpenerId,
-    const BrowsingContextId& aChildId, const nsString& aName) {
-  RefPtr<CanonicalBrowsingContext> parent =
-      CanonicalBrowsingContext::Get(aParentId);
-  if (aParentId && !parent) {
-    // Unless 'aParentId' is 0 (which it is when the child is a root
-    // BrowsingContext) there should always be a corresponding
-    // 'parent'. The only reason for there not beeing one is if the
-    // parent has already been detached, in which case the
-    // BrowsingContext that tries to attach itself to the context with
-    // 'aParentId' is surely doomed and we can safely do nothing.
-
-    // TODO(farre): When we start syncing/moving BrowsingContexts to
-    // other child processes is it possible to get into races where
-    // constructive operations on already detached BrowsingContexts
-    // are requested? This needs to be answered/handled, but for now
-    // return early. [Bug 1471598]
-    MOZ_LOG(
-        BrowsingContext::GetLog(), LogLevel::Debug,
-        ("ParentIPC: Trying to attach to already detached parent 0x%08" PRIx64,
-         (uint64_t)aParentId));
-    return IPC_OK();
-  }
-
-  if (parent && !parent->IsOwnedByProcess(ChildID())) {
+    BrowsingContext* aParent, BrowsingContext* aOpener,
+    BrowsingContextId aChildId, const nsString& aName) {
+  if (aParent && !aParent->Canonical()->IsOwnedByProcess(ChildID())) {
     // Where trying attach a child BrowsingContext to a parent
     // BrowsingContext in another process. This is illegal since the
     // only thing that could create that child BrowsingContext is a
     // parent docshell in the same process as that BrowsingContext.
 
     // TODO(farre): We're doing nothing now, but is that exactly what
     // we want? Maybe we want to crash the child currently calling
     // SendAttachBrowsingContext and/or the child that originally
     // called SendAttachBrowsingContext or possibly all children that
     // has a BrowsingContext connected to the child that currently
     // called SendAttachBrowsingContext? [Bug 1471598]
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to attach to out of process parent context "
              "0x%08" PRIx64,
-             parent->Id()));
+             aParent->Id()));
     return IPC_OK();
   }
 
   RefPtr<BrowsingContext> child = BrowsingContext::Get(aChildId);
   if (child && !child->IsCached()) {
     // This is highly suspicious. BrowsingContexts should only be
     // attached at most once, but finding one indicates that someone
     // is doing something they shouldn't.
 
     // TODO(farre): To crash or not to crash. Same reasoning as in
     // above TODO. [Bug 1471598]
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to attach already attached 0x%08" PRIx64
              " to 0x%08" PRIx64,
-             child->Id(), (uint64_t)aParentId));
+             child->Id(), aParent ? aParent->Id() : 0));
     return IPC_OK();
   }
 
   if (!child) {
-    RefPtr<BrowsingContext> opener = BrowsingContext::Get(aOpenerId);
-    child = BrowsingContext::CreateFromIPC(parent, opener, aName,
+    child = BrowsingContext::CreateFromIPC(aParent, aOpener, aName,
                                            (uint64_t)aChildId, this);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvDetachBrowsingContext(
-    const BrowsingContextId& aContextId, const bool& aMoveToBFCache) {
-  RefPtr<CanonicalBrowsingContext> context =
-      CanonicalBrowsingContext::Get(aContextId);
-
-  if (!context) {
+    BrowsingContext* aContext, bool aMoveToBFCache) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to detach already detached 0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ParentIPC: Trying to detach already detached"));
     return IPC_OK();
   }
 
-  if (!context->IsOwnedByProcess(ChildID())) {
+  if (!aContext->Canonical()->IsOwnedByProcess(ChildID())) {
     // Where trying to detach a child BrowsingContext in another child
     // process. This is illegal since the owner of the BrowsingContext
     // is the proccess with the in-process docshell, which is tracked
     // by OwnerProcessId.
 
     // TODO(farre): To crash or not to crash. Same reasoning as in
     // above TODO. [Bug 1471598]
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to detach out of process context 0x%08" PRIx64,
-             context->Id()));
+             aContext->Id()));
     return IPC_OK();
   }
 
   if (aMoveToBFCache) {
-    context->CacheChildren();
+    aContext->CacheChildren();
   } else {
-    context->Detach();
+    aContext->Detach();
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvSetOpenerBrowsingContext(
-    const BrowsingContextId& aContextId,
-    const BrowsingContextId& aOpenerContextId) {
-  RefPtr<CanonicalBrowsingContext> context =
-      CanonicalBrowsingContext::Get(aContextId);
-
-  if (!context) {
+    BrowsingContext* aContext, BrowsingContext* aOpener) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to set opener already detached 0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ParentIPC: Trying to set opener already detached"));
     return IPC_OK();
   }
 
-  if (!context->IsOwnedByProcess(ChildID())) {
+  if (!aContext->Canonical()->IsOwnedByProcess(ChildID())) {
     // Where trying to set opener on a child BrowsingContext in
     // another child process. This is illegal since the owner of the
     // BrowsingContext is the proccess with the in-process docshell,
     // which is tracked by OwnerProcessId.
 
     // TODO(farre): To crash or not to crash. Same reasoning as in
     // above TODO. [Bug 1471598]
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to set opener on out of process context "
              "0x%08" PRIx64,
-             context->Id()));
+             aContext->Id()));
     return IPC_OK();
   }
 
-  RefPtr<BrowsingContext> opener = BrowsingContext::Get(aOpenerContextId);
-  context->SetOpener(opener);
+  aContext->SetOpener(aOpener);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvSetUserGestureActivation(
-    const BrowsingContextId& aContextId, const bool& aNewValue) {
-  RefPtr<CanonicalBrowsingContext> context =
-      CanonicalBrowsingContext::Get(aContextId);
-
-  if (!context) {
+    BrowsingContext* aContext, bool aNewValue) {
+  if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to activate wrong context 0x%08" PRIx64,
-             (uint64_t)aContextId));
+            ("ParentIPC: Trying to activate wrong context"));
     return IPC_OK();
   }
 
-  context->NotifySetUserGestureActivationFromIPC(aNewValue);
+  aContext->Canonical()->NotifySetUserGestureActivationFromIPC(aNewValue);
   return IPC_OK();
 }
 
 void ContentParent::RegisterRemoteWorkerActor() { ++mRemoteWorkerActors; }
 
 void ContentParent::UnregisterRemoveWorkerActor() {
   MOZ_ASSERT(NS_IsMainThread());
 
@@ -5777,100 +5740,88 @@ void ContentParent::UnregisterRemoveWork
     // allow it to perform shutdown tasks.
     MessageLoop::current()->PostTask(NewRunnableMethod<ShutDownMethod>(
         "dom::ContentParent::ShutDownProcess", this,
         &ContentParent::ShutDownProcess, SEND_SHUTDOWN_MESSAGE));
   }
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvWindowClose(
-    const BrowsingContextId& aContextId, const bool& aTrustedCaller) {
-  RefPtr<CanonicalBrowsingContext> bc =
-      CanonicalBrowsingContext::Get(aContextId);
-  if (!bc) {
-    MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+    BrowsingContext* aContext, bool aTrustedCaller) {
+  if (!aContext) {
+    MOZ_LOG(
+        BrowsingContext::GetLog(), LogLevel::Debug,
+        ("ParentIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
   // FIXME Need to check that the sending process has access to the unit of
   // related
   //       browsing contexts of bc.
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
-  ContentParent* cp =
-      cpm->GetContentProcessById(ContentParentId(bc->OwnerProcessId()));
-  Unused << cp->SendWindowClose(aContextId, aTrustedCaller);
+  ContentParent* cp = cpm->GetContentProcessById(
+      ContentParentId(aContext->Canonical()->OwnerProcessId()));
+  Unused << cp->SendWindowClose(aContext, aTrustedCaller);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvWindowFocus(
-    const BrowsingContextId& aContextId) {
-  RefPtr<CanonicalBrowsingContext> bc =
-      CanonicalBrowsingContext::Get(aContextId);
-  if (!bc) {
-    MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+    BrowsingContext* aContext) {
+  if (!aContext) {
+    MOZ_LOG(
+        BrowsingContext::GetLog(), LogLevel::Debug,
+        ("ParentIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
-  ContentParent* cp =
-      cpm->GetContentProcessById(ContentParentId(bc->OwnerProcessId()));
-  Unused << cp->SendWindowFocus(aContextId);
+  ContentParent* cp = cpm->GetContentProcessById(
+      ContentParentId(aContext->Canonical()->OwnerProcessId()));
+  Unused << cp->SendWindowFocus(aContext);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvWindowBlur(
-    const BrowsingContextId& aContextId) {
-  RefPtr<CanonicalBrowsingContext> bc =
-      CanonicalBrowsingContext::Get(aContextId);
-  if (!bc) {
-    MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+    BrowsingContext* aContext) {
+  if (!aContext) {
+    MOZ_LOG(
+        BrowsingContext::GetLog(), LogLevel::Debug,
+        ("ParentIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
-  ContentParent* cp =
-      cpm->GetContentProcessById(ContentParentId(bc->OwnerProcessId()));
-  Unused << cp->SendWindowBlur(aContextId);
+  ContentParent* cp = cpm->GetContentProcessById(
+      ContentParentId(aContext->Canonical()->OwnerProcessId()));
+  Unused << cp->SendWindowBlur(aContext);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvWindowPostMessage(
-    const BrowsingContextId& aContextId, const ClonedMessageData& aMessage,
+    BrowsingContext* aContext, const ClonedMessageData& aMessage,
     const PostMessageData& aData) {
-  RefPtr<CanonicalBrowsingContext> bc =
-      CanonicalBrowsingContext::Get(aContextId);
-  if (!bc) {
-    MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
-            ("ParentIPC: Trying to send a message to dead or detached context "
-             "0x%08" PRIx64,
-             (uint64_t)aContextId));
+  if (!aContext) {
+    MOZ_LOG(
+        BrowsingContext::GetLog(), LogLevel::Debug,
+        ("ParentIPC: Trying to send a message to dead or detached context"));
     return IPC_OK();
   }
 
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
-  ContentParent* cp =
-      cpm->GetContentProcessById(ContentParentId(bc->OwnerProcessId()));
+  ContentParent* cp = cpm->GetContentProcessById(
+      ContentParentId(aContext->Canonical()->OwnerProcessId()));
   StructuredCloneData messageFromChild;
   UnpackClonedMessageDataForParent(aMessage, messageFromChild);
   ClonedMessageData message;
   if (!BuildClonedMessageDataForParent(cp, messageFromChild, message)) {
     // FIXME Logging?
     return IPC_OK();
   }
-  Unused << cp->SendWindowPostMessage(aContextId, message, aData);
+  Unused << cp->SendWindowPostMessage(aContext, message, aData);
   return IPC_OK();
 }
 
 }  // namespace dom
 }  // namespace mozilla
 
 NS_IMPL_ISUPPORTS(ParentIdleListener, nsIObserver)
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -613,37 +613,35 @@ class ContentParent final : public PCont
 
   // Control the priority of the IPC messages for input events.
   void SetInputPriorityEventEnabled(bool aEnabled);
   bool IsInputPriorityEventEnabled() { return mIsInputPriorityEventEnabled; }
 
   static bool IsInputEventQueueSupported();
 
   mozilla::ipc::IPCResult RecvAttachBrowsingContext(
-      const BrowsingContextId& aParentContextId,
-      const BrowsingContextId& aOpenerId, const BrowsingContextId& aContextId,
-      const nsString& aName);
+      BrowsingContext* aParentContext, BrowsingContext* aOpener,
+      BrowsingContextId aContextId, const nsString& aName);
 
-  mozilla::ipc::IPCResult RecvDetachBrowsingContext(
-      const BrowsingContextId& aContextId, const bool& aMoveToBFCache);
+  mozilla::ipc::IPCResult RecvDetachBrowsingContext(BrowsingContext* aContext,
+                                                    bool aMoveToBFCache);
 
   mozilla::ipc::IPCResult RecvSetOpenerBrowsingContext(
-      const BrowsingContextId& aContextId,
-      const BrowsingContextId& aOpenerContextId);
+      BrowsingContext* aContext, BrowsingContext* aOpener);
 
-  mozilla::ipc::IPCResult RecvWindowClose(const BrowsingContextId& aContextId,
-                                          const bool& aTrustedCaller);
-  mozilla::ipc::IPCResult RecvWindowFocus(const BrowsingContextId& aContextId);
-  mozilla::ipc::IPCResult RecvWindowBlur(const BrowsingContextId& aContextId);
+  mozilla::ipc::IPCResult RecvWindowClose(BrowsingContext* aContext,
+                                          bool aTrustedCaller);
+  mozilla::ipc::IPCResult RecvWindowFocus(BrowsingContext* aContext);
+  mozilla::ipc::IPCResult RecvWindowBlur(BrowsingContext* aContext);
   mozilla::ipc::IPCResult RecvWindowPostMessage(
-      const BrowsingContextId& aContextId, const ClonedMessageData& aMessage,
+      BrowsingContext* aContext, const ClonedMessageData& aMessage,
       const PostMessageData& aData);
 
   mozilla::ipc::IPCResult RecvSetUserGestureActivation(
-      const BrowsingContextId& aContextId, const bool& aNewValue);
+      BrowsingContext* aContext, bool aNewValue);
 
  protected:
   void OnChannelConnected(int32_t pid) override;
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   bool ShouldContinueFromReplyTimeout() override;
 
--- a/dom/ipc/DOMTypes.ipdlh
+++ b/dom/ipc/DOMTypes.ipdlh
@@ -22,17 +22,17 @@ using DesktopIntRect from "Units.h";
 using DesktopToLayoutDeviceScale from "Units.h";
 using CSSToLayoutDeviceScale from "Units.h";
 using CSSRect from "Units.h";
 using CSSSize from "Units.h";
 using mozilla::LayoutDeviceIntPoint from "Units.h";
 using hal::ScreenOrientation from "mozilla/HalScreenConfiguration.h";
 using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
 using refcounted class nsIPrincipal from "mozilla/dom/PermissionMessageUtils.h";
-using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
+using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
 using refcounted class nsIURI from "mozilla/ipc/URIUtils.h";
 
 namespace mozilla {
 namespace dom {
 
 struct MessagePortIdentifier
 {
   nsID uuid;
@@ -184,17 +184,17 @@ struct PerformanceInfo
   // Counters per category. For workers, a single entry
   CategoryDispatch[] items;
 };
 
 
 struct WindowGlobalInit
 {
   nsIPrincipal principal;
-  BrowsingContextId browsingContextId;
+  BrowsingContext browsingContext;
   uint64_t innerWindowId;
   uint64_t outerWindowId;
 };
 
 struct DocShellLoadStateInit
 {
   nsIURI Referrer;
   nsIURI URI;
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -83,17 +83,17 @@ using mozilla::EventMessage from "mozill
 using nsEventStatus from "mozilla/EventForwards.h";
 using mozilla::Modifiers from "mozilla/EventForwards.h";
 using nsSizeMode from "nsIWidgetListener.h";
 using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
 using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h";
 using mozilla::FontRange from "ipc/nsGUIEventIPC.h";
 using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
 using mozilla::OriginAttributes from "mozilla/ipc/BackgroundUtils.h";
-using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
+using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
 
 namespace mozilla {
 namespace dom {
 
 struct ShowInfo
 {
   nsString name;
   bool fullscreenAllowed;
@@ -616,17 +616,17 @@ parent:
                                      bool aHideDoorHanger);
 
     sync SetSystemFont(nsCString aFontName);
     sync GetSystemFont() returns (nsCString retval);
 
     sync SetPrefersReducedMotionOverrideForTest(bool aValue);
     sync ResetPrefersReducedMotionOverrideForTest();
 
-    async RootBrowsingContext(BrowsingContextId aId);
+    async RootBrowsingContext(BrowsingContext aContext);
 
 child:
     /**
      * Notify the remote browser that it has been Show()n on this
      * side, with the given |visibleRect|.  This message is expected
      * to trigger creation of the remote browser's "widget".
      *
      * |Show()| and |Move()| take IntSizes rather than Rects because
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -97,16 +97,17 @@ using mozilla::Telemetry::HistogramAccum
 using mozilla::Telemetry::KeyedHistogramAccumulation from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::ScalarAction from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::KeyedScalarAction from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::DynamicScalarDefinition from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::ChildEventData from "mozilla/TelemetryComms.h";
 using mozilla::Telemetry::DiscardedData from "mozilla/TelemetryComms.h";
 using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
 using refcounted class nsIInputStream from "mozilla/ipc/IPCStreamUtils.h";
+using refcounted class mozilla::dom::BrowsingContext from "mozilla/dom/BrowsingContext.h";
 using mozilla::dom::BrowsingContextId from "mozilla/dom/ipc/IdType.h";
 
 union ChromeRegistryItem
 {
     ChromePackage;
     OverrideMapping;
     SubstitutionMapping;
 };
@@ -303,17 +304,17 @@ struct NotificationEventData
     nsString tag;
     nsString icon;
     nsString data;
     nsString behavior;
 };
 
 struct PostMessageData
 {
-    BrowsingContextId source;
+    BrowsingContext source;
     nsString origin;
     nsString targetOrigin;
     nsIURI targetOriginURI;
     nsIPrincipal callerPrincipal;
     nsIPrincipal subjectPrincipal;
     nsIURI callerDocumentURI;
     bool isFromPrivateWindow;
 };
@@ -1214,57 +1215,54 @@ parent:
                                                   nsCString aTrackingOrigin,
                                                   nsCString aGrantedOrigin,
                                                   int aAllowMode)
           returns (bool unused);
 
     async StoreUserInteractionAsPermission(Principal aPrincipal);
 
     /**
-     * Sync the BrowsingContext with id 'aContextId' and name 'aName'
-     * to the parent, and attach it to the BrowsingContext with id
-     * 'aParentContextId'. If 'aParentContextId' is '0' the
-     * BrowsingContext is a root in the BrowsingContext
-     * tree. AttachBrowsingContext must only be called at most once
-     * for any child BrowsingContext, and only for BrowsingContexts
-     * where the parent and the child context contains their
-     * nsDocShell.
+     * Sync the BrowsingContext with id 'aContextId' and name 'aName' to the
+     * parent, and attach it to the BrowsingContext 'aParentContext'. If
+     * 'aParentContext' is 'nullptr' the BrowsingContext is a root in the
+     * BrowsingContext tree. AttachBrowsingContext must only be called at most
+     * once for any child BrowsingContext, and only for BrowsingContexts where
+     * the parent and the child context contains their nsDocShell.
      */
-    async AttachBrowsingContext(BrowsingContextId aParentContextId,
-                                BrowsingContextId aOpenerId,
+    async AttachBrowsingContext(BrowsingContext aParentContext,
+                                BrowsingContext aOpener,
                                 BrowsingContextId aContextId,
                                 nsString aName);
 
     /**
-     * Remove the synced BrowsingContext with id 'aContextId' from the
-     * parent. DetachBrowsingContext is only needed to be called once
-     * for any BrowsingContext, since detaching a node in the
-     * BrowsingContext detaches the entire sub-tree rooted at that
-     * node. Calling DetachBrowsingContext with an already detached
-     * BrowsingContext effectively does nothing. Note that it is not
-     * an error to call DetachBrowsingContext on a BrowsingContext
-     * belonging to an already detached subtree. The 'aMoveToBFCache'
-     * paramater controls if detaching a BrowsingContext should move
-     * it to the bfcache allowing it to be re-attached if navigated
+     * Remove the synced BrowsingContext 'aContext' from the parent.
+     * DetachBrowsingContext is only needed to be called once for any
+     * BrowsingContext, since detaching a node in the BrowsingContext detaches
+     * the entire sub-tree rooted at that node. Calling DetachBrowsingContext
+     * with an already detached BrowsingContext effectively does nothing. Note
+     * that it is not an error to call DetachBrowsingContext on a
+     * BrowsingContext belonging to an already detached subtree. The
+     * 'aMoveToBFCache' paramater controls if detaching a BrowsingContext
+     * should move it to the bfcache allowing it to be re-attached if navigated
      * to.
      */
-    async DetachBrowsingContext(BrowsingContextId aContextId,
+    async DetachBrowsingContext(BrowsingContext aContext,
                                 bool aMoveToBFCache);
 
     /**
-     * Set the opener of browsing context with id 'aContextId' to the
-     * browsing context with id 'aOpenerId'.
+     * Set the opener of browsing context 'aContext' to the browsing context
+     * with id 'aOpenerId'.
      */
-    async SetOpenerBrowsingContext(BrowsingContextId aContextId,
-                                   BrowsingContextId aOpenerContextId);
+    async SetOpenerBrowsingContext(BrowsingContext aContext,
+                                   BrowsingContext aOpenerContext);
 
     /**
      * Notify parent to update user gesture activation flag.
      */
-    async SetUserGestureActivation(BrowsingContextId aContextId,
+    async SetUserGestureActivation(BrowsingContext aContext,
                                    bool aNewValue);
 
 both:
      async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
                         Principal aPrincipal, ClonedMessageData aData);
 
     /**
      * Notify `push-subscription-modified` observers in the parent and child.
@@ -1274,18 +1272,17 @@ both:
 
     /**
      * Send a Push error message to all service worker clients in the parent or
      * child.
      */
     async PushError(nsCString scope, Principal principal, nsString message,
                     uint32_t flags);
 
-    async WindowClose(BrowsingContextId aContextId,
-                      bool aTrustedCaller);
-    async WindowFocus(BrowsingContextId aContextId);
-    async WindowBlur(BrowsingContextId aContextId);
-    async WindowPostMessage(BrowsingContextId aContextId, ClonedMessageData aMessage,
+    async WindowClose(BrowsingContext aContext, bool aTrustedCaller);
+    async WindowFocus(BrowsingContext aContext);
+    async WindowBlur(BrowsingContext aContext);
+    async WindowPostMessage(BrowsingContext aContext, ClonedMessageData aMessage,
                             PostMessageData aData);
 };
 
 }
 }
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -549,17 +549,17 @@ nsresult TabChild::Init(mozIDOMWindowPro
   MOZ_ASSERT(loadContext);
   loadContext->SetPrivateBrowsing(OriginAttributesRef().mPrivateBrowsingId > 0);
   loadContext->SetRemoteTabs(mChromeFlags &
                              nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
 
   // Send our browsing context to the parent process.
   RefPtr<BrowsingContext> browsingContext =
       nsDocShell::Cast(docShell)->GetBrowsingContext();
-  SendRootBrowsingContext(BrowsingContextId(browsingContext->Id()));
+  SendRootBrowsingContext(browsingContext);
 
   // Few lines before, baseWindow->Create() will end up creating a new
   // window root in nsGlobalWindow::SetDocShell.
   // Then this chrome event handler, will be inherited to inner windows.
   // We want to also set it to the docshell so that inner windows
   // and any code that has access to the docshell
   // can all listen to the same chrome event handler.
   // XXX: ideally, we would set a chrome event handler earlier,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3439,19 +3439,19 @@ mozilla::ipc::IPCResult TabParent::RecvG
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (widget) {
     widget->GetSystemFont(*aFontName);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult TabParent::RecvRootBrowsingContext(
-    const BrowsingContextId& aId) {
+  BrowsingContext* aBrowsingContext) {
   MOZ_ASSERT(!mBrowsingContext, "May only set browsing context once!");
-  mBrowsingContext = CanonicalBrowsingContext::Get(aId);
+  mBrowsingContext = CanonicalBrowsingContext::Cast(aBrowsingContext);
   MOZ_ASSERT(mBrowsingContext, "Invalid ID!");
   return IPC_OK();
 }
 
 NS_IMETHODIMP
 FakeChannel::OnAuthAvailable(nsISupports* aContext,
                              nsIAuthInformation* aAuthInfo) {
   nsAuthInformationHolder* holder =
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -252,21 +252,20 @@ class TabParent final : public PBrowserP
   mozilla::ipc::IPCResult RecvEnableDisableCommands(
       const nsString& aAction, nsTArray<nsCString>&& aEnabledCommands,
       nsTArray<nsCString>&& aDisabledCommands);
 
   mozilla::ipc::IPCResult RecvSetCursor(
       const nsCursor& aValue, const bool& aHasCustomCursor,
       const nsCString& aUri, const uint32_t& aWidth, const uint32_t& aHeight,
       const uint32_t& aStride, const gfx::SurfaceFormat& aFormat,
-      const uint32_t& aHotspotX, const uint32_t& aHotspotY,
-      const bool& aForce);
+      const uint32_t& aHotspotX, const uint32_t& aHotspotY, const bool& aForce);
 
-  mozilla::ipc::IPCResult RecvSetStatus(
-      const uint32_t& aType, const nsString& aStatus);
+  mozilla::ipc::IPCResult RecvSetStatus(const uint32_t& aType,
+                                        const nsString& aStatus);
 
   mozilla::ipc::IPCResult RecvShowTooltip(const uint32_t& aX,
                                           const uint32_t& aY,
                                           const nsString& aTooltip,
                                           const nsString& aDirection);
 
   mozilla::ipc::IPCResult RecvHideTooltip();
 
@@ -590,17 +589,17 @@ class TabParent final : public PBrowserP
                                             const int32_t& aX,
                                             const int32_t& aY,
                                             const int32_t& aCx,
                                             const int32_t& aCy);
 
   mozilla::ipc::IPCResult RecvShowCanvasPermissionPrompt(
       const nsCString& aFirstPartyURI, const bool& aHideDoorHanger);
 
-  mozilla::ipc::IPCResult RecvRootBrowsingContext(const BrowsingContextId& aId);
+  mozilla::ipc::IPCResult RecvRootBrowsingContext(BrowsingContext* aContext);
 
   mozilla::ipc::IPCResult RecvSetSystemFont(const nsCString& aFontName);
   mozilla::ipc::IPCResult RecvGetSystemFont(nsCString* aFontName);
 
   mozilla::ipc::IPCResult RecvVisitURI(const URIParams& aURI,
                                        const OptionalURIParams& aLastVisitedURI,
                                        const uint32_t& aFlags);
 
--- a/dom/ipc/WindowGlobalChild.cpp
+++ b/dom/ipc/WindowGlobalChild.cpp
@@ -34,19 +34,18 @@ already_AddRefed<WindowGlobalChild> Wind
 
   RefPtr<nsDocShell> docshell = nsDocShell::Cast(aWindow->GetDocShell());
   MOZ_ASSERT(docshell);
 
   // Initalize our WindowGlobalChild object.
   RefPtr<dom::BrowsingContext> bc = docshell->GetBrowsingContext();
   RefPtr<WindowGlobalChild> wgc = new WindowGlobalChild(aWindow, bc);
 
-  WindowGlobalInit init(principal,
-                        BrowsingContextId(wgc->BrowsingContext()->Id()),
-                        wgc->mInnerWindowId, wgc->mOuterWindowId);
+  WindowGlobalInit init(principal, bc, wgc->mInnerWindowId,
+                        wgc->mOuterWindowId);
 
   // Send the link constructor over PInProcessChild or PBrowser.
   if (XRE_IsParentProcess()) {
     InProcessChild* ipc = InProcessChild::Singleton();
     if (!ipc) {
       return nullptr;
     }
 
--- a/dom/ipc/WindowGlobalParent.cpp
+++ b/dom/ipc/WindowGlobalParent.cpp
@@ -32,17 +32,17 @@ WindowGlobalParent::WindowGlobalParent(c
       mOuterWindowId(aInit.outerWindowId()),
       mInProcess(aInProcess),
       mIPCClosed(true)  // Closed until WGP::Init
 {
   MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(), "Parent process only");
   MOZ_RELEASE_ASSERT(mDocumentPrincipal, "Must have a valid principal");
 
   // NOTE: mBrowsingContext initialized in Init()
-  MOZ_RELEASE_ASSERT(aInit.browsingContextId() != 0,
+  MOZ_RELEASE_ASSERT(aInit.browsingContext(),
                      "Must be made in BrowsingContext");
 }
 
 void WindowGlobalParent::Init(const WindowGlobalInit& aInit) {
   MOZ_ASSERT(Manager(), "Should have a manager!");
   MOZ_ASSERT(!mFrameLoader, "Cannot Init() a WindowGlobalParent twice!");
 
   MOZ_ASSERT(mIPCClosed, "IPC shouldn't be open yet");
@@ -58,17 +58,17 @@ void WindowGlobalParent::Init(const Wind
   entry.OrInsert([&] { return this; });
 
   // Determine which content process the window global is coming from.
   ContentParentId processId(0);
   if (!mInProcess) {
     processId = static_cast<ContentParent*>(Manager()->Manager())->ChildID();
   }
 
-  mBrowsingContext = CanonicalBrowsingContext::Get(aInit.browsingContextId());
+  mBrowsingContext = CanonicalBrowsingContext::Cast(aInit.browsingContext());
   MOZ_ASSERT(mBrowsingContext);
 
   // XXX(nika): This won't be the case soon, but for now this is a good
   // assertion as we can't switch processes. We should relax this eventually.
   MOZ_ASSERT(mBrowsingContext->IsOwnedByProcess(processId));
 
   // Attach ourself to the browsing context.
   mBrowsingContext->RegisterWindowGlobal(this);