Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject - r?froydnj draft
authorGerald Squelart <gsquelart@mozilla.com>
Sat, 21 Jan 2017 12:24:10 +1100
changeset 464552 f7d0bb3be0c4e8688a8e5940bce81df19e5b7f4c
parent 464206 3cedab21a7e65e6a1c4c2294ecfb5502575a46e3
child 542933 c1e09d4e72bf3816e15b1fb0e72b242803bb7ea2
push id42367
push usergsquelart@mozilla.com
push dateSat, 21 Jan 2017 02:04:09 +0000
reviewersfroydnj
bugs1332785, 1331137
milestone53.0a1
Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject - r?froydnj Instead of lvalues, MozPromiseHolder::Resolve and Reject now take either const& or && values of the expected types, to allow move semantics all the way to the ResolveOrRejectValue object. Note that we won't just take forwarding references of any type, as this could lead to implicit conversions by bypassing the 'explicit' marker of the value type constructors, like in bug 1331137. MozReview-Commit-ID: K0jeY6WTXI1
xpcom/threads/MozPromise.h
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -992,55 +992,87 @@ public:
       mMonitor->AssertCurrentThreadOwns();
     }
 
     RefPtr<typename PromiseType::Private> p = mPromise;
     mPromise = nullptr;
     return p.forget();
   }
 
-  void Resolve(typename PromiseType::ResolveValueType aResolveValue,
+  void Resolve(const typename PromiseType::ResolveValueType& aResolveValue,
                const char* aMethodName)
   {
     if (mMonitor) {
       mMonitor->AssertCurrentThreadOwns();
     }
     MOZ_ASSERT(mPromise);
     mPromise->Resolve(aResolveValue, aMethodName);
     mPromise = nullptr;
   }
-
+  void Resolve(typename PromiseType::ResolveValueType&& aResolveValue,
+               const char* aMethodName)
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    MOZ_ASSERT(mPromise);
+    mPromise->Resolve(Move(aResolveValue), aMethodName);
+    mPromise = nullptr;
+  }
 
-  void ResolveIfExists(typename PromiseType::ResolveValueType aResolveValue,
+  void ResolveIfExists(const typename PromiseType::ResolveValueType& aResolveValue,
                        const char* aMethodName)
   {
     if (!IsEmpty()) {
       Resolve(aResolveValue, aMethodName);
     }
   }
+  void ResolveIfExists(typename PromiseType::ResolveValueType&& aResolveValue,
+                       const char* aMethodName)
+  {
+    if (!IsEmpty()) {
+      Resolve(Move(aResolveValue), aMethodName);
+    }
+  }
 
-  void Reject(typename PromiseType::RejectValueType aRejectValue,
+  void Reject(const typename PromiseType::RejectValueType& aRejectValue,
               const char* aMethodName)
   {
     if (mMonitor) {
       mMonitor->AssertCurrentThreadOwns();
     }
     MOZ_ASSERT(mPromise);
     mPromise->Reject(aRejectValue, aMethodName);
     mPromise = nullptr;
   }
-
+  void Reject(typename PromiseType::RejectValueType&& aRejectValue,
+              const char* aMethodName)
+  {
+    if (mMonitor) {
+      mMonitor->AssertCurrentThreadOwns();
+    }
+    MOZ_ASSERT(mPromise);
+    mPromise->Reject(Move(aRejectValue), aMethodName);
+    mPromise = nullptr;
+  }
 
-  void RejectIfExists(typename PromiseType::RejectValueType aRejectValue,
+  void RejectIfExists(const typename PromiseType::RejectValueType& aRejectValue,
                       const char* aMethodName)
   {
     if (!IsEmpty()) {
       Reject(aRejectValue, aMethodName);
     }
   }
+  void RejectIfExists(typename PromiseType::RejectValueType&& aRejectValue,
+                      const char* aMethodName)
+  {
+    if (!IsEmpty()) {
+      Reject(Move(aRejectValue), aMethodName);
+    }
+  }
 
 private:
   Monitor* mMonitor;
   RefPtr<typename PromiseType::Private> mPromise;
 };
 
 /*
  * Class to encapsulate a MozPromise::Request reference. Use this as the member