Bug 1291665 - Unregister from refresh driver in DocumentTimeline::Unlink; r=hiro
authorBrian Birtles <birtles@gmail.com>
Wed, 17 Aug 2016 09:53:22 +0900
changeset 309772 3f9686fc43a6e58d383ec1bdc10eae3072943c71
parent 309771 2d422399bc48b3c212e42bc2bda6a4588e62f941
child 309773 4af8f838049d613be0c1a413ea8ce61350453b89
push id30570
push userkwierso@gmail.com
push dateWed, 17 Aug 2016 23:38:48 +0000
treeherdermozilla-central@a70835fe9f55 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershiro
bugs1291665
milestone51.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 1291665 - Unregister from refresh driver in DocumentTimeline::Unlink; r=hiro
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;