-
Notifications
You must be signed in to change notification settings - Fork 29.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
async_hooks: use new v8::Context PromiseHook API
PR-URL: #36394 Reviewed-By: Bryan English <bryan@bryanenglish.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: James M Snell <jasnell@gmail.com>
- Loading branch information
Showing
2 changed files
with
59 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ const { | |
ErrorCaptureStackTrace, | ||
ObjectPrototypeHasOwnProperty, | ||
ObjectDefineProperty, | ||
Promise, | ||
Symbol, | ||
} = primordials; | ||
|
||
|
@@ -53,7 +52,7 @@ const { | |
clearAsyncIdStack, | ||
} = async_wrap; | ||
// For performance reasons, only track Promises when a hook is enabled. | ||
const { enablePromiseHook, disablePromiseHook } = async_wrap; | ||
const { enablePromiseHook, disablePromiseHook, setPromiseHooks } = async_wrap; | ||
// Properties in active_hooks are used to keep track of the set of hooks being | ||
// executed in case another hook is enabled/disabled. The new set of hooks is | ||
// then restored once the active set of hooks is finished executing. | ||
|
@@ -303,71 +302,68 @@ function restoreActiveHooks() { | |
active_hooks.tmp_fields = null; | ||
} | ||
|
||
function trackPromise(promise, parent, silent) { | ||
const asyncId = getOrSetAsyncId(promise); | ||
function trackPromise(promise, parent) { | ||
if (promise[async_id_symbol]) { | ||
return; | ||
} | ||
|
||
promise[async_id_symbol] = newAsyncId(); | ||
promise[trigger_async_id_symbol] = parent ? getOrSetAsyncId(parent) : | ||
getDefaultTriggerAsyncId(); | ||
} | ||
|
||
if (!silent && initHooksExist()) { | ||
const triggerId = promise[trigger_async_id_symbol]; | ||
emitInitScript(asyncId, 'PROMISE', triggerId, promise); | ||
} | ||
function promiseInitHook(promise, parent) { | ||
trackPromise(promise, parent); | ||
const asyncId = promise[async_id_symbol]; | ||
const triggerAsyncId = promise[trigger_async_id_symbol]; | ||
emitInitScript(asyncId, 'PROMISE', triggerAsyncId, promise); | ||
} | ||
|
||
function fastPromiseHook(type, promise, parent) { | ||
if (type === kInit || !promise[async_id_symbol]) { | ||
const silent = type !== kInit; | ||
if (parent instanceof Promise) { | ||
trackPromise(promise, parent, silent); | ||
} else { | ||
trackPromise(promise, null, silent); | ||
} | ||
function promiseBeforeHook(promise) { | ||
trackPromise(promise); | ||
const asyncId = promise[async_id_symbol]; | ||
const triggerId = promise[trigger_async_id_symbol]; | ||
emitBeforeScript(asyncId, triggerId, promise); | ||
} | ||
|
||
if (!silent) return; | ||
function promiseAfterHook(promise) { | ||
trackPromise(promise); | ||
const asyncId = promise[async_id_symbol]; | ||
if (hasHooks(kAfter)) { | ||
emitAfterNative(asyncId); | ||
} | ||
if (asyncId === executionAsyncId()) { | ||
// This condition might not be true if async_hooks was enabled during | ||
// the promise callback execution. | ||
// Popping it off the stack can be skipped in that case, because it is | ||
// known that it would correspond to exactly one call with | ||
// PromiseHookType::kBefore that was not witnessed by the PromiseHook. | ||
popAsyncContext(asyncId); | ||
} | ||
} | ||
|
||
function promiseResolveHook(promise) { | ||
trackPromise(promise); | ||
const asyncId = promise[async_id_symbol]; | ||
switch (type) { | ||
case kBefore: | ||
const triggerId = promise[trigger_async_id_symbol]; | ||
emitBeforeScript(asyncId, triggerId, promise); | ||
break; | ||
case kAfter: | ||
if (hasHooks(kAfter)) { | ||
emitAfterNative(asyncId); | ||
} | ||
if (asyncId === executionAsyncId()) { | ||
// This condition might not be true if async_hooks was enabled during | ||
// the promise callback execution. | ||
// Popping it off the stack can be skipped in that case, because it is | ||
// known that it would correspond to exactly one call with | ||
// PromiseHookType::kBefore that was not witnessed by the PromiseHook. | ||
popAsyncContext(asyncId); | ||
} | ||
break; | ||
case kPromiseResolve: | ||
emitPromiseResolveNative(asyncId); | ||
break; | ||
} | ||
emitPromiseResolveNative(asyncId); | ||
} | ||
|
||
let wantPromiseHook = false; | ||
function enableHooks() { | ||
async_hook_fields[kCheck] += 1; | ||
} | ||
|
||
let promiseHookMode = -1; | ||
function updatePromiseHookMode() { | ||
wantPromiseHook = true; | ||
if (destroyHooksExist()) { | ||
if (promiseHookMode !== 1) { | ||
promiseHookMode = 1; | ||
enablePromiseHook(); | ||
} | ||
} else if (promiseHookMode !== 0) { | ||
promiseHookMode = 0; | ||
enablePromiseHook(fastPromiseHook); | ||
enablePromiseHook(); | ||
} else { | ||
setPromiseHooks( | ||
initHooksExist() ? promiseInitHook : undefined, | ||
promiseBeforeHook, | ||
promiseAfterHook, | ||
promiseResolveHooksExist() ? promiseResolveHook : undefined, | ||
); | ||
} | ||
} | ||
|
||
|
@@ -383,8 +379,8 @@ function disableHooks() { | |
|
||
function disablePromiseHookIfNecessary() { | ||
if (!wantPromiseHook) { | ||
promiseHookMode = -1; | ||
disablePromiseHook(); | ||
setPromiseHooks(undefined, undefined, undefined, undefined); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
Trott
Member
|
||
} | ||
} | ||
|
||
|
@@ -458,6 +454,10 @@ function destroyHooksExist() { | |
return hasHooks(kDestroy); | ||
} | ||
|
||
function promiseResolveHooksExist() { | ||
return hasHooks(kPromiseResolve); | ||
} | ||
|
||
|
||
function emitInitScript(asyncId, type, triggerAsyncId, resource) { | ||
// Short circuit all checks for the common case. Which is that no hooks have | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
why we cant use
setPromiseHooks()
instead?