Repository: WebKit/WebKit
Pull request #42062: [JSC] Use shuffle algorithm from BBQ for CCallHelpers::shuffleRegisters
Author: login: ddegazio
Labels: name: JavaScriptCore
description: For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.
Created: 2025-03-07T03:01:59Z | Merged: 2025-03-07T18:47:21Z

#### 40c330f75da3abf2cad6a49e51ec81e7adce87e9
<pre>
[JSC] Use shuffle algorithm from BBQ for CCallHelpers::shuffleRegisters
<a href="https://bugs.webkit.org/show_bug.cgi?id=289306">https://bugs.webkit.org/show_bug.cgi?id=289306</a>
<a href="https://rdar.apple.com/146442401">rdar://146442401</a>

Reviewed by Yusuke Suzuki.

Ports the shuffle algorithm used in the Wasm BBQ JIT to CCallHelpers::shuffleRegisters.
This results in fewer redundant moves being generated, particularly due to the fact we
are no longer using swaps to resolve dependent move cycles. Using this algorithm, we
elide 17234 out of 160180 moves total resolving shuffles on JetStream 2, a 10.7%
reduction, reducing code size and avoiding cheap but redundant work.

* Source/JavaScriptCore/jit/CCallHelpers.h:
(JSC::CCallHelpers::emitShuffleMove):
(JSC::CCallHelpers::scratchRegisterByType&lt;RegisterID&gt;):
(JSC::CCallHelpers::scratchRegisterByType&lt;FPRegisterID&gt;):
(JSC::CCallHelpers::shuffleRegisters):
* Source/JavaScriptCore/wasm/WasmBBQJIT.h:

Canonical link: <a href="https://commits.webkit.org/291786@main">https://commits.webkit.org/291786@main</a>
</pre>
<!--EWS-Status-Bubble-Start-->
https://github.com/WebKit/WebKit/commit/a41db803f50ff8f8f4c7b714542c07bbe248d186

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/93923 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/13508 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/3243 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/98929 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/44450 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/13805 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/21939 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/71673 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/29022 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/96925 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/10247 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/84848 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/52011 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/9929 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/2489 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/43766 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/86633 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/80192 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/2571 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/100969 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/92589 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/20975 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/15292 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/80690 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/21227 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/80813 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/80044 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/19950 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/24583 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/1943 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/14132 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/20959 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/26137 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/115239 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/20646 "Built successfully") | | [  ~~🧪 jsc-armv7-tests~~](https://ews-build.webkit.org/#/builders/25/builds/33130 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/24106 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/22387 "Built successfully") | | | 
<!--EWS-Status-Bubble-End-->


Diff:
diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt
index fdfe8802dc96..00440fb1af1b 100644
--- a/Source/JavaScriptCore/CMakeLists.txt
+++ b/Source/JavaScriptCore/CMakeLists.txt
@@ -571,6 +571,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
     assembler/CPU.h
     assembler/CPUInlines.h
     assembler/CodeLocation.h
+    assembler/DisallowMacroScratchRegisterUsage.h
     assembler/FastJITPermissions.h
     assembler/JITOperationList.h
     assembler/JITOperationValidation.h
diff --git a/Source/JavaScriptCore/jit/CCallHelpers.h b/Source/JavaScriptCore/jit/CCallHelpers.h
index 83aa31b9317a..ae0a59c30fed 100644
--- a/Source/JavaScriptCore/jit/CCallHelpers.h
+++ b/Source/JavaScriptCore/jit/CCallHelpers.h
@@ -28,6 +28,7 @@
 #if ENABLE(JIT)
 
 #include "AssemblyHelpers.h"
+#include "DisallowMacroScratchRegisterUsage.h"
 #include "FPRInfo.h"
 #include "GPRInfo.h"
 #include "OperationResult.h"
@@ -88,6 +89,43 @@ class CCallHelpers : public AssemblyHelpers {
         poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
     }
 
+    enum class ShuffleStatus : uint8_t {
+        ToMove,
+        BeingMoved,
+        Moved
+    };
+
+    template<typename RegType, size_t N, typename RegPair = std::pair<RegType, RegType>>
+    void emitShuffleMove(Vector<RegPair, N>& moves, Vector<ShuffleStatus, N>& status, unsigned index, RegType scratch)
+    {
+        status[index] = ShuffleStatus::BeingMoved;
+        for (unsigned i = 0; i < moves.size(); i ++) {
+            if (moves[i].first == moves[index].second) {
+                ASSERT(i != index);
+                switch (status[i]) {
+                case ShuffleStatus::ToMove:
+                    emitShuffleMove(moves, status, i, scratch);
+                    break;
+                case ShuffleStatus::BeingMoved: {
+                    if constexpr (std::is_same_v<RegType, FPRegisterID>)
+                        moveDouble(moves[i].first, scratch);
+                    else
+                        move(moves[i].first, scratch);
+                    moves[i].first = scratch;
+                    break;
+                }
+                case ShuffleStatus::Moved:
+                    break;
+                }
+            }
+        }
+        if constexpr (std::is_same_v<RegType, FPRegisterID>)
+            moveDouble(moves[index].first, moves[index].second);
+        else
+            move(moves[index].first, moves[index].second);
+        status[index] = ShuffleStatus::Moved;
+    }
+
     template<typename RegType, unsigned NumberOfRegisters>
     ALWAYS_INLINE void shuffleRegisters(std::array<RegType, NumberOfRegisters> sources, std::array<RegType, NumberOfRegisters> destinations)
     {
@@ -113,83 +151,22 @@ class CCallHelpers : public AssemblyHelpers {
             UNUSED_PARAM(destinations);
         }
 
-#if ASSERT_ENABLED
-        auto numUniqueSources = [&] () -> unsigned {
-            RegisterSetBuilder set;
-            for (auto& pair : pairs) {
-                RegType source = pair.first;
-                set.add(source, IgnoreVectors);
-            }
-            return set.numberOfSetRegisters();
-        };
+        Vector<ShuffleStatus, NumberOfRegisters> status;
+        status.fill(ShuffleStatus::ToMove, pairs.size());
 
-        auto numUniqueDests = [&] () -> unsigned {
-            RegisterSetBuilder set;
-            for (auto& pair : pairs) {
-                RegType dest = pair.second;
-                set.add(dest, IgnoreVectors);
-            }
-            return set.numberOfSetRegisters();
-        };
-#endif
-
-        while (!pairs.isEmpty()) {
-            RegisterSet freeDestinations;
-            for (auto& pair : pairs) {
-                RegType dest = pair.second;
-                freeDestinations.add(dest, IgnoreVectors);
-            }
-            for (auto& pair : pairs) {
-                RegType source = pair.first;
-                freeDestinations.remove(source);
-            }
+        RELEASE_ASSERT(m_allowScratchRegister); // We absolutely need one for the recursive shuffle algorithm.
+        auto scratch = scratchRegister();
 
-            if (freeDestinations.numberOfSetRegisters()) {
-                bool madeMove = false;
-                for (unsigned i = 0; i < pairs.size(); i++) {
-                    auto [source, dest] = pairs[i];
-                    if (freeDestinations.contains(dest, IgnoreVectors)) {
-                        // This means that this setup function cannot handle SIMD vectors as a part of parameters.
-                        // Now, this is guaranteed that we ensure FP parameter is always `double`.
-                        if constexpr (std::is_same_v<RegType, FPRReg>)
-                            moveDouble(source, dest);
-                        else
-                            move(source, dest);
-                        pairs.remove(i);
-                        madeMove = true;
-                        break;
-                    }
-                }
-                ASSERT_UNUSED(madeMove, madeMove);
-                continue;
-            }
-
-            ASSERT(numUniqueDests() == numUniqueSources());
-            ASSERT(numUniqueDests() == pairs.size());
-            // The set of source and destination registers are equivalent sets. This means we don't have
-            // any free destination registers that won't also clobber a source. We get around this by
-            // exchanging registers.
-
-            auto [source, dest] = pairs.first();
-            if constexpr (std::is_same_v<RegType, FPRReg>)
-                swapDouble(source, dest);
-            else
-                swap(source, dest);
-            pairs.remove(0);
-
-            RegType newSource = source;
-            for (auto& pair : pairs) {
-                RegType source = pair.first;
-                if (source == dest) {
-                    pair.first = newSource;
-                    break;
+        {
+            DisallowMacroScratchRegisterUsage disallowScratch(*this);
+            for (size_t i = 0; i < pairs.size(); i ++) {
+                if (status[i] == ShuffleStatus::ToMove) {
+                    if constexpr (std::is_same_v<RegType, RegisterID>)
+                        emitShuffleMove(pairs, status, i, scratch);
+                    else
+                        emitShuffleMove(pairs, status, i, fpTempRegister);
                 }
             }
-
-            // We may have introduced pairs that have the same source and destination. Remove those now.
-            pairs.removeAllMatching([](const auto& pair) {
-                return pair.first == pair.second;
-            });
         }
     }
 
diff --git a/Source/JavaScriptCore/wasm/WasmBBQJIT.h b/Source/JavaScriptCore/wasm/WasmBBQJIT.h
index da8a27661f44..b5bd8ab0d7a2 100644
--- a/Source/JavaScriptCore/wasm/WasmBBQJIT.h
+++ b/Source/JavaScriptCore/wasm/WasmBBQJIT.h
@@ -1932,11 +1932,7 @@ class BBQJIT {
 
     void emitMove(Value src, Location dst);
 
-    enum class ShuffleStatus {
-        ToMove,
-        BeingMoved,
-        Moved
-    };
+    using ShuffleStatus = CCallHelpers::ShuffleStatus;
 
     template<size_t N, typename OverflowHandler>
     void emitShuffleMove(Vector<Value, N, OverflowHandler>& srcVector, Vector<Location, N, OverflowHandler>& dstVector, Vector<ShuffleStatus, N, OverflowHandler>& statusVector, unsigned index);


Reviews:
user: login: Constellation
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-07T03:44:05Z
user: login: Constellation
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-07T03:46:22Z
user: login: ddegazio
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T03:51:13Z

Review comments:
diff_hunk: @@ -88,6 +89,50 @@ class CCallHelpers : public AssemblyHelpers {
         poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
     }
 
+    enum class ShuffleStatus : uint8_t {
+        ToMove,
+        BeingMoved,
+        Moved
+    };
+
+    template<typename RegType, size_t N, typename RegPair = std::pair<RegType, RegType>>
+    void emitShuffleMove(Vector<RegPair, N>& moves, Vector<ShuffleStatus, N>& status, unsigned index, RegType scratch)
+    {
+        status[index] = ShuffleStatus::BeingMoved;
+        for (unsigned i = 0; i < moves.size(); i ++) {
+            if (moves[i].first == moves[index].second) {
+                ASSERT(i != index);
path: Source/JavaScriptCore/jit/CCallHelpers.h
user: login: Constellation
body: Is it ensured? I wonder if we should have early check like what we have in BBQJIT::emitShuffleMove.
created_at: 2025-03-07T03:46:19Z
author_association: MEMBER
diff_hunk: @@ -88,6 +89,50 @@ class CCallHelpers : public AssemblyHelpers {
         poke(GPRInfo::nonArgGPR0, POKE_ARGUMENT_OFFSET + argumentIndex - GPRInfo::numberOfArgumentRegisters);
     }
 
+    enum class ShuffleStatus : uint8_t {
+        ToMove,
+        BeingMoved,
+        Moved
+    };
+
+    template<typename RegType, size_t N, typename RegPair = std::pair<RegType, RegType>>
+    void emitShuffleMove(Vector<RegPair, N>& moves, Vector<ShuffleStatus, N>& status, unsigned index, RegType scratch)
+    {
+        status[index] = ShuffleStatus::BeingMoved;
+        for (unsigned i = 0; i < moves.size(); i ++) {
+            if (moves[i].first == moves[index].second) {
+                ASSERT(i != index);
path: Source/JavaScriptCore/jit/CCallHelpers.h
user: login: ddegazio
body: It should be ensured, in the existing implementation of `shuffleRegisters` we have:
```
for (unsigned i = 0; i < NumberOfRegisters; ++i) {
    if (sources[i] != destinations[i])
        pairs.append(std::make_pair(sources[i], destinations[i]));
}
```
so trivial moves are already checked for and shouldn't make it into the shuffle algorithm.
created_at: 2025-03-07T03:51:13Z
author_association: CONTRIBUTOR

PR comments:
user: login: webkit-early-warning-system
created_at: 2025-03-07T03:02:07Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/199040f5949d14b8bcc7e88b11edfbf2f2a12d93)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/93913 "Passed style check") | [  ~~🛠 ios~~](https://ews-build.webkit.org/#/builders/131/builds/13497 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/98919 "Hash 199040f5 for PR 42062 does not build (failure)") | [  ~~🛠 win~~](https://ews-build.webkit.org/#/builders/59/builds/44440 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| | [❌ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/13797 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/21929 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/5/builds/98919 "Hash 199040f5 for PR 42062 does not build (failure)") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/59/builds/44440 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/96915 "Passed tests") | [❌ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/130/builds/13797 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 api-mac](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/5/builds/98919 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| | [❌ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/130/builds/13797 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [  ~~🛠 wpe-cairo~~](https://ews-build.webkit.org/#/builders/65/builds/43756 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| [❌ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/86623 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 api-ios](https://ews-build.webkit.org/#/builders/130/builds/13797 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/100959 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| [❌ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/92579 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/20965 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/123/builds/21929 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/2/builds/100959 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| | [❌ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/21217 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [❌ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/2/builds/100959 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| | [⏳ 🧪 vision-wk2 ](https://ews-build.webkit.org/#/builders/visionOS-2-Simulator-WK2-Tests-EWS "Waiting in queue, processing has not started yet") | [❌ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/138/builds/3232 "Hash 199040f5 for PR 42062 does not build (failure)") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/14122 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [❌ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/20949 "Hash 199040f5 for PR 42062 does not build (failure)") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/26127 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/115229 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| | [  ~~🛠 tv-sim~~](https://ews-build.webkit.org/#/builders/125/builds/20636 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | [❌ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/35/builds/115229 "Hash 199040f5 for PR 42062 does not build (failure)") | 
| | [  ~~🛠 watch~~](https://ews-build.webkit.org/#/builders/129/builds/24096 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | 
| | [  ~~🛠 watch-sim~~](https://ews-build.webkit.org/#/builders/124/builds/22377 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-03-07T03:32:13Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/eba984777d825c22c2757e170227e236479e0988)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/93916 "Passed style check") | [  ~~🛠 ios~~](https://ews-build.webkit.org/#/builders/131/builds/13500 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/3235 "Built successfully") | [❌ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/98922 "Hash eba98477 for PR 42062 does not build (failure)") | [  ~~🛠 win~~](https://ews-build.webkit.org/#/builders/59/builds/44443 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/13798 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/21932 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/5/builds/98922 "Hash eba98477 for PR 42062 does not build (failure)") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/59/builds/44443 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/96918 "Passed tests") | [⏳ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/iOS-18-Simulator-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 api-mac](https://ews-build.webkit.org/#/builders/API-Tests-macOS-EWS "Waiting to run tests") | [❌ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/5/builds/98922 "Hash eba98477 for PR 42062 does not build (failure)") | 
| | [  ~~🧪 ios-wk2-wpt~~](https://ews-build.webkit.org/#/builders/133/builds/9924 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/2483 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🛠 wpe-cairo~~](https://ews-build.webkit.org/#/builders/65/builds/43759 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| [  ~~🛠 🧪 jsc~~](https://ews-build.webkit.org/#/builders/20/builds/86626 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 api-ios](https://ews-build.webkit.org/#/builders/API-Tests-iOS-Simulator-EWS "Waiting to run tests") | [  ~~🧪 mac-wk2~~](https://ews-build.webkit.org/#/builders/136/builds/2565 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/100962 "Hash eba98477 for PR 42062 does not build (failure)") | 
| [  ~~🛠 🧪 jsc-arm64~~](https://ews-build.webkit.org/#/builders/12/builds/92582 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/20968 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [❌ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/2/builds/100962 "Hash eba98477 for PR 42062 does not build (failure)") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/21220 "Built successfully") | [  ~~🧪 mac-wk2-stress~~](https://ews-build.webkit.org/#/builders/8/builds/80807 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/2/builds/100962 "Hash eba98477 for PR 42062 does not build (failure)") | 
| | [  ~~🧪 vision-wk2~~](https://ews-build.webkit.org/#/builders/126/builds/24576 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/14125 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/20952 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/26130 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/115232 "Hash eba98477 for PR 42062 does not build (failure)") | 
| | [  ~~🛠 tv-sim~~](https://ews-build.webkit.org/#/builders/125/builds/20639 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | [❌ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/35/builds/115232 "Hash eba98477 for PR 42062 does not build (failure)") | 
| | [  ~~🛠 watch~~](https://ews-build.webkit.org/#/builders/129/builds/24099 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | 
| | [  ~~🛠 watch-sim~~](https://ews-build.webkit.org/#/builders/124/builds/22380 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-03-07T03:53:16Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/8b1bc325e25801b09c95a3da80e23ae193aecdf8)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/93918 "Passed style check") | [  ~~🛠 ios~~](https://ews-build.webkit.org/#/builders/131/builds/13503 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/3237 "Built successfully") | [❌ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/98924 "Hash 8b1bc325 for PR 42062 does not build (failure)") | [  ~~🛠 win~~](https://ews-build.webkit.org/#/builders/59/builds/44445 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/13800 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/21934 "Built successfully") | [❌ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/5/builds/98924 "Hash 8b1bc325 for PR 42062 does not build (failure)") | [  ~~🧪 win-tests~~](https://ews-build.webkit.org/#/builders/59/builds/44445 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/96920 "Passed tests") | [⏳ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/iOS-18-Simulator-WK2-Tests-EWS "Waiting to run tests") | [⏳ 🧪 api-mac](https://ews-build.webkit.org/#/builders/API-Tests-macOS-EWS "Waiting to run tests") | [❌ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/5/builds/98924 "Hash 8b1bc325 for PR 42062 does not build (failure)") | 
| | [  ~~🧪 ios-wk2-wpt~~](https://ews-build.webkit.org/#/builders/133/builds/9926 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🧪 mac-wk1~~](https://ews-build.webkit.org/#/builders/135/builds/2485 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [  ~~🛠 wpe-cairo~~](https://ews-build.webkit.org/#/builders/65/builds/43761 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/86628 "Built successfully and passed tests") | [⏳ 🧪 api-ios](https://ews-build.webkit.org/#/builders/API-Tests-iOS-Simulator-EWS "Waiting to run tests") | [  ~~🧪 mac-wk2~~](https://ews-build.webkit.org/#/builders/136/builds/2567 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/100964 "Hash 8b1bc325 for PR 42062 does not build (failure)") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/92584 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/20970 "Built successfully") | [⏳ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/macOS-Sequoia-Debug-WK2-Tests-EWS "Waiting to run tests") | [❌ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/2/builds/100964 "Hash 8b1bc325 for PR 42062 does not build (failure)") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/21222 "Built successfully") | [  ~~🧪 mac-wk2-stress~~](https://ews-build.webkit.org/#/builders/8/builds/80809 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [❌ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/2/builds/100964 "Hash 8b1bc325 for PR 42062 does not build (failure)") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/24578 "Passed tests") | [⏳ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/macOS-Sonoma-Release-WK2-Intel-Tests-EWS "Waiting to run tests") | [  ~~🛠 playstation~~](https://ews-build.webkit.org/#/builders/134/builds/14127 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/20954 "Built successfully") | [  ~~🛠 mac-safer-cpp~~](https://ews-build.webkit.org/#/builders/120/builds/26132 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/115234 "Built successfully") | 
| | [  ~~🛠 tv-sim~~](https://ews-build.webkit.org/#/builders/125/builds/20641 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | [⏳ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/JSC-ARMv7-32bits-Tests-EWS "Waiting to run tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/24101 "Built successfully") | | | 
| | [  ~~🛠 watch-sim~~](https://ews-build.webkit.org/#/builders/124/builds/22382 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-03-07T04:32:07Z
body: EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/a41db803f50ff8f8f4c7b714542c07bbe248d186)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/93923 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/13508 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/3243 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/98929 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/44450 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/13805 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/21939 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/71673 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/29022 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/96925 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/10247 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/84848 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/52011 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/9929 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/2489 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/43766 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/86633 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/80192 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/2571 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/100969 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/92589 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/20975 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/15292 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/80690 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/21227 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/80813 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/80044 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/19950 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/24583 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/1943 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/14132 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/20959 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/26137 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/115239 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/20646 "Built successfully") | | [  ~~🧪 jsc-armv7-tests~~](https://ews-build.webkit.org/#/builders/25/builds/33130 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/24106 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/22387 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-03-07T18:47:21Z
body: Committed 291786@main (40c330f75da3): <https://commits.webkit.org/291786@main>

Reviewed commits have been landed. Closing PR #42062 and removing active labels.
author_association: COLLABORATOR