Commit 41c875a6 authored by gsathya's avatar gsathya Committed by Commit bot

Promises: Short circuit promise resolution procedure

When |ResolvePromise| is resolved with a promise that is
already fulfilled or resolved, we can short circuit the
promise resolution procedure by directly looking up the
result from the promise. We save creating two closures, enqueuing in
the promise queue, and running through PromiseThen.

This patch uses IsPromise to check if the |resolution| object is a native
promise and also checks if |resolution.then| hasn't been monkey
patched.

This patch adds some redundant code from PromiseThen like setting
the promiseHasHandlerSymbol and calling PromiseRevokeReject call,
which would've been taken care of by PromiseThen in the old code path.

This patch results in a 13.8% improvement(over 5 runs) in the bluebird
benchmarks.

BUG=v8:5046

Review-Url: https://codereview.chromium.org/2028253004
Cr-Commit-Position: refs/heads/master@{#36765}
parent 59785f9e
......@@ -250,6 +250,33 @@ function ResolvePromise(promise, resolution) {
} catch (e) {
return RejectPromise(promise, e);
}
// Resolution is a native promise and if it's already resolved or
// rejected, shortcircuit the resolution procedure by directly
// reusing the value from the promise.
if (IsPromise(resolution) && then === PromiseThen) {
var thenableState = GET_PRIVATE(resolution, promiseStateSymbol);
if (thenableState === kFulfilled) {
// This goes inside the if-else to save one symbol lookup in
// the slow path.
var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
FulfillPromise(promise, kFulfilled, thenableValue,
promiseFulfillReactionsSymbol);
SET_PRIVATE(promise, promiseHasHandlerSymbol, true);
return;
} else if (thenableState === kRejected) {
var thenableValue = GET_PRIVATE(resolution, promiseResultSymbol);
if (!HAS_DEFINED_PRIVATE(resolution, promiseHasHandlerSymbol)) {
// Promise has already been rejected, but had no handler.
// Revoke previously triggered reject event.
%PromiseRevokeReject(resolution);
}
RejectPromise(promise, thenableValue);
SET_PRIVATE(resolution, promiseHasHandlerSymbol, true);
return;
}
}
if (IS_CALLABLE(then)) {
// PromiseResolveThenableJob
var id, name, instrumenting = DEBUG_IS_ACTIVE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment