Skip to content
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

Closed
wants to merge 2 commits into from
Closed

async_wrap,src: wrap promises directly #13224

wants to merge 2 commits into from

Conversation

matthewloring
Copy link

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), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

async_wrap, src

Matt Loring added 2 commits May 25, 2017 10:50
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.
@nodejs-github-bot nodejs-github-bot added async_wrap build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. v8 engine Issues and PRs related to the V8 dependency. labels May 25, 2017
@matthewloring matthewloring added this to the 8.0.0 milestone May 25, 2017
addaleax
addaleax previously approved these changes May 25, 2017
Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

env->promise_async_tag(),
obj, hidden).FromJust();
PromiseWrap* wrap = new PromiseWrap(env, promise);
promise->SetAlignedPointerInInternalField(0, wrap);
Copy link
Member

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?

Copy link
Member

@AndreasMadsen AndreasMadsen left a 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);
Copy link
Member

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

@addaleax addaleax dismissed their stale review May 25, 2017 19:31

got some more questions

@addaleax
Copy link
Member

addaleax commented May 26, 2017

@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/node@0ec3eba)

@AndreasMadsen
Copy link
Member

@addaleax @matthewloring anything holding us back from applying the memory fix and merging this?

@addaleax
Copy link
Member

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.

@AndreasMadsen
Copy link
Member

I see. This is on the 8.0.0 milestone so let's just wait another day. I don't expect many conflicts.

@addaleax
Copy link
Member

Landed in 849f223

@addaleax addaleax closed this May 28, 2017
addaleax pushed a commit that referenced this pull request May 28, 2017
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]>
jasnell pushed a commit that referenced this pull request May 28, 2017
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]>
@matthewloring matthewloring deleted the promise-hook-opt branch August 22, 2017 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. v8 engine Issues and PRs related to the V8 dependency.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants