Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject - r=jwwang
authorGerald Squelart <gsquelart@mozilla.com>
Sat, 21 Jan 2017 12:24:10 +1100
changeset 465478 839e34051bf99b49f80893f80b40e4873a251ae1
parent 464951 726ee922483f6e3e12a2921fbcdbe7c5616aafe8
child 465479 5561d78059791fa8859c2ac041af383653376b78
push id42606
push usergsquelart@mozilla.com
push dateTue, 24 Jan 2017 05:22:29 +0000
reviewersjwwang
bugs1332785, 1331137
milestone53.0a1
Bug 1332785 - Optimize MozPromiseHolder::Resolve and Reject - r=jwwang 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