Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: d11c8c7ba675067079fe261af351c44e5fd3278b
      
https://github.com/WebKit/WebKit/commit/d11c8c7ba675067079fe261af351c44e5fd3278b
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-07-09 (Thu, 09 Jul 2026)

  Changed paths:
    A JSTests/microbenchmarks/await-async-function-call-chain.js
    A JSTests/microbenchmarks/promise-then-chain-distinct-functions.js
    A JSTests/stress/microtask-call-cache.js
    M Source/JavaScriptCore/interpreter/MicrotaskCall.h
    M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
    M Source/JavaScriptCore/runtime/JSMicrotask.cpp
    M Source/JavaScriptCore/runtime/JSMicrotask.h
    M Source/JavaScriptCore/runtime/JSPromise.cpp
    M Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
    M Source/JavaScriptCore/runtime/MicrotaskQueue.cpp
    M Source/JavaScriptCore/runtime/MicrotaskQueueInlines.h

  Log Message:
  -----------
  [JSC] Use a polymorphic cache for microtask calls
https://bugs.webkit.org/show_bug.cgi?id=318847

Reviewed by Yusuke Suzuki.

The microtask drain loop has a call cache with a single entry. It
remembers the last callee (executable, CodeBlock, and entry address), and
a hit skips getCallData / prepareForExecution / incoming-call relinking.

But one entry misses whenever an async function awaits another async
function: the callee's completion wakes the caller, so their resumes are
always adjacent in the microtask stream, and the cache never sees the
same callee twice in a row. This is the common shape of async code, and
the miss path took ~14% of drain time in an await-chain profile.

This change widens the cache to 8 entries with round-robin replacement,
so all callees of a typical await/then chain stay cached.

It also inlines JSGlobalObject::queueMicrotask and microtaskQueue(),
which were out-of-line and copied a QueuedTask on every enqueue. This
part alone is worth about 5-8% on promise-heavy microbenchmarks.

                                                Baseline                  
Patched

promise-then-chain-distinct-functions       16.9122+-0.1662     ^     
10.7162+-0.1512        ^ definitely 1.5782x faster
await-async-function-call-chain             16.0482+-0.1623     ^     
12.5936+-0.2134        ^ definitely 1.2743x faster

Tests: JSTests/microbenchmarks/await-async-function-call-chain.js
       JSTests/microbenchmarks/promise-then-chain-distinct-functions.js

* JSTests/microbenchmarks/await-async-function-call-chain.js: Added.
(async d5):
(async d4):
(async d3):
(async d2):
(async d1):
(async run):
* JSTests/microbenchmarks/promise-then-chain-distinct-functions.js: Added.
(async run):
* JSTests/stress/microtask-call-cache.js: Added.
(shouldBe):
(async a1):
(async a2):
(async a3):
(async a4):
(async a5):
(async a6):
(async a7):
(async a8):
(async a9):
(async a10):
(async a11):
(async a12):
(makeAdder.return.async adder):
(makeAdder):
(async test):
(async run):
* Source/JavaScriptCore/interpreter/MicrotaskCall.h:
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::microtaskQueue const): Deleted.
(JSC::JSGlobalObject::queueMicrotask): Deleted.
* Source/JavaScriptCore/runtime/JSMicrotask.cpp:
(JSC::callMicrotask):
(JSC::runInternalMicrotask):
* Source/JavaScriptCore/runtime/JSMicrotask.h:
* Source/JavaScriptCore/runtime/JSPromise.cpp:
* Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp:
* Source/JavaScriptCore/runtime/MicrotaskQueue.cpp:
(JSC::runMicrotask):
(JSC::MicrotaskQueue::drainImpl):
* Source/JavaScriptCore/runtime/MicrotaskQueueInlines.h:
(JSC::JSGlobalObject::microtaskQueue const):
(JSC::JSGlobalObject::queueMicrotask):

Canonical link: https://commits.webkit.org/316864@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to