Bug 1376936 - nsContentLists should stop observing mutations when their refcnt drops to 0, r=ehsan
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 29 Jun 2017 13:25:15 +0300
changeset 366835 0cec50535e2c38b00e8ed3a1a29be4d4935757be
parent 366687 17153099b556f1aefcf9c48582f34a68f9528e9a
child 366836 9120668e5a82faeaa98df34616355620ea774c8e
push id32109
push usercbook@mozilla.com
push dateFri, 30 Jun 2017 11:00:05 +0000
treeherdermozilla-central@d536973fe668 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1376936
milestone56.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 1376936 - nsContentLists should stop observing mutations when their refcnt drops to 0, r=ehsan
dom/base/nsContentList.cpp
dom/base/nsContentList.h
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -86,17 +86,18 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_E
 NS_INTERFACE_TABLE_HEAD(nsBaseContentList)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE(nsBaseContentList, nsINodeList, nsIDOMNodeList)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsBaseContentList)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsBaseContentList)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBaseContentList)
+NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(nsBaseContentList,
+                                                   LastRelease())
 
 
 NS_IMETHODIMP
 nsBaseContentList::GetLength(uint32_t* aLength)
 {
   *aLength = mElements.Length();
 
   return NS_OK;
@@ -587,16 +588,27 @@ nsContentList::NodeWillBeDestroyed(const
   RemoveFromCaches();
   mRootNode = nullptr;
 
   // We will get no more updates, so we can never know we're up to
   // date
   SetDirty();
 }
 
+void
+nsContentList::LastRelease()
+{
+  RemoveFromCaches();
+  if (mRootNode) {
+    mRootNode->RemoveMutationObserver(this);
+    mRootNode = nullptr;
+  }
+  SetDirty();
+}
+
 NS_IMETHODIMP
 nsContentList::GetLength(uint32_t* aLength)
 {
   *aLength = Length(true);
 
   return NS_OK;
 }
 
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -90,16 +90,19 @@ public:
 
   virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
     override = 0;
 
   void SetCapacity(uint32_t aCapacity)
   {
     mElements.SetCapacity(aCapacity);
   }
+
+  virtual void LastRelease() {}
+
 protected:
   virtual ~nsBaseContentList();
 
   /**
    * To be called from non-destructor locations (e.g. unlink) that want to
    * remove from caches.  Cacheable subclasses should override.
    */
   virtual void RemoveFromCaches()
@@ -347,16 +350,18 @@ public:
    * @note This is the only acceptable way to set state to LIST_DIRTY.
    */
   void SetDirty()
   {
     mState = LIST_DIRTY;
     Reset();
   }
 
+  virtual void LastRelease() override;
+
 protected:
   /**
    * Returns whether the element matches our criterion
    *
    * @param  aElement the element to attempt to match
    * @return whether we match
    */
   bool Match(mozilla::dom::Element *aElement);