Bug 1362910. P1 - enable move when IsExclusive is true. r=gerald

When IsExclusive is true, there is at most only one consumer.
So it is safe to move the ResolveOrRejectValue stored in the promise.

MozReview-Commit-ID: ED9fFr7TkvN

--HG--
extra : rebase_source : 57c6732279a2c76fc21c3e7bad17d70f9cd0834a
extra : intermediate-source : c55836b6708150e88c2ca3a804c2cf2fbcf79990
extra : source : 3285b59746e994283e101cc10267d3a642c96ab3
This commit is contained in:
JW Wang 2017-05-11 01:30:12 +08:00
Родитель 2cdc2fb924
Коммит d45ddf9078
1 изменённых файлов: 30 добавлений и 16 удалений

Просмотреть файл

@ -133,6 +133,15 @@ class MozPromise : public MozPromiseRefcountable
{
static const uint32_t sMagic = 0xcecace11;
// Return a |T&&| to enable move when IsExclusive is true or
// a |const T&| to enforce copy otherwise.
template <typename T,
typename R = typename Conditional<IsExclusive, T&&, const T&>::Type>
static R MaybeMove(T& aX)
{
return static_cast<R>(aX);
}
public:
typedef ResolveValueT ResolveValueType;
typedef RejectValueT RejectValueType;
@ -449,9 +458,9 @@ protected:
}
protected:
virtual already_AddRefed<MozPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) = 0;
virtual already_AddRefed<MozPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) = 0;
void DoResolveOrReject(const ResolveOrRejectValue& aValue)
void DoResolveOrReject(ResolveOrRejectValue& aValue)
{
PROMISE_ASSERT(mMagic1 == sMagic && mMagic2 == sMagic);
MOZ_DIAGNOSTIC_ASSERT(mResponseTarget->IsCurrentThreadIn());
@ -549,13 +558,15 @@ protected:
}
protected:
already_AddRefed<MozPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
already_AddRefed<MozPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
{
RefPtr<MozPromise> completion;
if (aValue.IsResolve()) {
completion = InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aValue.ResolveValue());
completion = InvokeCallbackMethod(
mThisVal.get(), mResolveMethod, MaybeMove(aValue.ResolveValue()));
} else {
completion = InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aValue.RejectValue());
completion = InvokeCallbackMethod(
mThisVal.get(), mRejectMethod, MaybeMove(aValue.RejectValue()));
}
// Null out mThisVal after invoking the callback so that any references are
@ -598,10 +609,10 @@ protected:
}
protected:
already_AddRefed<MozPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
already_AddRefed<MozPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
{
RefPtr<MozPromise> completion =
InvokeCallbackMethod(mThisVal.get(), mResolveRejectMethod, aValue);
RefPtr<MozPromise> completion = InvokeCallbackMethod(
mThisVal.get(), mResolveRejectMethod, MaybeMove(aValue));
// Null out mThisVal after invoking the callback so that any references are
// released predictably on the dispatch thread. Otherwise, it would be
@ -645,7 +656,7 @@ protected:
}
protected:
already_AddRefed<MozPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
already_AddRefed<MozPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
{
// Note: The usage of InvokeCallbackMethod here requires that
// ResolveFunction/RejectFunction are capture-lambdas (i.e. anonymous
@ -654,9 +665,11 @@ protected:
// just capturing something.
RefPtr<MozPromise> completion;
if (aValue.IsResolve()) {
completion = InvokeCallbackMethod(mResolveFunction.ptr(), &ResolveFunction::operator(), aValue.ResolveValue());
completion = InvokeCallbackMethod(mResolveFunction.ptr(),
&ResolveFunction::operator(), MaybeMove(aValue.ResolveValue()));
} else {
completion = InvokeCallbackMethod(mRejectFunction.ptr(), &RejectFunction::operator(), aValue.RejectValue());
completion = InvokeCallbackMethod(mRejectFunction.ptr(),
&RejectFunction::operator(), MaybeMove(aValue.RejectValue()));
}
// Destroy callbacks after invocation so that any references in closures are
@ -700,7 +713,7 @@ protected:
}
protected:
already_AddRefed<MozPromise> DoResolveOrRejectInternal(const ResolveOrRejectValue& aValue) override
already_AddRefed<MozPromise> DoResolveOrRejectInternal(ResolveOrRejectValue& aValue) override
{
// Note: The usage of InvokeCallbackMethod here requires that
// ResolveRejectFunction is capture-lambdas (i.e. anonymous
@ -710,7 +723,7 @@ protected:
RefPtr<MozPromise> completion =
InvokeCallbackMethod(mResolveRejectFunction.ptr(),
&ResolveRejectFunction::operator(),
aValue);
MaybeMove(aValue));
// Destroy callbacks after invocation so that any references in closures are
// released predictably on the dispatch thread. Otherwise, they would be
@ -950,7 +963,8 @@ public:
protected:
bool IsPending() const { return mValue.IsNothing(); }
const ResolveOrRejectValue& Value() const
ResolveOrRejectValue& Value()
{
// This method should only be called once the value has stabilized. As
// such, we don't need to acquire the lock here.
@ -976,9 +990,9 @@ protected:
{
MOZ_ASSERT(!IsPending());
if (mValue.IsResolve()) {
aOther->Resolve(mValue.ResolveValue(), "<chained promise>");
aOther->Resolve(MaybeMove(mValue.ResolveValue()), "<chained promise>");
} else {
aOther->Reject(mValue.RejectValue(), "<chained promise>");
aOther->Reject(MaybeMove(mValue.RejectValue()), "<chained promise>");
}
}