From 73ad7b6505cfa9e40b1072c4e0f37a3cb2c4ebb2 Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Mon, 24 Aug 2026 14:55:44 +0100 Subject: [PATCH] lib: optimize async context frame activation Signed-off-by: Tim Perry --- lib/internal/async_context_frame.js | 66 +++++++++++++---------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/lib/internal/async_context_frame.js b/lib/internal/async_context_frame.js index cac193e33188..cd03eafe6fa6 100644 --- a/lib/internal/async_context_frame.js +++ b/lib/internal/async_context_frame.js @@ -1,7 +1,6 @@ 'use strict'; const { - ObjectSetPrototypeOf, SafeMap, } = primordials; @@ -10,45 +9,22 @@ const { setContinuationPreservedEmbedderData, } = internalBinding('async_context_frame'); -let enabled_; - -class ActiveAsyncContextFrame extends SafeMap { - static get enabled() { - return true; - } - - static current() { - return getContinuationPreservedEmbedderData(); - } - - static set(frame) { - setContinuationPreservedEmbedderData(frame); - } - - static exchange(frame) { - const prior = this.current(); - this.set(frame); - return prior; - } - - static disable(store) { - const frame = this.current(); - frame?.disable(store); - } +function activeCurrent() { + return getContinuationPreservedEmbedderData(); } -function checkEnabled() { - const enabled = require('internal/options') - .getOptionValue('--async-context-frame'); +function activeSet(frame) { + setContinuationPreservedEmbedderData(frame); +} - // If enabled, swap to active prototype so we don't need to check status - // on every interaction with the async context frame. - if (enabled) { - // eslint-disable-next-line no-use-before-define - ObjectSetPrototypeOf(AsyncContextFrame, ActiveAsyncContextFrame); - } +function activeExchange(frame) { + const prior = getContinuationPreservedEmbedderData(); + setContinuationPreservedEmbedderData(frame); + return prior; +} - return enabled; +function activeDisable(store) { + getContinuationPreservedEmbedderData()?.disable(store); } class InactiveAsyncContextFrame extends SafeMap { @@ -74,4 +50,22 @@ class AsyncContextFrame extends InactiveAsyncContextFrame { } } +let enabled_; + +function checkEnabled() { + const enabled = require('internal/options') + .getOptionValue('--async-context-frame'); + + // If enabled, install the active implementations directly. We use props + // rather than a prototype replacement to preserve V8 optimizations. + if (enabled) { + AsyncContextFrame.current = activeCurrent; + AsyncContextFrame.set = activeSet; + AsyncContextFrame.exchange = activeExchange; + AsyncContextFrame.disable = activeDisable; + } + + return enabled; +} + module.exports = AsyncContextFrame;