-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
async_wrap,src: wrap promises directly #13224
Conversation
Original commit message: Allow embedder to set promise internal field count Asynchronous context tracking mechanisms in Node.js need to store some state on all promise objects. This change will allow embedders to configure the number of internal fields on promises as is already done for ArrayBuffers. BUG=v8:6435 Review-Url: https://codereview.chromium.org/2889863002 Cr-Commit-Position: refs/heads/master@{#45496}
Promises do not have any internal fields by default. V8 recently added the capability of configuring the number of internal fields on promises. This change adds an internal field to promises allowing promises to be wrapped directly by the PromiseWrap object. In addition to cleaner code this avoids an extra object allocation per promise and speeds up promise creation with async_hooks enabled by ~2x.
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.
Thanks, looks good to me!
env->promise_async_tag(), | ||
obj, hidden).FromJust(); | ||
PromiseWrap* wrap = new PromiseWrap(env, promise); | ||
promise->SetAlignedPointerInInternalField(0, wrap); |
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.
Wait… doesn’t this leak the PromiseWrap
memory? V8 doesn’t know that this is a pointer to something it can/should garbage collect. I think promise->SetInternalField(0, wrap->object());
should work?
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.
LGTM, although I'm not completely sharp on the V8 specifics.
promise->DefineOwnProperty(context, | ||
env->promise_async_tag(), | ||
obj, hidden).FromJust(); | ||
PromiseWrap* wrap = new PromiseWrap(env, promise); |
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.
This makes the resource
that the init
callback sees the Promise itself, right? /cc @Fishrock123
@matthewloring This should be enough to close the memory leak: diff --git a/src/async-wrap.cc b/src/async-wrap.cc
index 4a210741bedc..b1f651c12d8d 100644
--- a/src/async-wrap.cc
+++ b/src/async-wrap.cc
@@ -282,12 +282,11 @@ static void PromiseHook(PromiseHookType type, Local<Promise> promise,
Environment* env = Environment::GetCurrent(context);
if (type == PromiseHookType::kInit) {
PromiseWrap* wrap = new PromiseWrap(env, promise);
- promise->SetAlignedPointerInInternalField(0, wrap);
+ wrap->MakeWeak(wrap);
} else if (type == PromiseHookType::kResolve) {
// TODO(matthewloring): need to expose this through the async hooks api.
}
- PromiseWrap* wrap =
- static_cast<PromiseWrap*>(promise->GetAlignedPointerFromInternalField(0));
+ PromiseWrap* wrap = Unwrap<PromiseWrap>(promise);
CHECK_NE(wrap, nullptr);
if (type == PromiseHookType::kBefore) {
PreCallbackExecution(wrap, false); |
@addaleax @matthewloring anything holding us back from applying the memory fix and merging this? |
I guess it technically violates the 72-hour rule, but as mentioned in #13242 (comment) I would be okay with merging this (or both PRs) now. |
I see. This is on the |
Landed in 849f223 |
Promises do not have any internal fields by default. V8 recently added the capability of configuring the number of internal fields on promises. This change adds an internal field to promises allowing promises to be wrapped directly by the PromiseWrap object. In addition to cleaner code this avoids an extra object allocation per promise and speeds up promise creation with async_hooks enabled by ~2x. PR-URL: #13242 Ref: #13224 Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Promises do not have any internal fields by default. V8 recently added the capability of configuring the number of internal fields on promises. This change adds an internal field to promises allowing promises to be wrapped directly by the PromiseWrap object. In addition to cleaner code this avoids an extra object allocation per promise and speeds up promise creation with async_hooks enabled by ~2x. PR-URL: #13242 Ref: #13224 Reviewed-By: Andreas Madsen <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Promises do not have any internal fields by default. V8 recently added
the capability of configuring the number of internal fields on promises.
This change adds an internal field to promises allowing promises to be
wrapped directly by the PromiseWrap object. In addition to cleaner code
this avoids an extra object allocation per promise and speeds up promise
creation with async_hooks enabled by ~2x.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
async_wrap, src