Bug 1286183 - Improve SVGEffects' unlinking. r=mstange
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 15 Jul 2016 02:40:30 +0300
changeset 388543 0a961f12af55e9e54dfc6fcb3caf4155244c9e5e
parent 388462 0d82d5d030afa2e8f48dd68e86eb75efd0947a5c
child 388544 1254b1288956b90865c746f416b387417dea773e
push id23207
push userrthijssen@mozilla.com
push dateSat, 16 Jul 2016 09:33:55 +0000
reviewersmstange
bugs1286183
milestone50.0a1
Bug 1286183 - Improve SVGEffects' unlinking. r=mstange
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -233,17 +233,26 @@ nsSVGRenderingObserverProperty::DoUpdate
       frame->GetContent()->AsElement(), nsRestyleHint(0),
       nsChangeHint_InvalidateRenderingObservers);
   }
 }
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGFilterReference)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGFilterReference)
 
-NS_IMPL_CYCLE_COLLECTION(nsSVGFilterReference, mElement)
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGFilterReference)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsSVGFilterReference)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsSVGFilterReference)
+  tmp->StopListening();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGFilterReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsSVGIDRenderingObserver)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsISVGFilterReference)
 NS_INTERFACE_MAP_END
 
 nsSVGFilterFrame *
@@ -261,40 +270,47 @@ nsSVGFilterReference::DoUpdate()
   if (mFilterChainObserver) {
     mFilterChainObserver->Invalidate();
   }
 }
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGFilterChainObserver)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGFilterChainObserver)
 
+NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGFilterChainObserver)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsSVGFilterChainObserver)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReferences)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsSVGFilterChainObserver)
+  tmp->DetachReferences();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mReferences);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGFilterChainObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION(nsSVGFilterChainObserver, mReferences)
-
 nsSVGFilterChainObserver::nsSVGFilterChainObserver(const nsTArray<nsStyleFilter>& aFilters,
                                                    nsIContent* aFilteredElement)
 {
   for (uint32_t i = 0; i < aFilters.Length(); i++) {
     if (aFilters[i].GetType() != NS_STYLE_FILTER_URL)
       continue;
 
     RefPtr<nsSVGFilterReference> reference =
       new nsSVGFilterReference(aFilters[i].GetURL(), aFilteredElement, this);
     mReferences.AppendElement(reference);
   }
 }
 
 nsSVGFilterChainObserver::~nsSVGFilterChainObserver()
 {
-  for (uint32_t i = 0; i < mReferences.Length(); i++) {
-    mReferences[i]->DetachFromChainObserver();
-  }
+  DetachReferences();
 }
 
 bool
 nsSVGFilterChainObserver::ReferencesValidResources()
 {
   for (uint32_t i = 0; i < mReferences.Length(); i++) {
     if (!mReferences[i]->ReferencesValidResource())
       return false;
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -266,16 +266,24 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS(nsSVGFilterChainObserver)
 
 protected:
   virtual ~nsSVGFilterChainObserver();
 
   virtual void DoUpdate() = 0;
 
 private:
+
+  void DetachReferences()
+  {
+    for (uint32_t i = 0; i < mReferences.Length(); i++) {
+      mReferences[i]->DetachFromChainObserver();
+    }
+  }
+
   nsTArray<RefPtr<nsSVGFilterReference>> mReferences;
 };
 
 class nsSVGFilterProperty : public nsSVGFilterChainObserver
 {
 public:
   nsSVGFilterProperty(const nsTArray<nsStyleFilter> &aFilters,
                       nsIFrame *aFilteredFrame)