Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 7f538702bc4e7b6abe58e723004d216beac074c3
https://github.com/WebKit/WebKit/commit/7f538702bc4e7b6abe58e723004d216beac074c3
Author: Sosuke Suzuki <[email protected]>
Date: 2026-07-03 (Fri, 03 Jul 2026)
Changed paths:
A JSTests/microbenchmarks/async-function-return-number-no-await.js
A JSTests/microbenchmarks/async-function-return-object-no-await.js
A JSTests/stress/async-function-return-non-thenable-folding.js
A JSTests/stress/async-function-return-thenable.js
M Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
M Source/JavaScriptCore/dfg/DFGNode.h
Log Message:
-----------
[JSC] Prove resolved values non-thenable for `NewResolvedPromise` in DFG
constant folding
https://bugs.webkit.org/show_bug.cgi?id=318515
Reviewed by Yusuke Suzuki.
Returning a value from an async function that has no await compiles to a
NewResolvedPromise node in the DFG and FTL.
NewResolvedPromise already has a fast path that allocates and fulfills the
promise inline, skipping the observable "then" property lookup, gated on its
isResolvedValueKnownNonThenable flag.
However, the flag is only set when constant folding converts
Promise.resolve(object) into NewResolvedPromise; nodes created for async
function returns never get it, so they call into C++ and clobber the world
on every resolution.
This patch adds a NewResolvedPromise case to constant folding that upgrades
the flag in place. If the resolved value is proven non-object, it cannot be
a thenable, so the flag is set immediately. Otherwise, if it has a single
structure, we prove "then" is absent from the structure and its prototype
chain via tryEnsureAbsence and watch those conditions; adding "then" later
fires the watchpoints and jettisons the code. Returning a promise keeps the
slow path, since the absence proof fails on Promise.prototype.then.
baseline
patched
async-function-return-object-no-await 58.9822+-13.0567 ^
30.9665+-1.6062 ^ definitely 1.9047x faster
async-function-return-number-no-await 41.0872+-2.4379
38.7943+-3.4576 might be 1.0591x faster
Tests: JSTests/microbenchmarks/async-function-return-number-no-await.js
JSTests/microbenchmarks/async-function-return-object-no-await.js
JSTests/stress/async-function-return-non-thenable-folding.js
JSTests/stress/async-function-return-thenable.js
* JSTests/microbenchmarks/async-function-return-number-no-await.js: Added.
(async compute):
(kernel):
(last.then):
* JSTests/microbenchmarks/async-function-return-object-no-await.js: Added.
(async toDTO):
(kernel):
(last.then):
* JSTests/stress/async-function-return-non-thenable-folding.js: Added.
(shouldBe):
(async toDTO):
* JSTests/stress/async-function-return-thenable.js: Added.
(shouldBe):
(async makeOwnThenable):
(i.makeOwnThenable.i.then):
(ProtoThenable):
(ProtoThenable.prototype.then):
(async makeProtoThenable):
(i.makeProtoThenable.i.then):
(string_appeared_here.async makeDeepThenable):
(string_appeared_here):
(GetterThenable):
(GetterThenable.prototype.get then):
(async makeGetterThenable):
(i.makeGetterThenable.i.then):
(string_appeared_here.o.then):
(string_appeared_here.async maybeThenable):
(shouldBe.LateProto):
(shouldBe.async makeLateProto):
(shouldBe.LateProto.prototype.then):
(shouldBe.NonCallableThen):
(shouldBe.async makeNonCallable):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::setResolvedValueKnownNonThenable):
Canonical link: https://commits.webkit.org/316466@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications