Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 0f6a35669fa8e3e9b3aa37e9778611a5eadaf674
https://github.com/WebKit/WebKit/commit/0f6a35669fa8e3e9b3aa37e9778611a5eadaf674
Author: Sosuke Suzuki <[email protected]>
Date: 2026-05-16 (Sat, 16 May 2026)
Changed paths:
M Source/JavaScriptCore/interpreter/Interpreter.cpp
M Source/JavaScriptCore/runtime/JSMicrotask.cpp
M Source/JavaScriptCore/runtime/JSPromise.cpp
M Source/JavaScriptCore/runtime/JSPromise.h
M Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
M Source/JavaScriptCore/runtime/JSPromiseReaction.cpp
M Source/JavaScriptCore/runtime/Microtask.h
Log Message:
-----------
[JSC] Avoid per-element `JSPromiseCombinatorsContext` allocation in Promise
combinators
https://bugs.webkit.org/show_bug.cgi?id=314861
Reviewed by Yusuke Suzuki.
After 313230@main, an element promise in Promise.all/allSettled/any stores its
inline
internal-microtask reaction as (m_packed.pointer() = outerPromise, m_slot =
JSPromiseCombinatorsContext). The JSPromiseCombinatorsContext is a 32-byte heap
cell
pairing (globalContext, index), allocated once per element on the fast path.
Since the
inline reaction already has two slots, this patch stores globalContext directly
as the
payload cell and the element index as jsNumber() in the slot, eliminating the
per-element
allocation. The outer promise is recovered from globalContext->promise() on
settlement,
and the index store needs no write barrier since it is not a cell.
The PromiseAll*ResolveJob microtasks are reached only from the fast path (slow
paths use
JSFunctionWithFields and a separate JSPromiseCombinatorsContext), so they are
switched
unconditionally to take (globalContext, resolution, index). Spilled
JSSlimPromiseReactions
follow the same shape, so no materialization is needed when the inline reaction
is spilled.
Async stack traces continue to work by anchoring on the global context directly.
With 500,000 pending element reactions (Promise.allSettled([100 resolved
promises]) called
5,000 times before draining the microtask queue), peak process footprint drops
from
91.6 MiB to 75.3 MiB, matching the expected 500,000 × 32 bytes for the
eliminated
JSPromiseCombinatorsContext cells. Promise.all and Promise.any show similar
reductions.
* Source/JavaScriptCore/interpreter/Interpreter.cpp:
(JSC::Interpreter::getAsyncStackTrace):
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::promiseAllResolveJob):
(JSC::promiseAllSettledResolveJob):
(JSC::promiseAnyResolveJob):
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/JSPromise.cpp:
(JSC::JSPromise::setInlineMicrotaskReaction):
(JSC::JSPromise::spillInlineReaction):
(JSC::JSPromise::asyncStackTraceContext const):
(JSC::JSPromise::performPromiseThenWithInternalMicrotask):
(JSC::JSPromise::settleInlineInternalMicrotask):
* Source/JavaScriptCore/runtime/JSPromise.h:
* Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSPromiseReaction.cpp:
(JSC::JSPromiseReaction::tryGetContext):
* Source/JavaScriptCore/runtime/Microtask.h:
(JSC::isPromiseCombinatorElementTask):
Canonical link: https://commits.webkit.org/313361@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications