Bug 1031967 - Make mozilla::css::Loader cycle collected and traverse its observer array. r=bzbarsky
authorCameron McCormack <cam@mcc.id.au>
Wed, 02 Jul 2014 08:37:09 +1000
changeset 212593 ed5afdaaa6d38651fac803721e4fb2b4e69f93ad
parent 212592 b796d6062a9834c43ef3466a168d8e03e48f3bd1
child 212594 b8eccf3af85550627ea6e139e02b981a18d1dee6
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1031967
milestone33.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 1031967 - Make mozilla::css::Loader cycle collected and traverse its observer array. r=bzbarsky
content/base/src/nsDocument.cpp
layout/style/Loader.cpp
layout/style/Loader.h
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1979,19 +1979,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   if (tmp->mAnimationController) {
     tmp->mAnimationController->Traverse(&cb);
   }
 
   if (tmp->mSubDocuments && tmp->mSubDocuments->ops) {
     PL_DHashTableEnumerate(tmp->mSubDocuments, SubDocTraverser, &cb);
   }
 
-  if (tmp->mCSSLoader) {
-    tmp->mCSSLoader->TraverseCachedSheets(cb);
-  }
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCSSLoader)
 
   for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
     nsHostObjectProtocolHandler::Traverse(tmp->mHostObjectURIs[i], cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
 
@@ -2078,19 +2076,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   tmp->mExpandoAndGeneration.Unlink();
 
   if (tmp->mAnimationController) {
     tmp->mAnimationController->Unlink();
   }
 
   tmp->mPendingTitleChangeEvent.Revoke();
 
-  if (tmp->mCSSLoader) {
-    tmp->mCSSLoader->UnlinkCachedSheets();
-  }
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mCSSLoader)
 
   for (uint32_t i = 0; i < tmp->mHostObjectURIs.Length(); ++i) {
     nsHostObjectProtocolHandler::RemoveDataEntry(tmp->mHostObjectURIs[i]);
   }
 
   tmp->mInUnlinkOrDeletion = false;
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -56,17 +56,16 @@
 #endif
 
 #include "nsIMediaList.h"
 #include "nsIDOMStyleSheet.h"
 #include "nsError.h"
 
 #include "nsIChannelPolicy.h"
 #include "nsIContentSecurityPolicy.h"
-#include "nsCycleCollectionParticipant.h"
 
 #include "mozilla/dom/EncodingUtils.h"
 using mozilla::dom::EncodingUtils;
 
 using namespace mozilla::dom;
 
 /**
  * OVERALL ARCHITECTURE
@@ -2449,31 +2448,39 @@ TraverseSheet(URIPrincipalAndCORSModeHas
 {
   nsCycleCollectionTraversalCallback* cb =
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "Sheet cache nsCSSLoader");
   cb->NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIStyleSheet*, aSheet));
   return PL_DHASH_NEXT;
 }
 
-void
-Loader::TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb)
-{
-  if (mSheets) {
-    mSheets->mCompleteSheets.EnumerateRead(TraverseSheet, &cb);
-  }
-}
+NS_IMPL_CYCLE_COLLECTION_CLASS(Loader)
 
-void
-Loader::UnlinkCachedSheets()
-{
-  if (mSheets) {
-    mSheets->mCompleteSheets.Clear();
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Loader)
+  if (tmp->mSheets) {
+    tmp->mSheets->mCompleteSheets.EnumerateRead(TraverseSheet, &cb);
+  }
+  nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver>>::ForwardIterator
+    it(tmp->mObservers);
+  while (it.HasMore()) {
+    ImplCycleCollectionTraverse(cb, it.GetNext(),
+                                "mozilla::css::Loader.mObservers");
   }
-}
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Loader)
+  if (tmp->mSheets) {
+    tmp->mSheets->mCompleteSheets.Clear();
+  }
+  tmp->mObservers.Clear();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Loader, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Loader, Release)
 
 struct SheetMemoryCounter {
   size_t size;
   mozilla::MallocSizeOf mallocSizeOf;
 };
 
 static size_t
 CountSheetMemory(URIPrincipalAndCORSModeHashKey* /* unused */,
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -6,16 +6,17 @@
 /* loading of CSS style sheets using the network APIs */
 
 #ifndef mozilla_css_Loader_h
 #define mozilla_css_Loader_h
 
 #include "nsIPrincipal.h"
 #include "nsAutoPtr.h"
 #include "nsCompatibility.h"
+#include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsRefPtrHashtable.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
 #include "nsTObserverArray.h"
 #include "nsURIHashKey.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/CORSMode.h"
@@ -131,17 +132,18 @@ public:
   Loader();
   Loader(nsIDocument*);
 
  private:
   // Private destructor, to discourage deletion outside of Release():
   ~Loader();
 
  public:
-  NS_INLINE_DECL_REFCOUNTING(Loader)
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Loader)
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(Loader)
 
   void DropDocumentReference(); // notification that doc is going away
 
   void SetCompatibilityMode(nsCompatibility aCompatMode)
   { mCompatMode = aCompatMode; }
   nsCompatibility GetCompatibilityMode() { return mCompatMode; }
   nsresult SetPreferredSheet(const nsAString& aTitle);
 
@@ -360,24 +362,16 @@ public:
   // within nsCSSLoader.cpp.
 
   // IsAlternate can change our currently selected style set if none
   // is selected and aHasAlternateRel is false.
   bool IsAlternate(const nsAString& aTitle, bool aHasAlternateRel);
 
   typedef nsTArray<nsRefPtr<SheetLoadData> > LoadDataArray;
 
-  // Traverse the cached stylesheets we're holding on to.  This should
-  // only be called from the document that owns this loader.
-  void TraverseCachedSheets(nsCycleCollectionTraversalCallback& cb);
-
-  // Unlink the cached stylesheets we're holding on to.  Again, this
-  // should only be called from the document that owns this loader.
-  void UnlinkCachedSheets();
-
   // Measure our size.
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
   // Marks all the sheets at the given URI obsolete, and removes them from the
   // cache.
   nsresult ObsoleteSheet(nsIURI* aURI);
 
 private:
@@ -492,17 +486,16 @@ private:
   // some.  Allocate some storage, what the hell.
   nsAutoTArray<SheetLoadData*, 8> mParsingDatas;
 
   // The array of posted stylesheet loaded events (SheetLoadDatas) we have.
   // Note that these are rare.
   LoadDataArray     mPostedEvents;
 
   // Our array of "global" observers
-  // XXXbz these are strong refs; should we be cycle collecting CSS loaders?
   nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
 
   // the load data needs access to the document...
   nsIDocument*      mDocument;  // the document we live for
 
 
   // Number of datas still waiting to be notified on if we're notifying on a
   // whole bunch at once (e.g. in one of the stop methods).  This is used to