Bug 879475 - Part 004. Fix IndexedDBObjectStore to not assume that PContent connects the same processes as PBrowser r=bent
☠☠ backed out by 2d457b6bae2d ☠ ☠
author"Kan-Ru Chen (陳侃如)" <kanru@kanru.info>
Mon, 09 Jun 2014 16:49:11 +0800
changeset 206753 5b65bf834d5f8e9450542d4d46de12ae033f62e5
parent 206752 3f1a5417af05693178de465e70ce581ee853df15
child 206754 a7872dbfa5ce0a91b06c353b1080dc6950c97ef8
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent
bugs879475
milestone32.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 879475 - Part 004. Fix IndexedDBObjectStore to not assume that PContent connects the same processes as PBrowser r=bent Based on original patch by David Zbarsky <dzbarsky@gmail.com>
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/ipc/IndexedDBChild.cpp
dom/indexedDB/ipc/IndexedDBChild.h
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -152,17 +152,17 @@ IDBFactory::Create(nsPIDOMWindow* aWindo
   factory->mDefaultPersistenceType = defaultPersistenceType;
   factory->mWindow = aWindow;
   factory->mContentParent = aContentParent;
 
   if (!IndexedDatabaseManager::IsMainProcess()) {
     TabChild* tabChild = TabChild::GetFrom(aWindow);
     IDB_ENSURE_TRUE(tabChild, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
-    IndexedDBChild* actor = new IndexedDBChild(origin);
+    IndexedDBChild* actor = new IndexedDBChild(tabChild, origin);
 
     bool allowed;
     tabChild->SendPIndexedDBConstructor(actor, group, origin, &allowed);
 
     if (!allowed) {
       actor->Send__delete__(actor);
       *aFactory = nullptr;
       return NS_OK;
@@ -211,17 +211,17 @@ IDBFactory::Create(JSContext* aCx,
 
   mozilla::HoldJSObjects(factory.get());
   factory->mRootedOwningObject = true;
 
   if (!IndexedDatabaseManager::IsMainProcess()) {
     ContentChild* contentChild = ContentChild::GetSingleton();
     IDB_ENSURE_TRUE(contentChild, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
-    IndexedDBChild* actor = new IndexedDBChild(origin);
+    IndexedDBChild* actor = new IndexedDBChild(contentChild, origin);
 
     contentChild->SendPIndexedDBConstructor(actor);
 
     actor->SetFactory(factory);
   }
 
   factory.forget(aFactory);
   return NS_OK;
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -12,16 +12,17 @@
 #include "nsIOutputStream.h"
 
 #include <algorithm>
 #include "jsfriendapi.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/nsIContentParent.h"
 #include "mozilla/dom/FileHandleBinding.h"
 #include "mozilla/dom/StructuredCloneTags.h"
+#include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/ipc/Blob.h"
 #include "mozilla/dom/quota/FileStreams.h"
 #include "mozilla/Endian.h"
 #include "mozilla/storage.h"
 #include "nsContentUtils.h"
 #include "nsDOMClassInfo.h"
 #include "nsDOMFile.h"
 #include "mozilla/dom/DOMStringList.h"
@@ -106,17 +107,18 @@ public:
     NS_ASSERTION(aObjectStore, "Null object store!");
   }
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult Dispatch(nsIEventTarget* aDatabaseThread) MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) = 0;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) = 0;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) = 0;
 
 protected:
   nsRefPtr<IDBObjectStore> mObjectStore;
 
 private:
@@ -179,17 +181,18 @@ public:
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -223,17 +226,18 @@ public:
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -258,17 +262,18 @@ public:
 
   virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection)
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 };
@@ -281,17 +286,18 @@ public:
               IDBObjectStore* aObjectStore)
   : ObjectStoreHelper(aTransaction, aRequest, aObjectStore)
   { }
 
   virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection)
                                   MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 };
@@ -317,17 +323,18 @@ public:
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -368,17 +375,18 @@ public:
   virtual nsresult
   GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
                    MOZ_OVERRIDE;
 
   virtual void
   ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -475,17 +483,18 @@ public:
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -517,17 +526,18 @@ public:
   virtual nsresult
   GetSuccessResult(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
                    MOZ_OVERRIDE;
 
   virtual void
   ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -555,17 +565,18 @@ public:
                                   MOZ_OVERRIDE;
 
   virtual nsresult GetSuccessResult(JSContext* aCx,
                                     JS::MutableHandle<JS::Value> aVal) MOZ_OVERRIDE;
 
   virtual void ReleaseMainThreadObjects() MOZ_OVERRIDE;
 
   virtual nsresult
-  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
+  PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                nsIContentChild* aBlobCreator) MOZ_OVERRIDE;
 
   virtual ChildProcessSendResult
   SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
 
   virtual nsresult
   UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
                                   MOZ_OVERRIDE;
 
@@ -3035,17 +3046,32 @@ ObjectStoreHelper::Dispatch(nsIEventTarg
     IDB_REPORT_INTERNAL_ERR();
     return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
   }
 
   IndexedDBObjectStoreChild* objectStoreActor = mObjectStore->GetActorChild();
   NS_ASSERTION(objectStoreActor, "Must have an actor here!");
 
   ObjectStoreRequestParams params;
-  nsresult rv = PackArgumentsForParentProcess(params);
+
+  // Our "parent" process may be either the root process or another content
+  // process if this indexedDB is managed by a PBrowser that is managed by a
+  // PContentBridge.  We need to find which one it is so that we can create
+  // PBlobs that are managed by the right nsIContentChild.
+  IndexedDBChild* rootActor =
+    static_cast<IndexedDBChild*>(objectStoreActor->Manager()->
+                                 Manager()->Manager());
+  nsIContentChild* blobCreator;
+  if (rootActor->GetManagerContent()) {
+    blobCreator = rootActor->GetManagerContent();
+  } else {
+    blobCreator = rootActor->GetManagerTab()->Manager();
+  }
+
+  nsresult rv = PackArgumentsForParentProcess(params, blobCreator);
   IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   NoDispatchEventTarget target;
   rv = AsyncConnectionHelper::Dispatch(&target);
   IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   mActor =
     new IndexedDBObjectStoreRequestChild(this, mObjectStore, params.type());
@@ -3315,20 +3341,22 @@ AddHelper::GetSuccessResult(JSContext* a
 void
 AddHelper::ReleaseMainThreadObjects()
 {
   IDBObjectStore::ClearCloneWriteInfo(mCloneWriteInfo);
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+AddHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                         nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("AddHelper", "PackArgumentsForParentProcess",
     js::ProfileEntry::Category::STORAGE);
 
   AddPutParams commonParams;
   commonParams.cloneInfo() = mCloneWriteInfo;
   commonParams.key() = mKey;
   commonParams.indexUpdateInfos().AppendElements(mIndexUpdateInfo);
@@ -3336,27 +3364,26 @@ AddHelper::PackArgumentsForParentProcess
   const nsTArray<StructuredCloneFile>& files = mCloneWriteInfo.mFiles;
 
   if (!files.IsEmpty()) {
     uint32_t fileCount = files.Length();
 
     InfallibleTArray<PBlobChild*>& blobsChild = commonParams.blobsChild();
     blobsChild.SetCapacity(fileCount);
 
-    ContentChild* contentChild = ContentChild::GetSingleton();
-    NS_ASSERTION(contentChild, "This should never be null!");
+    NS_ASSERTION(aBlobCreator, "This should never be null!");
 
     for (uint32_t index = 0; index < fileCount; index++) {
       const StructuredCloneFile& file = files[index];
 
       NS_ASSERTION(file.mFile, "This should never be null!");
       NS_ASSERTION(!file.mFileInfo, "This is not yet supported!");
 
       BlobChild* actor =
-        contentChild->GetOrCreateActorForBlob(file.mFile);
+        aBlobCreator->GetOrCreateActorForBlob(file.mFile);
       if (!actor) {
         IDB_REPORT_INTERNAL_ERR();
         return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
       }
       blobsChild.AppendElement(actor);
     }
   }
 
@@ -3482,21 +3509,23 @@ void
 GetHelper::ReleaseMainThreadObjects()
 {
   mKeyRange = nullptr;
   IDBObjectStore::ClearCloneReadInfo(mCloneReadInfo);
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-GetHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+GetHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                         nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   NS_ASSERTION(mKeyRange, "This should never be null!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("GetHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   GetParams params;
 
   mKeyRange->ToSerializedKeyRange(params.keyRange());
 
@@ -3620,21 +3649,23 @@ nsresult
 DeleteHelper::GetSuccessResult(JSContext* aCx,
                                JS::MutableHandle<JS::Value> aVal)
 {
   aVal.setUndefined();
   return NS_OK;
 }
 
 nsresult
-DeleteHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+DeleteHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                            nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
   NS_ASSERTION(mKeyRange, "This should never be null!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("DeleteHelper", "PackArgumentsForParentProcess",
     js::ProfileEntry::Category::STORAGE);
 
   DeleteParams params;
 
   mKeyRange->ToSerializedKeyRange(params.keyRange());
 
@@ -3703,20 +3734,22 @@ ClearHelper::DoDatabaseWork(mozIStorageC
 
   rv = stmt->Execute();
   IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
 
   return NS_OK;
 }
 
 nsresult
-ClearHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+ClearHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                           nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("ClearHelper", "PackArgumentsForParentProcess",
     js::ProfileEntry::Category::STORAGE);
 
   aParams = ClearParams();
   return NS_OK;
 }
 
@@ -3937,21 +3970,22 @@ OpenCursorHelper::ReleaseMainThreadObjec
   // as long as mCursor is set.
   mSerializedCloneReadInfo.data = nullptr;
   mSerializedCloneReadInfo.dataLength = 0;
 
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-OpenCursorHelper::PackArgumentsForParentProcess(
-                                              ObjectStoreRequestParams& aParams)
+OpenCursorHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                                nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("OpenCursorHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   OpenCursorParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
@@ -4260,21 +4294,22 @@ OpenKeyCursorHelper::ReleaseMainThreadOb
 
   mKeyRange = nullptr;
   mCursor = nullptr;
 
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-OpenKeyCursorHelper::PackArgumentsForParentProcess(
-                                              ObjectStoreRequestParams& aParams)
+OpenKeyCursorHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                                   nsIContentChild* aBlobCreator)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("OpenKeyCursorHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   OpenKeyCursorParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
@@ -4700,20 +4735,22 @@ GetAllHelper::ReleaseMainThreadObjects()
   mKeyRange = nullptr;
   for (uint32_t index = 0; index < mCloneReadInfos.Length(); index++) {
     IDBObjectStore::ClearCloneReadInfo(mCloneReadInfos[index]);
   }
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-GetAllHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+GetAllHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                            nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("GetAllHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   GetAllParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
@@ -4946,21 +4983,22 @@ GetAllKeysHelper::ReleaseMainThreadObjec
   MOZ_ASSERT(NS_IsMainThread());
 
   mKeyRange = nullptr;
 
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-GetAllKeysHelper::PackArgumentsForParentProcess(
-                                              ObjectStoreRequestParams& aParams)
+GetAllKeysHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                                nsIContentChild* aBlobCreator)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("GetAllKeysHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   GetAllKeysParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
@@ -5098,20 +5136,22 @@ CountHelper::GetSuccessResult(JSContext*
 void
 CountHelper::ReleaseMainThreadObjects()
 {
   mKeyRange = nullptr;
   ObjectStoreHelper::ReleaseMainThreadObjects();
 }
 
 nsresult
-CountHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams)
+CountHelper::PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams,
+                                           nsIContentChild* aBlobCreator)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
+  NS_ASSERTION(aBlobCreator, "Must have a valid creator!");
 
   PROFILER_MAIN_THREAD_LABEL("CountHelper", "PackArgumentsForParentProcess [IDBObjectStore.cpp]",
     js::ProfileEntry::Category::STORAGE);
 
   CountParams params;
 
   if (mKeyRange) {
     KeyRange keyRange;
--- a/dom/indexedDB/ipc/IndexedDBChild.cpp
+++ b/dom/indexedDB/ipc/IndexedDBChild.cpp
@@ -154,22 +154,41 @@ public:
 };
 
 } // anonymous namespace
 
 /*******************************************************************************
  * IndexedDBChild
  ******************************************************************************/
 
-IndexedDBChild::IndexedDBChild(const nsCString& aASCIIOrigin)
-: mFactory(nullptr), mASCIIOrigin(aASCIIOrigin)
+IndexedDBChild::IndexedDBChild(ContentChild* aContentChild,
+                               const nsCString& aASCIIOrigin)
+: mFactory(nullptr)
+, mManagerContent(aContentChild)
+, mManagerTab(nullptr)
+, mASCIIOrigin(aASCIIOrigin)
 #ifdef DEBUG
-  , mDisconnected(false)
+, mDisconnected(false)
 #endif
 {
+  MOZ_ASSERT(aContentChild);
+  MOZ_COUNT_CTOR(IndexedDBChild);
+}
+
+IndexedDBChild::IndexedDBChild(TabChild* aTabChild,
+                               const nsCString& aASCIIOrigin)
+: mFactory(nullptr)
+, mManagerContent(nullptr)
+, mManagerTab(aTabChild)
+, mASCIIOrigin(aASCIIOrigin)
+#ifdef DEBUG
+, mDisconnected(false)
+#endif
+{
+  MOZ_ASSERT(aTabChild);
   MOZ_COUNT_CTOR(IndexedDBChild);
 }
 
 IndexedDBChild::~IndexedDBChild()
 {
   MOZ_COUNT_DTOR(IndexedDBChild);
   MOZ_ASSERT(!mFactory);
 }
--- a/dom/indexedDB/ipc/IndexedDBChild.h
+++ b/dom/indexedDB/ipc/IndexedDBChild.h
@@ -14,16 +14,23 @@
 #include "mozilla/dom/indexedDB/PIndexedDBCursorChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBDatabaseChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBDeleteDatabaseRequestChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBIndexChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBObjectStoreChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBRequestChild.h"
 #include "mozilla/dom/indexedDB/PIndexedDBTransactionChild.h"
 
+namespace mozilla {
+namespace dom {
+class ContentChild;
+class TabChild;
+} // dom
+} // mozilla
+
 BEGIN_INDEXEDDB_NAMESPACE
 
 class AsyncConnectionHelper;
 class IDBCursor;
 class IDBFactory;
 class IDBIndex;
 class IDBOpenDBRequest;
 class IDBRequest;
@@ -31,32 +38,48 @@ class IDBTransactionListener;
 
 /*******************************************************************************
  * IndexedDBChild
  ******************************************************************************/
 
 class IndexedDBChild : public PIndexedDBChild
 {
   IDBFactory* mFactory;
+  ContentChild* mManagerContent;
+  TabChild* mManagerTab;
+
   nsCString mASCIIOrigin;
 
 #ifdef DEBUG
   bool mDisconnected;
 #endif
 
 public:
-  IndexedDBChild(const nsCString& aASCIIOrigin);
+  IndexedDBChild(ContentChild* aContentChild, const nsCString& aASCIIOrigin);
+  IndexedDBChild(TabChild* aTabChild, const nsCString& aASCIIOrigin);
   virtual ~IndexedDBChild();
 
   const nsCString&
   ASCIIOrigin() const
   {
     return mASCIIOrigin;
   }
 
+  ContentChild*
+  GetManagerContent() const
+  {
+    return mManagerContent;
+  }
+
+  TabChild*
+  GetManagerTab() const
+  {
+    return mManagerTab;
+  }
+
   void
   SetFactory(IDBFactory* aFactory);
 
   void
   Disconnect();
 
 protected:
   virtual void