Bug 1349683: Give RevocableEventPtr a "move" assignment operator, and use it to reduce refcount churn. r? draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Wed, 19 Jul 2017 00:03:59 -0700
changeset 611080 bbd4e8caf861e3a035a663d14924da236d38ef07
parent 611022 6ddefe2ca9db02afd1615b14f4e0bf8a0a686558
child 638066 e82708fd01889bcc4ada8d5bb4b8732e93f655a9
push id69119
push userdholbert@mozilla.com
push dateWed, 19 Jul 2017 07:04:37 +0000
bugs1349683
milestone56.0a1
Bug 1349683: Give RevocableEventPtr a "move" assignment operator, and use it to reduce refcount churn. r? MozReview-Commit-ID: 9JQXZJqebm2
dom/base/Selection.cpp
dom/base/nsDocument.cpp
layout/base/PresShell.cpp
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsTextControlFrame.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
xpcom/threads/nsThreadUtils.h
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -3497,21 +3497,20 @@ Selection::PostScrollSelectionIntoViewEv
   // processed before we scroll. This will insure that we scroll to the
   // correct place on screen.
   mScrollEvent.Revoke();
   nsPresContext* presContext = GetPresContext();
   NS_ENSURE_STATE(presContext);
   nsRefreshDriver* refreshDriver = presContext->RefreshDriver();
   NS_ENSURE_STATE(refreshDriver);
 
-  RefPtr<ScrollSelectionIntoViewEvent> ev =
+  mScrollEvent =
     new ScrollSelectionIntoViewEvent(this, aRegion, aVertical, aHorizontal,
                                      aFlags);
-  mScrollEvent = ev;
-  refreshDriver->AddEarlyRunner(ev);
+  refreshDriver->AddEarlyRunner(mScrollEvent.get());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Selection::ScrollIntoView(SelectionRegion aRegion, bool aIsSynchronous,
                           int16_t aVPercent, int16_t aHPercent)
 {
   ErrorResult result;
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7039,17 +7039,17 @@ nsDocument::NotifyPossibleTitleChange(bo
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   RefPtr<nsRunnableMethod<nsDocument, void, false>> event =
     NewNonOwningRunnableMethod("nsDocument::DoNotifyPossibleTitleChange",
                                this,
                                &nsDocument::DoNotifyPossibleTitleChange);
   nsresult rv = Dispatch("nsDocument::DoNotifyPossibleTitleChange",
                          TaskCategory::Other, do_AddRef(event));
   if (NS_SUCCEEDED(rv)) {
-    mPendingTitleChangeEvent = event;
+    mPendingTitleChangeEvent = Move(event);
   }
 }
 
 void
 nsDocument::DoNotifyPossibleTitleChange()
 {
   mPendingTitleChangeEvent.Forget();
   mHaveFiredTitleChange = true;
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -2027,17 +2027,17 @@ PresShell::ResizeReflowIgnoreOverride(ns
       }
     } else {
       RefPtr<nsRunnableMethod<PresShell>> event = NewRunnableMethod(
         "PresShell::FireResizeEvent", this, &PresShell::FireResizeEvent);
       nsresult rv = mDocument->Dispatch("PresShell::FireResizeEvent",
                                         TaskCategory::Other,
                                         do_AddRef(event));
       if (NS_SUCCEEDED(rv)) {
-        mResizeEvent = event;
+        mResizeEvent = Move(event);
         SetNeedStyleFlush();
       }
     }
   }
 
   return NS_OK; //XXX this needs to be real. MMP
 }
 
@@ -5539,17 +5539,17 @@ void PresShell::SynthesizeMouseMove(bool
         new nsSynthMouseMoveEvent(this, aFromScroll);
 
     if (!GetPresContext()->RefreshDriver()
                          ->AddRefreshObserver(ev, FlushType::Display)) {
       NS_WARNING("failed to dispatch nsSynthMouseMoveEvent");
       return;
     }
 
-    mSynthMouseMoveEvent = ev;
+    mSynthMouseMoveEvent = Move(ev);
   }
 }
 
 /**
  * Find the first floating view with a widget in a postorder traversal of the
  * view tree that contains the point. Thus more deeply nested floating views
  * are preferred over their ancestors, and floating views earlier in the
  * view hierarchy (i.e., added later) are preferred over their siblings.
@@ -6222,17 +6222,17 @@ PresShell::ScheduleApproximateFrameVisib
                       this,
                       &PresShell::UpdateApproximateFrameVisibility);
   nsresult rv =
     mDocument->Dispatch("PresShell::UpdateApproximateFrameVisibility",
                         TaskCategory::Other,
                         do_AddRef(event));
 
   if (NS_SUCCEEDED(rv)) {
-    mUpdateApproximateFrameVisibilityEvent = event;
+    mUpdateApproximateFrameVisibilityEvent = Move(event);
   }
 }
 
 void
 PresShell::EnsureFrameInApproximatelyVisibleList(nsIFrame* aFrame)
 {
   if (!aFrame->TrackingVisibility()) {
     return;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -1014,19 +1014,18 @@ nsComboboxControlFrame::RedisplayText()
     // Revoke outstanding events to avoid out-of-order events which could mean
     // displaying the wrong text.
     mRedisplayTextEvent.Revoke();
 
     NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
                  "If we happen to run our redisplay event now, we might kill "
                  "ourselves!");
 
-    RefPtr<RedisplayTextEvent> event = new RedisplayTextEvent(this);
-    mRedisplayTextEvent = event;
-    nsContentUtils::AddScriptRunner(event);
+    mRedisplayTextEvent = new RedisplayTextEvent(this);
+    nsContentUtils::AddScriptRunner(mRedisplayTextEvent.get());
   }
   return rv;
 }
 
 void
 nsComboboxControlFrame::HandleRedisplayTextEvent()
 {
   // First, make sure that the content model is up to date and we've
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -669,17 +669,17 @@ void nsTextControlFrame::SetFocus(bool a
       }
     }
     if (!(lastFocusMethod & nsIFocusManager::FLAG_BYMOUSE)) {
       RefPtr<ScrollOnFocusEvent> event = new ScrollOnFocusEvent(this);
       nsresult rv = mContent->OwnerDoc()->Dispatch("ScrollOnFocusEvent",
                                                    TaskCategory::Other,
                                                    do_AddRef(event));
       if (NS_SUCCEEDED(rv)) {
-        mScrollEvent = event;
+        mScrollEvent = Move(event);
       }
     }
   }
 
   // tell the caret to use our selection
   caret->SetSelection(ourSel);
 
   // mutual-exclusion: the selection is either controlled by the
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -4780,17 +4780,17 @@ nsTreeBodyFrame::PostScrollEvent()
 
   RefPtr<ScrollEvent> event = new ScrollEvent(this);
   nsresult rv = mContent->OwnerDoc()->Dispatch("ScrollEvent",
                                                TaskCategory::Other,
                                                do_AddRef(event));
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to dispatch ScrollEvent");
   } else {
-    mScrollEvent = event;
+    mScrollEvent = Move(event);
   }
 }
 
 void
 nsTreeBodyFrame::ScrollbarActivityStarted() const
 {
   if (mScrollbarActivity) {
     mScrollbarActivity->ActivityStarted();
--- a/xpcom/threads/nsThreadUtils.h
+++ b/xpcom/threads/nsThreadUtils.h
@@ -1607,31 +1607,21 @@ NewNonOwningIdleRunnableMethod(const cha
 //
 template<class T>
 class nsRevocableEventPtr
 {
 public:
   nsRevocableEventPtr() : mEvent(nullptr) {}
   ~nsRevocableEventPtr() { Revoke(); }
 
-  const nsRevocableEventPtr& operator=(T* aEvent)
+  const nsRevocableEventPtr& operator=(RefPtr<T>&& aEvent)
   {
     if (mEvent != aEvent) {
       Revoke();
-      mEvent = aEvent;
-    }
-    return *this;
-  }
-
-  const nsRevocableEventPtr& operator=(already_AddRefed<T> aEvent)
-  {
-    RefPtr<T> event = aEvent;
-    if (mEvent != event) {
-      Revoke();
-      mEvent = event.forget();
+      mEvent = Move(aEvent);
     }
     return *this;
   }
 
   void Revoke()
   {
     if (mEvent) {
       mEvent->Revoke();