Bug 1202085 - Part 6: Clear the entries in the image cache belonging to a controlled document when it gets destroyed; r=seth
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 28 Oct 2015 16:01:07 -0400
changeset 270510 e08508d502c88b8f95baa1b8e72f159d6d27934d
parent 270509 e221700129d556b8976a802cdbdab35adc9a51b7
child 270511 d68a55e2c1baaa6376b1b5fc4c24c38d1f53dff9
push id16027
push userphilringnalda@gmail.com
push dateSun, 01 Nov 2015 00:26:11 +0000
treeherderfx-team@96377bdbcdf3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs1202085
milestone45.0a1
Bug 1202085 - Part 6: Clear the entries in the image cache belonging to a controlled document when it gets destroyed; r=seth
dom/base/nsDocument.cpp
image/ImageCacheKey.h
image/imgICache.idl
image/imgLoader.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -65,17 +65,18 @@
 #include "nsRange.h"
 #include "nsIDOMText.h"
 #include "nsIDOMComment.h"
 #include "mozilla/dom/DocumentType.h"
 #include "mozilla/dom/NodeIterator.h"
 #include "mozilla/dom/TreeWalker.h"
 
 #include "nsIServiceManager.h"
-#include "nsIServiceWorkerManager.h"
+#include "mozilla/dom/workers/ServiceWorkerManager.h"
+#include "imgLoader.h"
 
 #include "nsCanvasFrame.h"
 #include "nsContentCID.h"
 #include "nsError.h"
 #include "nsPresShell.h"
 #include "nsPresContext.h"
 #include "nsIJSON.h"
 #include "nsThreadUtils.h"
@@ -8888,18 +8889,23 @@ nsDocument::Destroy()
 
   // Shut down our external resource map.  We might not need this for
   // leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
   // tearing down all those frame trees right now is the right thing to do.
   mExternalResourceMap.Shutdown();
 
   mRegistry = nullptr;
 
-  nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
+  using mozilla::dom::workers::ServiceWorkerManager;
+  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
   if (swm) {
+    ErrorResult error;
+    if (swm->IsControlled(this, error)) {
+      nsContentUtils::GetImgLoaderForDocument(this)->ClearCacheForControlledDocument(this);
+    }
     swm->MaybeStopControlling(this);
   }
 
   // XXX We really should let cycle collection do this, but that currently still
   //     leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
   ReleaseWrapper(static_cast<nsINode*>(this));
 }
 
--- a/image/ImageCacheKey.h
+++ b/image/ImageCacheKey.h
@@ -41,16 +41,20 @@ public:
   uint32_t Hash() const { return mHash; }
 
   /// A weak pointer to the URI spec for this cache entry. For logging only.
   const char* Spec() const;
 
   /// Is this cache entry for a chrome image?
   bool IsChrome() const { return mIsChrome; }
 
+  /// A token indicating which service worker controlled document this entry
+  /// belongs to, if any.
+  void* ControlledDocument() const { return mControlledDocument; }
+
 private:
   static uint32_t ComputeHash(ImageURL* aURI,
                               const Maybe<uint64_t>& aBlobSerial,
                               void* aControlledDocument);
   static void* GetControlledDocumentToken(nsIDOMDocument* aDocument);
 
   RefPtr<ImageURL> mURI;
   Maybe<uint64_t> mBlobSerial;
--- a/image/imgICache.idl
+++ b/image/imgICache.idl
@@ -2,28 +2,29 @@
  *
  * 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 "nsISupports.idl"
 
 interface imgIRequest;
+interface nsIDocument;
 interface nsIDOMDocument;
 interface nsIProperties;
 interface nsIURI;
 
 /**
  * imgICache interface
  *
  * @author Stuart Parmenter <pavlov@netscape.com>
  * @version 0.1
  * @see imagelib2
  */
-[scriptable, builtinclass, uuid(6c1e3f96-4701-4c75-9883-217a790a53e2)]
+[scriptable, builtinclass, uuid(bfdf23ff-378e-402e-8a6c-840f0c82b6c3)]
 interface imgICache : nsISupports
 {
   /**
    * Evict images from the cache.
    *
    * @param chrome If TRUE,  evict only chrome images.
    *               If FALSE, evict everything except chrome images.
    */
@@ -47,9 +48,16 @@ interface imgICache : nsISupports
   nsIProperties findEntryProperties(in nsIURI uri, [optional] in nsIDOMDocument doc);
 
   /**
    * Make this cache instance respect private browsing notifications. This
    * entails clearing the chrome and content caches whenever the
    * last-pb-context-exited notification is observed.
    */
   void respectPrivacyNotifications();
+
+  /**
+   * Clear the image cache for a document.  Controlled documents are responsible
+   * for doing this manually when they get destroyed.
+   */
+  [noscript, notxpcom]
+  void clearCacheForControlledDocument(in nsIDocument doc);
 };
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -1356,16 +1356,35 @@ imgLoader::FindEntryProperties(nsIURI* u
       nsCOMPtr<nsIProperties> properties = request->Properties();
       properties.forget(_retval);
     }
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP_(void)
+imgLoader::ClearCacheForControlledDocument(nsIDocument* aDoc)
+{
+  MOZ_ASSERT(aDoc);
+  nsAutoTArray<RefPtr<imgCacheEntry>, 128> entriesToBeRemoved;
+  imgCacheTable& cache = GetCache(false);
+  for (auto iter = cache.Iter(); !iter.Done(); iter.Next()) {
+    auto& key = iter.Key();
+    if (key.ControlledDocument() == aDoc) {
+      entriesToBeRemoved.AppendElement(iter.Data());
+    }
+  }
+  for (auto& entry : entriesToBeRemoved) {
+    if (!RemoveFromCache(entry)) {
+      NS_WARNING("Couldn't remove an entry from the cache in ClearCacheForControlledDocument()\n");
+    }
+  }
+}
+
 void
 imgLoader::Shutdown()
 {
   NS_IF_RELEASE(gSingleton);
   NS_IF_RELEASE(gPBSingleton);
 }
 
 nsresult