Skip to content
This repository has been archived by the owner on Jan 26, 2022. It is now read-only.

Optimize constructor.resolve lookup #40

Merged
merged 3 commits into from
Apr 16, 2019
Merged

Conversation

gsathya
Copy link
Member

@gsathya gsathya commented Apr 8, 2019

To optimize away the Get and Call of the resolve method on the constructor, I'd have to check the constructor to see if its resolve method has been modified or not. If it's not been modified, I can directly call (or even inline) the builtin %PromiseResolve%, saving the lookup and call overhead for faster performance.

Without this patch, I would have to check against the constructor for every iteration of the loop before going to the fast path.

With this patch, I can do a check against the constructor just once at the beginning.

The change in behavior with this patch is that if you modify the constructor's resolve property in the middle of iterating the iterable argument, then it is not observed. I don't think anyone should do this in any case as it's surprising side-effecting behavior.

Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this change be pursued for https://tc39.github.io/ecma262/#sec-performpromiseall as well?

spec.html Outdated Show resolved Hide resolved
@jridgewell
Copy link
Member

Should this change be pursued for https://tc39.github.io/ecma262/#sec-performpromiseall as well?

Promise.all, Promise.race, and Promse.any's proposal, too.

@ljharb
Copy link
Member

ljharb commented Apr 8, 2019

It kind of seems like before this optimization lands here, there should be some consensus for making the change in the other promise methods?

(Especially since allSettled can’t be polyfilled with Promise.all if there’s an inconsistency)

@gsathya
Copy link
Member Author

gsathya commented Apr 8, 2019

It kind of seems like before this optimization lands here, there should be some consensus for making the change in the other promise methods?

That would mean blocking shipping this until we do the web compat dance for all the other methods, which seems unfortunate.

@ljharb
Copy link
Member

ljharb commented Apr 9, 2019

I agree, but if we end up with a nice table of 4 Promise combinators, per the readme, but 3 of them have one observable behavior and 1 has another, that seems more unfortunate :-/

@mathiasbynens
Copy link
Member

We have successfully made similar changes to the iterator protocol in the past without any web-compat trouble, which makes me hopeful that we'd be able to get away with these changes (to the two existing combinators) as well.

I agree, but if we end up with a nice table of 4 Promise combinators, per the readme, but 3 of them have one observable behavior and 1 has another, that seems more unfortunate :-/

Ack, but note that instead of 3-1 it would be 2-2 (since it seems the 2 new proposals would enable the optimization @gsathya suggested).

cc @anba who has a SpiderMonkey patch.

@gibson042
Copy link
Contributor

I agree with @ljharb; at no point should this proposal specify behavior that differs from already-required common behavior in the other Promise combinators. If we can get Promise.all and Promise.race updated then I'm for this, but not otherwise.

@gsathya
Copy link
Member Author

gsathya commented Apr 10, 2019

Filed tc39/ecma262#1505 to track changes for Promise.all and Promise.race.

I understand the spec consistency argument for having all the promise combinators have the same behavior, but I think it's worthwhile to deviate in this very minor case if it means Promise.allSettled and Promise.any will have better performance.

We should try and change Promise.all and Promise.race -- I will implement this in V8 and get data to see if this possible. But, if we find it web incompatible to change Promise.all and Promise.race, then it's unfortunate that newer features have to pay the price and be slow as well.

@gibson042
Copy link
Contributor

gibson042 commented Apr 10, 2019

Thanks very much for opening the main spec issue!

As for these new functions, I disagree that deviation is worthwhile, and would further caution against overemphasizing the significance of performance upon Promise aggegration, which can surely tolerate some inefficiency.

@mathiasbynens
Copy link
Member

Ok, to summarize the above:

  1. We'll ship the optimization for all existing promise combinators at the same time in V8/Chrome. We're hoping it'll be web-compatible, and will report back otherwise.
  2. I'm merging this PR now.

@mathiasbynens mathiasbynens merged commit d2a5c56 into tc39:master Apr 16, 2019
@gsathya gsathya deleted the patch-3 branch April 18, 2019 05:59
oleavr pushed a commit to frida/v8 that referenced this pull request Apr 26, 2019
In the PerformPromise{All, Race, AllSettled} operations, the resolve
property of the constructor is looked up only once.

In the implementation, for the fast path, where the constructor's
resolve property is untainted, the resolve function is set to undefined.
Since undefined can't be a valid value for the resolve function,
we can switch on it (in CallResolve) to directly call the  PromiseResolve
builtin. If the resolve property is tainted, we do an observable property
lookup, save this value, and call this property later (in CallResolve).

I ran this CL against the test262 tests locally and they all pass:
tc39/test262#2131

Spec:
- tc39/ecma262#1506
- tc39/proposal-promise-allSettled#40

Bug: v8:9152
Change-Id: Icb36a90b5a244a67a729611c7b3315d2c29de6e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1574705
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60957}
mathiasbynens pushed a commit to tc39/proposal-promise-any that referenced this pull request May 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants