Bug 1291665 - Unregister from refresh driver in DocumentTimeline::Unlink. r=hiro, a=abillings
authorBrian Birtles <birtles@gmail.com>
Wed, 17 Aug 2016 09:53:22 +0900
changeset 332776 a55ede08a8bad53f6fbecf32aea2df6e28980e7f
parent 332775 84b11aee0b433f8ca33c870804965f5f9e952261
child 332777 0b2e1f4c1af39800b1e33d2f2e5e88f9aee5e8a0
push id9921
push userryanvm@gmail.com
push dateFri, 19 Aug 2016 02:21:12 +0000
treeherdermozilla-aurora@0b2e1f4c1af3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershiro, abillings
bugs1291665
milestone50.0a2
Bug 1291665 - Unregister from refresh driver in DocumentTimeline::Unlink. r=hiro, a=abillings
dom/animation/DocumentTimeline.cpp
dom/animation/DocumentTimeline.h
--- a/dom/animation/DocumentTimeline.cpp
+++ b/dom/animation/DocumentTimeline.cpp
@@ -12,18 +12,26 @@
 #include "nsDOMNavigationTiming.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsRefreshDriver.h"
 
 namespace mozilla {
 namespace dom {
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED(DocumentTimeline, AnimationTimeline,
-                                   mDocument)
+NS_IMPL_CYCLE_COLLECTION_CLASS(DocumentTimeline)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DocumentTimeline,
+                                                AnimationTimeline)
+  tmp->UnregisterFromRefreshDriver();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DocumentTimeline,
+                                                  AnimationTimeline)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DocumentTimeline,
                                                AnimationTimeline)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DocumentTimeline)
 NS_INTERFACE_MAP_END_INHERITING(AnimationTimeline)
 
@@ -174,18 +182,17 @@ DocumentTimeline::WillRefresh(mozilla::T
   if (!needsTicks) {
     // We already assert that GetRefreshDriver() is non-null at the beginning
     // of this function but we check it again here to be sure that ticking
     // animations does not have any side effects that cause us to lose the
     // connection with the refresh driver, such as triggering the destruction
     // of mDocument's PresShell.
     MOZ_ASSERT(GetRefreshDriver(),
                "Refresh driver should still be valid at end of WillRefresh");
-    GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
-    mIsObservingRefreshDriver = false;
+    UnregisterFromRefreshDriver();
   }
 }
 
 void
 DocumentTimeline::NotifyRefreshDriverCreated(nsRefreshDriver* aDriver)
 {
   MOZ_ASSERT(!mIsObservingRefreshDriver,
              "Timeline should not be observing the refresh driver before"
@@ -209,21 +216,17 @@ DocumentTimeline::NotifyRefreshDriverDes
 }
 
 void
 DocumentTimeline::RemoveAnimation(Animation* aAnimation)
 {
   AnimationTimeline::RemoveAnimation(aAnimation);
 
   if (mIsObservingRefreshDriver && mAnimations.IsEmpty()) {
-    MOZ_ASSERT(GetRefreshDriver(),
-               "Refresh driver should still be valid when "
-               "mIsObservingRefreshDriver is true");
-    GetRefreshDriver()->RemoveRefreshObserver(this, Flush_Style);
-    mIsObservingRefreshDriver = false;
+    UnregisterFromRefreshDriver();
   }
 }
 
 TimeStamp
 DocumentTimeline::ToTimeStamp(const TimeDuration& aTimeDuration) const
 {
   TimeStamp result;
   RefPtr<nsDOMNavigationTiming> timing = mDocument->GetNavigationTiming();
@@ -247,10 +250,26 @@ DocumentTimeline::GetRefreshDriver() con
   nsPresContext* presContext = presShell->GetPresContext();
   if (MOZ_UNLIKELY(!presContext)) {
     return nullptr;
   }
 
   return presContext->RefreshDriver();
 }
 
+void
+DocumentTimeline::UnregisterFromRefreshDriver()
+{
+  if (!mIsObservingRefreshDriver) {
+    return;
+  }
+
+  nsRefreshDriver* refreshDriver = GetRefreshDriver();
+  if (!refreshDriver) {
+    return;
+  }
+
+  refreshDriver->RemoveRefreshObserver(this, Flush_Style);
+  mIsObservingRefreshDriver = false;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/DocumentTimeline.h
+++ b/dom/animation/DocumentTimeline.h
@@ -78,16 +78,17 @@ public:
   void WillRefresh(TimeStamp aTime) override;
 
   void NotifyRefreshDriverCreated(nsRefreshDriver* aDriver);
   void NotifyRefreshDriverDestroying(nsRefreshDriver* aDriver);
 
 protected:
   TimeStamp GetCurrentTimeStamp() const;
   nsRefreshDriver* GetRefreshDriver() const;
+  void UnregisterFromRefreshDriver();
 
   nsCOMPtr<nsIDocument> mDocument;
 
   // The most recently used refresh driver time. This is used in cases where
   // we don't have a refresh driver (e.g. because we are in a display:none
   // iframe).
   mutable TimeStamp mLastRefreshDriverTime;
   bool mIsObservingRefreshDriver;