Bug 1451913 P10 Make the inner window explicitly disconnect the IDBFactory. r=baku
authorBen Kelly <ben@wanderview.com>
Mon, 16 Apr 2018 06:08:53 -0700
changeset 467385 ca5da952ff4c690bd34336b8a8aafec06b01e0e8
parent 467384 76afcfbd047bb5131bde2f4f693ee0013bd2ed64
child 467386 d089589540944ed724ec39eb58720cf28f7cf53b
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1451913
milestone61.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 1451913 P10 Make the inner window explicitly disconnect the IDBFactory. r=baku
dom/base/nsGlobalWindowInner.cpp
dom/indexedDB/IDBFactory.cpp
dom/indexedDB/IDBFactory.h
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -1225,17 +1225,20 @@ nsGlobalWindowInner::FreeInnerObjects()
   // Remove our reference to the document and the document principal.
   mFocusedNode = nullptr;
 
   if (mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(mApplicationCache.get())->Disconnect();
     mApplicationCache = nullptr;
   }
 
-  mIndexedDB = nullptr;
+  if (mIndexedDB) {
+    mIndexedDB->DisconnectFromWindow(this);
+    mIndexedDB = nullptr;
+  }
 
   UnlinkHostObjectURIs();
 
   NotifyWindowIDDestroyed("inner-window-destroyed");
 
   CleanupCachedXBLHandlers();
 
   for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) {
@@ -1519,17 +1522,20 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mHistory)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mCustomElements)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLocalStorage)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSessionStorage)
   if (tmp->mApplicationCache) {
     static_cast<nsDOMOfflineResourceList*>(tmp->mApplicationCache.get())->Disconnect();
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplicationCache)
   }
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
+  if (tmp->mIndexedDB) {
+    tmp->mIndexedDB->DisconnectFromWindow(tmp);
+    NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
+  }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentPrincipal)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleService)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mIdleObservers)
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGamepads)
 
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -890,16 +890,26 @@ IDBFactory::RebindToNewWindow(nsPIDOMWin
 
   mWindow = aNewWindow;
 
   mInnerWindowID = aNewWindow->WindowID();
   mWindow->UpdateActiveIndexedDBTransactionCount(mActiveTransactionCount);
   mWindow->UpdateActiveIndexedDBDatabaseCount(mActiveDatabaseCount);
 }
 
+void
+IDBFactory::DisconnectFromWindow(nsPIDOMWindowInner* aOldWindow)
+{
+  MOZ_DIAGNOSTIC_ASSERT(aOldWindow);
+  // If CC unlinks us first, then mWindow might be nullptr
+  MOZ_DIAGNOSTIC_ASSERT(!mWindow || mWindow == aOldWindow);
+
+  mWindow = nullptr;
+}
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(IDBFactory)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(IDBFactory)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IDBFactory)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -225,16 +225,19 @@ public:
                      const nsAString& aName,
                      const IDBOpenDBOptions& aOptions,
                      SystemCallerGuarantee,
                      ErrorResult& aRv);
 
   void
   RebindToNewWindow(nsPIDOMWindowInner* aNewWindow);
 
+  void
+  DisconnectFromWindow(nsPIDOMWindowInner* aOldWindow);
+
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IDBFactory)
 
   // nsWrapperCache
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 private: