Bug 1332825 - Use move semantics in MozPromise::All() and AllPromiseHolder.

MozPromise::All sets up 'Then' lambdas on all sub-promises, each one
taking the resolve/reject object by value. Since this value will not be
used again in the lambda, it is safe to Move it, and from there
MozPromiseHolder::Resolve/Reject can also Move it again into the holder
storage, potentially saving two copies per Resolve/Reject. Also, once
all sub-promises have been resolved, the resolve-values can be Move'd
into the joining promise's Resolve function.
This commit is contained in:
Gerald Squelart 2023-11-19 13:10:29 +01:00 • committed by roytam1
commit 543e41f3ac

View file

@ -229,35 +229,35 @@ private:
mResolveValues.SetLength(aDependentPromises); mResolveValues.SetLength(aDependentPromises);
} }
void Resolve(size_t aIndex, const ResolveValueType& aResolveValue) void Resolve(size_t aIndex, ResolveValueType&& aResolveValue)
{ {
if (!mPromise) { if (!mPromise) {
// Already rejected. // Already rejected.
return; return;
} }
mResolveValues[aIndex].emplace(aResolveValue); mResolveValues[aIndex].emplace(Move(aResolveValue));
if (--mOutstandingPromises == 0) { if (--mOutstandingPromises == 0) {
nsTArray<ResolveValueType> resolveValues; nsTArray<ResolveValueType> resolveValues;
resolveValues.SetCapacity(mResolveValues.Length()); resolveValues.SetCapacity(mResolveValues.Length());
for (size_t i = 0; i < mResolveValues.Length(); ++i) { for (size_t i = 0; i < mResolveValues.Length(); ++i) {
resolveValues.AppendElement(mResolveValues[i].ref()); resolveValues.AppendElement(Move(mResolveValues[i].ref()));
} }
mPromise->Resolve(resolveValues, __func__); mPromise->Resolve(Move(resolveValues), __func__);
mPromise = nullptr; mPromise = nullptr;
mResolveValues.Clear(); mResolveValues.Clear();
} }
} }
void Reject(const RejectValueType& aRejectValue) void Reject(RejectValueType&& aRejectValue)
{ {
if (!mPromise) { if (!mPromise) {
// Already rejected. // Already rejected.
return; return;
} }
mPromise->Reject(aRejectValue, __func__); mPromise->Reject(Move(aRejectValue), __func__);
mPromise = nullptr; mPromise = nullptr;
mResolveValues.Clear(); mResolveValues.Clear();
} }
@ -276,8 +276,8 @@ public:
RefPtr<AllPromiseHolder> holder = new AllPromiseHolder(aPromises.Length()); RefPtr<AllPromiseHolder> holder = new AllPromiseHolder(aPromises.Length());
for (size_t i = 0; i < aPromises.Length(); ++i) { for (size_t i = 0; i < aPromises.Length(); ++i) {
aPromises[i]->Then(aProcessingThread, __func__, aPromises[i]->Then(aProcessingThread, __func__,
[holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, aResolveValue); }, [holder, i] (ResolveValueType aResolveValue) -> void { holder->Resolve(i, Move(aResolveValue)); },
[holder] (RejectValueType aRejectValue) -> void { holder->Reject(aRejectValue); } [holder] (RejectValueType aRejectValue) -> void { holder->Reject(Move(aRejectValue)); }
); );
} }
return holder->Promise(); return holder->Promise();