Bug 1363676. P1 - use Variant as the internal storage of ResolveOrRejectValue. r=gerald
authorJW Wang <jwwang@mozilla.com>
Tue, 09 May 2017 18:24:18 +0800
changeset 357673 5fb3ab3d4ce8cb62dd1439102dca2dffc4ebdf89
parent 357672 b8e7b44f30502c7e048e2b72c8047f9f5185fc83
child 357674 9547fbdccbed18da0d1e912e7d6fce49287906e8
push id42444
push userjwwang@mozilla.com
push dateThu, 11 May 2017 02:28:55 +0000
treeherderautoland@9547fbdccbed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1363676
milestone55.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 1363676. P1 - use Variant as the internal storage of ResolveOrRejectValue. r=gerald MozReview-Commit-ID: 4B3M3hvfvyz
xpcom/threads/MozPromise.h
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -10,16 +10,17 @@
 #include "mozilla/AbstractThread.h"
 #include "mozilla/IndexSequence.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Tuple.h"
 #include "mozilla/TypeTraits.h"
+#include "mozilla/Variant.h"
 
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA)
 #define PROMISE_DEBUG
 #endif
 
@@ -132,29 +133,42 @@ class MozPromise : public MozPromiseRefc
 {
   static const uint32_t sMagic = 0xcecace11;
 
 public:
   typedef ResolveValueT ResolveValueType;
   typedef RejectValueT RejectValueType;
   class ResolveOrRejectValue
   {
+    template <int, typename T>
+    struct Holder
+    {
+      template <typename... Args>
+      explicit Holder(Args&&... aArgs) : mData(Forward<Args>(aArgs)...) { }
+      T mData;
+    };
+
+    // Ensure Holder<0, T1> and Holder<1, T2> are different types
+    // which is required by Variant.
+    using ResolveValueHolder = Holder<0, ResolveValueType>;
+    using RejectValueHolder = Holder<1, RejectValueType>;
+
   public:
     template<typename ResolveValueType_>
     void SetResolve(ResolveValueType_&& aResolveValue)
     {
       MOZ_ASSERT(IsNothing());
-      mResolveValue.emplace(Forward<ResolveValueType_>(aResolveValue));
+      mValue = AsVariant(ResolveValueHolder(Forward<ResolveValueType_>(aResolveValue)));
     }
 
     template<typename RejectValueType_>
     void SetReject(RejectValueType_&& aRejectValue)
     {
       MOZ_ASSERT(IsNothing());
-      mRejectValue.emplace(Forward<RejectValueType_>(aRejectValue));
+      mValue = AsVariant(RejectValueHolder(Forward<RejectValueType_>(aRejectValue)));
     }
 
     template<typename ResolveValueType_>
     static ResolveOrRejectValue MakeResolve(ResolveValueType_&& aResolveValue)
     {
       ResolveOrRejectValue val;
       val.SetResolve(Forward<ResolveValueType_>(aResolveValue));
       return val;
@@ -163,26 +177,39 @@ public:
     template<typename RejectValueType_>
     static ResolveOrRejectValue MakeReject(RejectValueType_&& aRejectValue)
     {
       ResolveOrRejectValue val;
       val.SetReject(Forward<RejectValueType_>(aRejectValue));
       return val;
     }
 
-    bool IsResolve() const { return mResolveValue.isSome(); }
-    bool IsReject() const { return mRejectValue.isSome(); }
-    bool IsNothing() const { return mResolveValue.isNothing() && mRejectValue.isNothing(); }
+    bool IsResolve() const { return mValue.template is<ResolveValueHolder>(); }
+    bool IsReject() const { return mValue.template is<RejectValueHolder>(); }
+    bool IsNothing() const { return mValue.template is<Nothing>(); }
 
-    const ResolveValueType& ResolveValue() const { return mResolveValue.ref(); }
-    const RejectValueType& RejectValue() const { return mRejectValue.ref(); }
+    const ResolveValueType& ResolveValue() const
+    {
+      return mValue.template as<ResolveValueHolder>().mData;
+    }
+    ResolveValueType& ResolveValue()
+    {
+      return mValue.template as<ResolveValueHolder>().mData;
+    }
+    const RejectValueType& RejectValue() const
+    {
+      return mValue.template as<RejectValueHolder>().mData;
+    }
+    RejectValueType& RejectValue()
+    {
+      return mValue.template as<RejectValueHolder>().mData;
+    }
 
   private:
-    Maybe<ResolveValueType> mResolveValue;
-    Maybe<RejectValueType> mRejectValue;
+    Variant<Nothing, ResolveValueHolder, RejectValueHolder> mValue = AsVariant(Nothing{});
   };
 
 protected:
   // MozPromise is the public type, and never constructed directly. Construct
   // a MozPromise::Private, defined below.
   MozPromise(const char* aCreationSite, bool aIsCompletionPromise)
     : mCreationSite(aCreationSite)
     , mMutex("MozPromise Mutex")