-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Editorial: refactor PerformPromiseThen to allow no capability #1146
Conversation
Search for "throwawayCapability" |
578f37b
to
a1234e9
Compare
@domenic thanks, updated! |
a1234e9
to
9a77b53
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few small things missing. Sorry for the massive delay!
spec.html
Outdated
1. If _resultCapability_ is present, then | ||
1. Assert: _resultCapability_ is a PromiseCapability Record. | ||
1. Else, | ||
1. Set _resultCapability to *undefined*. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing _
I think maybe you should use "Let" here instead of "Set" since the variable doesn't technically exist yet? (Which might argue for moving the else clause into a single line, so the "block scoping" is less confusing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable exists because it's in the abstract operation signature, so I think "Set" is correct.
Thanks, I've added the underscore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I guess that depends on how you interpret "is present", but your way makes sense too.
spec.html
Outdated
@@ -38204,7 +38202,7 @@ <h1>AsyncGeneratorRequest Records</h1> | |||
</tr> | |||
<tr> | |||
<td>[[Capability]]</td> | |||
<td>A PromiseCapability record</td> | |||
<td>A PromiseCapability record, or *undefined*</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant to edit PromiseReaction, not AsyncGeneratorRequest.
spec.html
Outdated
@@ -39095,11 +39094,14 @@ <h1>Promise.prototype.then ( _onFulfilled_, _onRejected_ )</h1> | |||
|
|||
<!-- es6num="25.4.5.3.1" --> | |||
<emu-clause id="sec-performpromisethen" aoid="PerformPromiseThen"> | |||
<h1>PerformPromiseThen ( _promise_, _onFulfilled_, _onRejected_, _resultCapability_ )</h1> | |||
<h1>PerformPromiseThen ( _promise_, _onFulfilled_, _onRejected_ [ , _resultCapability_ ] )</h1> | |||
<p>The abstract operation PerformPromiseThen performs the “then” operation on _promise_ using _onFulfilled_ and _onRejected_ as its settlement actions. The result is _resultCapability_'s promise.</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should modify the intro text. Suggestion:
If resultCapability is passed, the result is stored by updating resultCapability's promise. (If it is not passed, then PerformPromiseThen is being called by a specification-internal operation where the result does not matter.)
9a77b53
to
71e8b85
Compare
Thanks, updated! |
71e8b85
to
414666d
Compare
I don't like spending resources on snapshots, but whatevs... |
@MayaLekova We chatted about this change and it sounded like you might have had some reservations about it. Are any embedding environments depending on the throwaway Promise, based on embedder-specific hooks into the Promise lifecycle, even if it's unobservable without those hooks? |
For now it seems we won't fire the promise hooks on the throwawayPromise, don't know if this is the only change. @ak239 - please comment as well! |
On DevTools side to implement async stacks we rely on kBefore and kAfter hook calls for throwaway promise:
From implementation point of view I believe we can instrument microtask by itself with inspector-only hooks or we can stop using promise hooks at all by proper instrumentation async function suspended, async function resumed and async function finished. It will work for us but I am not sure about some external developers who relies on promise hooks. |
@ak239 Could you explain more how DevTools currently takes advantage of the kBefore and kAfter events related to the throwawayPromise? |
When function is suspended we get instrumentation call with async function promise as argument and record stack trace for this promise. As external developer I think that I can use:
What we actually would like to have: instrumentation every time when async function suspended, every time when async function is resumed and once when async function finished. |
On inspector side we can implement required for us instrumentation without using I am not sure how important it is to provide these hooks for developers. |
@littledan @domenic @ljharb Any other roadblocks left to have this merged? |
414666d
to
689a396
Compare
689a396
to
5e93e1b
Compare
5e93e1b
to
a7139c5
Compare
…o capability". This implements the editorial change in tc39/ecma262#1146 which removes the need to allocate the throwaway promise in await (the throwaway promise was not exposed to user JavaScript anyways, but this spec change allows us to rely on this behavior). Now we still need the throwaway promise for proper before and after events with both DevTools (which might change) and PromiseHooks. So if either DevTools or PromiseHooks is on, we call into %AwaitPromisesInit, which then allocates the throwaway promise and does all the other debugger/hooks related setup. This gives around 7% improvement on the doxbee-async-es2017-native and around 1-2% on the parallel-async-es2017-native benchmarks. Bug: v8:7253, v8:8285 Ref: tc39/ecma262#1146 Tbr: [email protected] Change-Id: I972ba0538ec8c00808e95b183603025c7e55a6d3 Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;luci.chromium.try:linux_chromium_rel_ng;master.tryserver.blink:linux_trusty_blink_rel Reviewed-on: https://chromium-review.googlesource.com/c/1270798 Commit-Queue: Benedikt Meurer <[email protected]> Reviewed-by: Benedikt Meurer <[email protected]> Reviewed-by: Maya Lekova <[email protected]> Reviewed-by: Sathya Gunasekaran <[email protected]> Cr-Commit-Position: refs/heads/master@{#56506}
This CL introduces a new fast-path for `Promise.all(a)` for the case that elements in `a` are native promises, and the Promise.prototype and Promise function itself are intact. If so, we can skip the lookups of "resolve" on Promise and "then" on the result of invoking "resolve", which are both quite expensive, and we can instead directly call the PerformPromiseThen() operation on the element of `a`. In addition to that we don't need to create and chain a result promise, since this is only used when either async_hooks or DevTools are enabled. Otherwise it's a "throwaway promise" only used to satisfy the operation parameter signature (see tc39/ecma262#1146). This results in a significant performance improvement on `Promise.all()` heavy code. For example the parallel-promises-es2015-native test goes from around 84ms to roughly 68ms, which is almost a 20% improvement. Bug: v8:7253 Ref: tc39/ecma262#1146 Change-Id: Iab9c57edb26d13a467b0653fd8de6149c382efc6 Reviewed-on: https://chromium-review.googlesource.com/c/1293374 Reviewed-by: Sathya Gunasekaran <[email protected]> Reviewed-by: Maya Lekova <[email protected]> Commit-Queue: Benedikt Meurer <[email protected]> Cr-Commit-Position: refs/heads/master@{#56858}
Fixes #694.
I followed @domenic's steps in the linked issue here; I'm not sure if other changes are needed.
Specifically, which
PerformPromiseThen
calls should now be able to omit a capability?