async_wrap,src: wrap promises directly#13224
async_wrap,src: wrap promises directly#13224matthewloring wants to merge 2 commits intonodejs:masterfrom matthewloring:promise-hook-opt
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.
| env->promise_async_tag(), | ||
| obj, hidden).FromJust(); | ||
| PromiseWrap* wrap = new PromiseWrap(env, promise); | ||
| promise->SetAlignedPointerInInternalField(0, wrap); |
There was a problem hiding this comment.
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?
| promise->DefineOwnProperty(context, | ||
| env->promise_async_tag(), | ||
| obj, hidden).FromJust(); | ||
| PromiseWrap* wrap = new PromiseWrap(env, promise); |
There was a problem hiding this comment.
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