Bug 1480113 - Split parent process specific parts out of BrowsingContext r=peterv
authorAndreas Farre <farre@mozilla.com>
Fri, 14 Sep 2018 14:57:18 +0000
changeset 495124 1de6dfd1e6ed1e54e440f1d9bf18ffc579b76a3b
parent 495123 e0802d8df93ad985967484485c7d942486472f8b
child 495125 8854f79600bb5612cd742638e2e175559690d618
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1480113
milestone64.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 1480113 - Split parent process specific parts out of BrowsingContext r=peterv Create ChromeBrowsingContext and move parent process specific parts from BrowsingContext there. After that make sure that all BrowsingContexts created in the parent process is actually ChromeBrowsingContexts and all BrowsingContexts in the child processes are BrowsingContexts. Differential Revision: https://phabricator.services.mozilla.com/D5419
docshell/base/BrowsingContext.cpp
docshell/base/BrowsingContext.h
docshell/base/ChromeBrowsingContext.cpp
docshell/base/ChromeBrowsingContext.h
docshell/base/moz.build
docshell/base/nsDocShell.cpp
dom/ipc/ContentParent.cpp
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -1,16 +1,17 @@
 /* -*- 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 "BrowsingContext.h"
 
+#include "mozilla/dom/ChromeBrowsingContext.h"
 #include "mozilla/dom/BrowsingContextBinding.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/Logging.h"
 #include "mozilla/StaticPtr.h"
 
 #include "nsDataHashtable.h"
@@ -56,64 +57,51 @@ BrowsingContext::Init()
 }
 
 /* static */ LogModule*
 BrowsingContext::GetLog()
 {
   return gBrowsingContextLog;
 }
 
-// TODO(farre): BrowsingContext::CleanupContexts starts from the list
-// of root BrowsingContexts. This isn't enough when separate
-// BrowsingContext nodes of a BrowsingContext tree not in a crashing
-// child process are from that process and thus needs to be
-// cleaned. [Bug 1472108]
-/* static */ void
-BrowsingContext::CleanupContexts(uint64_t aProcessId)
-{
-  if (sRootBrowsingContexts) {
-    RefPtr<BrowsingContext> context = sRootBrowsingContexts->getFirst();
-
-    while (context) {
-      RefPtr<BrowsingContext> next = context->getNext();
-      if (context->IsOwnedByProcess() &&
-          aProcessId == context->OwnerProcessId()) {
-        context->Detach();
-      }
-      context = next;
-    }
-  }
-}
-
 /* static */ already_AddRefed<BrowsingContext>
 BrowsingContext::Get(uint64_t aId)
 {
   RefPtr<BrowsingContext> abc = sBrowsingContexts->Get(aId);
   return abc.forget();
 }
 
+/* static */ already_AddRefed<BrowsingContext>
+BrowsingContext::Create(nsIDocShell* aDocShell)
+{
+  RefPtr<BrowsingContext> context;
+  if (XRE_IsParentProcess()) {
+    context = new ChromeBrowsingContext(aDocShell);
+  } else {
+    // TODO(farre): will we ever create BrowsingContexts on processes
+    // other than content and parent?
+    MOZ_ASSERT(XRE_IsContentProcess());
+    context = new BrowsingContext(aDocShell);
+  }
+
+  return context.forget();
+}
+
 BrowsingContext::BrowsingContext(nsIDocShell* aDocShell)
   : mBrowsingContextId(nsContentUtils::GenerateBrowsingContextId())
-  , mProcessId(Nothing())
   , mDocShell(aDocShell)
 {
   sBrowsingContexts->Put(mBrowsingContextId, this);
 }
 
 BrowsingContext::BrowsingContext(uint64_t aBrowsingContextId,
-                                 const nsAString& aName,
-                                 const Maybe<uint64_t>& aProcessId)
+                const nsAString& aName)
   : mBrowsingContextId(aBrowsingContextId)
-  , mProcessId(aProcessId)
   , mName(aName)
 {
-  // mProcessId only really has a meaning in the parent process, where
-  // it keeps track of which BrowsingContext is actually holding the
-  // nsDocShell.
-  MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess() || aProcessId.isNothing());
   sBrowsingContexts->Put(mBrowsingContextId, this);
 }
 
 void
 BrowsingContext::Attach(BrowsingContext* aParent)
 {
   if (isInList()) {
     MOZ_LOG(GetLog(),
@@ -140,21 +128,21 @@ BrowsingContext::Attach(BrowsingContext*
   auto* children = aParent ? &aParent->mChildren : sRootBrowsingContexts.get();
   children->insertBack(this);
   mParent = aParent;
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
-  auto cc = dom::ContentChild::GetSingleton();
+  auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
   cc->SendAttachBrowsingContext(
-    dom::BrowsingContextId(mParent ? mParent->Id() : 0),
-    dom::BrowsingContextId(Id()),
+    BrowsingContextId(mParent ? mParent->Id() : 0),
+    BrowsingContextId(Id()),
     mName);
 }
 
 void
 BrowsingContext::Detach()
 {
   RefPtr<BrowsingContext> kungFuDeathGrip(this);
 
@@ -179,19 +167,19 @@ BrowsingContext::Detach()
            mParent ? mParent->Id() : 0));
 
   remove();
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
-  auto cc = dom::ContentChild::GetSingleton();
+  auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
-  cc->SendDetachBrowsingContext(dom::BrowsingContextId(Id()),
+  cc->SendDetachBrowsingContext(BrowsingContextId(Id()),
                                 false /* aMoveToBFCache */);
 }
 
 void
 BrowsingContext::CacheChildren()
 {
   if (mChildren.isEmpty()) {
     return;
@@ -207,35 +195,28 @@ BrowsingContext::CacheChildren()
     RefPtr<BrowsingContext> child = mChildren.popFirst();
     sCachedBrowsingContexts->Put(child->Id(), child);
   }
 
   if (!XRE_IsContentProcess()) {
     return;
   }
 
-  auto cc = dom::ContentChild::GetSingleton();
+  auto cc = ContentChild::GetSingleton();
   MOZ_DIAGNOSTIC_ASSERT(cc);
-  cc->SendDetachBrowsingContext(dom::BrowsingContextId(Id()),
+  cc->SendDetachBrowsingContext(BrowsingContextId(Id()),
                                 true /* aMoveToBFCache */);
 }
 
 bool
 BrowsingContext::IsCached()
 {
   return sCachedBrowsingContexts->Contains(Id());
 }
 
-uint64_t
-BrowsingContext::OwnerProcessId() const
-{
-  MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
-  return mProcessId.value();
-}
-
 void
 BrowsingContext::GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren)
 {
   for (BrowsingContext* context : mChildren) {
     aChildren.AppendElement(context);
   }
 }
 
@@ -282,14 +263,32 @@ ImplCycleCollectionTraverse(nsCycleColle
                             uint32_t aFlags = 0)
 {
   for (BrowsingContext* aContext : aField) {
     aCallback.NoteNativeChild(aContext,
                               NS_CYCLE_COLLECTION_PARTICIPANT(BrowsingContext));
   }
 }
 
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BrowsingContext, mDocShell, mChildren)
+NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContext)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContext)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell, mChildren)
+  if (XRE_IsParentProcess()) {
+    ChromeBrowsingContext::Cast(tmp)->Unlink();
+  }
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowsingContext)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell, mChildren)
+  if (XRE_IsParentProcess()) {
+    ChromeBrowsingContext::Cast(tmp)->Traverse(cb);
+  }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BrowsingContext)
+
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContext, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContext, Release)
 
 } // namespace dom
 } // namespace mozilla
--- a/docshell/base/BrowsingContext.h
+++ b/docshell/base/BrowsingContext.h
@@ -43,28 +43,17 @@ class BrowsingContext
   , public LinkedListElement<RefPtr<BrowsingContext>>
 {
 public:
   static void Init();
   static LogModule* GetLog();
   static void CleanupContexts(uint64_t aProcessId);
 
   static already_AddRefed<BrowsingContext> Get(uint64_t aId);
-
-  // Create a new BrowsingContext for 'aDocShell'. The id will be
-  // generated so that it is unique across all content child processes
-  // and the content parent process.
-  explicit BrowsingContext(nsIDocShell* aDocShell);
-  // Create a BrowsingContext for a particular BrowsingContext id, in
-  // the case where the id is known beforehand and a nsDocShell isn't
-  // needed (e.g. when creating BrowsingContexts in the parent
-  // process).
-  BrowsingContext(uint64_t aBrowsingContextId,
-                  const nsAString& aName,
-                  const Maybe<uint64_t>& aProcessId = Nothing());
+  static already_AddRefed<BrowsingContext> Create(nsIDocShell* aDocShell);
 
   // Attach the current BrowsingContext to its parent, in both the
   // child and the parent process. If 'aParent' is null, 'this' is
   // taken to be a root BrowsingContext.
   void Attach(BrowsingContext* aParent);
 
   // Detach the current BrowsingContext from its parent, in both the
   // child and the parent process.
@@ -77,17 +66,16 @@ public:
   bool IsCached();
 
   void SetName(const nsAString& aName) { mName = aName; }
   void GetName(nsAString& aName) { aName = mName; }
   bool NameEquals(const nsAString& aName) { return mName.Equals(aName); }
 
   uint64_t Id() const { return mBrowsingContextId; }
   uint64_t OwnerProcessId() const;
-  bool IsOwnedByProcess() const { return mProcessId.isSome(); }
 
   already_AddRefed<BrowsingContext> GetParent()
   {
     return do_AddRef(mParent.get());
   }
 
   void GetChildren(nsTArray<RefPtr<BrowsingContext>>& aChildren);
 
@@ -99,25 +87,28 @@ public:
                                JS::Handle<JSObject*> aGivenProto) override;
 
   MOZ_DECLARE_WEAKREFERENCE_TYPENAME(BrowsingContext)
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContext)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(BrowsingContext)
 
   using Children = AutoCleanLinkedList<RefPtr<BrowsingContext>>;
 
-private:
+protected:
   virtual ~BrowsingContext();
+  // Create a new BrowsingContext for 'aDocShell'. The id will be
+  // generated so that it is unique across all content child processes
+  // and the content parent process.
+  explicit BrowsingContext(nsIDocShell* aDocShell);
+  BrowsingContext(uint64_t aBrowsingContextId,
+                  const nsAString& aName);
 
+private:
   const uint64_t mBrowsingContextId;
 
-  // Indicates which process owns the docshell. Only valid in the
-  // parent process.
-  Maybe<uint64_t> mProcessId;
-
   WeakPtr<BrowsingContext> mParent;
   Children mChildren;
   nsCOMPtr<nsIDocShell> mDocShell;
   nsString mName;
 };
 
 } // namespace dom
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/docshell/base/ChromeBrowsingContext.cpp
@@ -0,0 +1,74 @@
+/* -*- 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 "ChromeBrowsingContext.h"
+
+namespace mozilla {
+namespace dom {
+
+ChromeBrowsingContext::ChromeBrowsingContext(uint64_t aBrowsingContextId,
+                                             const nsAString& aName,
+                                             uint64_t aProcessId)
+  : BrowsingContext(aBrowsingContextId, aName)
+  , mProcessId(aProcessId)
+{
+  // You are only ever allowed to create ChromeBrowsingContexts in the
+  // parent process.
+  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+}
+
+ChromeBrowsingContext::ChromeBrowsingContext(nsIDocShell* aDocShell)
+  : BrowsingContext(aDocShell)
+  , mProcessId(0)
+{
+  // You are only ever allowed to create ChromeBrowsingContexts in the
+  // parent process.
+  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+}
+
+// TODO(farre): ChromeBrowsingContext::CleanupContexts starts from the
+// list of root BrowsingContexts. This isn't enough when separate
+// BrowsingContext nodes of a BrowsingContext tree, not in a crashing
+// child process, are from that process and thus needs to be
+// cleaned. [Bug 1472108]
+/* static */ void
+ChromeBrowsingContext::CleanupContexts(uint64_t aProcessId)
+{
+  nsTArray<RefPtr<BrowsingContext>> roots;
+  BrowsingContext::GetRootBrowsingContexts(roots);
+
+  for (RefPtr<BrowsingContext> context : roots) {
+    if (Cast(context)->IsOwnedByProcess(aProcessId)) {
+      context->Detach();
+    }
+  }
+}
+
+/* static */ already_AddRefed<ChromeBrowsingContext>
+ChromeBrowsingContext::Get(uint64_t aId)
+{
+  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+  return BrowsingContext::Get(aId).downcast<ChromeBrowsingContext>();
+}
+
+/* static */ ChromeBrowsingContext*
+ChromeBrowsingContext::Cast(BrowsingContext* aContext)
+{
+  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+  return static_cast<ChromeBrowsingContext*>(aContext);
+}
+
+/* static */ already_AddRefed<ChromeBrowsingContext>
+ChromeBrowsingContext::Create(
+  uint64_t aBrowsingContextId,
+  const nsAString& aName,
+  uint64_t aProcessId)
+{
+  return do_AddRef(new ChromeBrowsingContext(aBrowsingContextId, aName, aProcessId));
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/docshell/base/ChromeBrowsingContext.h
@@ -0,0 +1,58 @@
+/* -*- 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 ChromeBrowsingContext_h
+#define ChromeBrowsingContext_h
+
+#include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/RefPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+class nsIDocShell;
+
+namespace mozilla {
+namespace dom {
+
+// ChromeBrowsingContext is a BrowsingContext living in the parent
+// process, with whatever extra data that a BrowsingContext in the
+// parent needs.
+class ChromeBrowsingContext final
+  : public BrowsingContext
+{
+public:
+  static void CleanupContexts(uint64_t aProcessId);
+  static already_AddRefed<ChromeBrowsingContext> Get(uint64_t aId);
+  static ChromeBrowsingContext* Cast(BrowsingContext* aContext);
+  static already_AddRefed<ChromeBrowsingContext> Create(
+    uint64_t aBrowsingContextId,
+    const nsAString& aName,
+    uint64_t aProcessId);
+
+  bool IsOwnedByProcess(uint64_t aProcessId) const
+  {
+    return mProcessId == aProcessId;
+  }
+
+protected:
+  void Traverse(nsCycleCollectionTraversalCallback& cb) {}
+  void Unlink() {}
+  ChromeBrowsingContext(uint64_t aBrowsingContextId,
+                        const nsAString& aName,
+                        uint64_t aProcessId);
+
+private:
+  friend class BrowsingContext;
+
+  explicit ChromeBrowsingContext(nsIDocShell* aDocShell);
+
+  // Indicates which process owns the docshell.
+  uint64_t mProcessId;
+};
+
+} // namespace dom
+} // namespace mozilla
+#endif
--- a/docshell/base/moz.build
+++ b/docshell/base/moz.build
@@ -71,20 +71,22 @@ EXPORTS += [
 
 EXPORTS.mozilla += [
     'IHistory.h',
     'LoadContext.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'BrowsingContext.h',
+    'ChromeBrowsingContext.h'
 ]
 
 UNIFIED_SOURCES += [
     'BrowsingContext.cpp',
+    'ChromeBrowsingContext.cpp',
     'LoadContext.cpp',
     'nsAboutRedirector.cpp',
     'nsDefaultURIFixup.cpp',
     'nsDocShell.cpp',
     'nsDocShellEditorData.cpp',
     'nsDocShellEnumerator.cpp',
     'nsDocShellLoadInfo.cpp',
     'nsDocShellTreeOwner.cpp',
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -469,17 +469,17 @@ nsDocShell::Init()
   // ref to us...  use an InterfaceRequestorProxy to do this.
   nsCOMPtr<nsIInterfaceRequestor> proxy =
     new InterfaceRequestorProxy(static_cast<nsIInterfaceRequestor*>(this));
   mLoadGroup->SetNotificationCallbacks(proxy);
 
   rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mBrowsingContext = new BrowsingContext(this);
+  mBrowsingContext = BrowsingContext::Create(this);
 
   // Add as |this| a progress listener to itself.  A little weird, but
   // simpler than reproducing all the listener-notification logic in
   // overrides of the various methods via which nsDocLoader can be
   // notified.   Note that this holds an nsWeakPtr to ourselves, so it's ok.
   return AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT |
                                      nsIWebProgress::NOTIFY_STATE_NETWORK);
 }
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -32,16 +32,17 @@
 #include "mozilla/AntiTrackingCommon.h"
 #include "mozilla/BasePrincipal.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/DataStorage.h"
 #include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/ChromeBrowsingContext.h"
 #include "mozilla/dom/ClientManager.h"
 #include "mozilla/dom/ClientOpenWindowOpActors.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/FileCreatorHelper.h"
 #include "mozilla/dom/FileSystemSecurity.h"
 #include "mozilla/dom/IPCBlobUtils.h"
@@ -1896,17 +1897,17 @@ ContentParent::ActorDestroy(ActorDestroy
   }
 
   mBlobURLs.Clear();
 
 #if defined(XP_WIN32) && defined(ACCESSIBILITY)
   a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
 #endif
 
-  BrowsingContext::CleanupContexts(ChildID());
+  ChromeBrowsingContext::CleanupContexts(ChildID());
 }
 
 bool
 ContentParent::TryToRecycle()
 {
   // This life time check should be replaced by a memory health check (memory usage + fragmentation).
   const double kMaxLifeSpan = 5;
   if (mShutdownPending ||
@@ -5966,17 +5967,17 @@ ContentParent::RecvFirstPartyStorageAcce
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvAttachBrowsingContext(
   const BrowsingContextId& aParentId,
   const BrowsingContextId& aChildId,
   const nsString& aName)
 {
-  RefPtr<BrowsingContext> parent = BrowsingContext::Get(aParentId);
+  RefPtr<ChromeBrowsingContext> parent = ChromeBrowsingContext::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.
 
@@ -5988,17 +5989,17 @@ ContentParent::RecvAttachBrowsingContext
     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->OwnerProcessId() != ChildID()) {
+  if (parent && !parent->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
@@ -6026,38 +6027,38 @@ ContentParent::RecvAttachBrowsingContext
             ("ParentIPC: Trying to attach already attached 0x%08" PRIx64
              " to 0x%08" PRIx64,
              child->Id(),
              (uint64_t)aParentId));
     return IPC_OK();
   }
 
   if (!child) {
-    child = new BrowsingContext(aChildId, aName, Some(ChildID()));
+    child = ChromeBrowsingContext::Create(aChildId, aName, ChildID());
   }
   child->Attach(parent);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvDetachBrowsingContext(const BrowsingContextId& aContextId,
                                          const bool& aMoveToBFCache)
 {
-  RefPtr<BrowsingContext> context = BrowsingContext::Get(aContextId);
+  RefPtr<ChromeBrowsingContext> context = ChromeBrowsingContext::Get(aContextId);
 
   if (!context) {
     MOZ_LOG(BrowsingContext::GetLog(),
             LogLevel::Debug,
             ("ParentIPC: Trying to detach already detached 0x%08" PRIx64,
              (uint64_t)aContextId));
     return IPC_OK();
   }
 
-  if (context->OwnerProcessId() != ChildID()) {
+  if (!context->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(),