Bug 1499725 - make IdleTaskRunner timers more efficient; r=farre
authorNathan Froyd <froydnj@mozilla.com>
Mon, 22 Oct 2018 09:44:50 -0400
changeset 490645 7b36a8c21a150097364be7d4642904bc2051e93c
parent 490642 74061c1b02a17da7d3e346d5c1e1a6cfd3e561b4
child 490646 52ad8c18256e6d42be6512514c0867977527fedb
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersfarre
bugs1499725
milestone64.0a1
Bug 1499725 - make IdleTaskRunner timers more efficient; r=farre Instead of creating a timer and then setting the timer's target, we can determine the timer's target and pass it in directly when the timer is created. This reordering of steps is slightly more efficient, since SetTarget() is both a virtual call and requires locking, both of which can be skipped if we know the target at timer creation time. If we're reusing the timer, we also don't need to repeatedly set the timer's target: we can set the target once at timer creation, and then be done. We can do this safely here because mTaskCategory doesn't change throughout the life of the IdleTaskRunner; we make mTaskCategory `const` to make this more explicit to the reader.
xpcom/threads/IdleTaskRunner.cpp
xpcom/threads/IdleTaskRunner.h
--- a/xpcom/threads/IdleTaskRunner.cpp
+++ b/xpcom/threads/IdleTaskRunner.cpp
@@ -141,26 +141,27 @@ IdleTaskRunner::Schedule(bool aAllowIdle
   } else {
     // RefreshDriver doesn't seem to be running.
     if (aAllowIdleDispatch) {
       nsCOMPtr<nsIRunnable> runnable = this;
       SetTimerInternal(mDelay);
       NS_IdleDispatchToCurrentThread(runnable.forget());
     } else {
       if (!mScheduleTimer) {
-        mScheduleTimer = NS_NewTimer();
+        nsIEventTarget* target = nullptr;
+        if (TaskCategory::Count != mTaskCategory) {
+          target = SystemGroup::EventTargetFor(mTaskCategory);
+        }
+        mScheduleTimer = NS_NewTimer(target);
         if (!mScheduleTimer) {
           return;
         }
       } else {
         mScheduleTimer->Cancel();
       }
-      if (TaskCategory::Count != mTaskCategory) {
-        mScheduleTimer->SetTarget(SystemGroup::EventTargetFor(mTaskCategory));
-      }
       // We weren't allowed to do idle dispatch immediately, do it after a
       // short timeout.
       mScheduleTimer->InitWithNamedFuncCallback(ScheduleTimedOut, this, 16,
                                                 nsITimer::TYPE_ONE_SHOT_LOW_PRIORITY,
                                                 mName);
     }
   }
 }
@@ -186,25 +187,26 @@ IdleTaskRunner::CancelTimer()
 void
 IdleTaskRunner::SetTimerInternal(uint32_t aDelay)
 {
   if (mTimerActive) {
     return;
   }
 
   if (!mTimer) {
-    mTimer = NS_NewTimer();
+    nsIEventTarget* target = nullptr;
+    if (TaskCategory::Count != mTaskCategory) {
+      target = SystemGroup::EventTargetFor(mTaskCategory);
+    }
+    mTimer = NS_NewTimer(target);
   } else {
     mTimer->Cancel();
   }
 
   if (mTimer) {
-    if (TaskCategory::Count != mTaskCategory) {
-      mTimer->SetTarget(SystemGroup::EventTargetFor(mTaskCategory));
-    }
     mTimer->InitWithNamedFuncCallback(TimedOut, this, aDelay,
                                       nsITimer::TYPE_ONE_SHOT,
                                       mName);
     mTimerActive = true;
   }
 }
 
 } // end of namespace mozilla
--- a/xpcom/threads/IdleTaskRunner.h
+++ b/xpcom/threads/IdleTaskRunner.h
@@ -61,15 +61,15 @@ private:
   nsCOMPtr<nsITimer> mScheduleTimer;
   CallbackType mCallback;
   uint32_t mDelay;
   TimeStamp mDeadline;
   TimeDuration mBudget;
   bool mRepeating;
   bool mTimerActive;
   MayStopProcessingCallbackType mMayStopProcessing;
-  TaskCategory mTaskCategory;
+  const TaskCategory mTaskCategory;
   const char* mName;
 };
 
 } // end of namespace mozilla.
 
 #endif