Repository: WebKit/WebKit
Pull request #44267: Optimize conversions from NSArray / CFArrayRef to Vector
Author: login: cdumez
Created: 2025-04-18T20:45:19Z | Merged: 2025-04-29T19:24:40Z

#### d8e283330a3152118a1a0832dbd23b5a542b16f0
<pre>
Optimize conversions from NSArray / CFArrayRef to Vector
<a href="https://bugs.webkit.org/show_bug.cgi?id=291769">https://bugs.webkit.org/show_bug.cgi?id=291769</a>

Reviewed by Darin Adler.

Optimize conversions from NSArray / CFArrayRef to Vector by leveraging the
`Vector(size_t, const Functor&amp; valueGenerator)` constructor. It avoids
capacity checks when appending elements.

* Source/WTF/wtf/Vector.h:
(WTF::Vector::Vector):
* Source/WTF/wtf/cf/VectorCF.h:
(WTF::makeVector):
* Source/WTF/wtf/cocoa/VectorCocoa.h:
(WTF::makeVector):

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

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/101355 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/21019 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/11324 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/106508 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51984 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/21327 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/29513 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/77208 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/34234 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/104362 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/16455 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91549 "Passed tests") | [  ~~🧪 api-wpe~~](https://ews-build.webkit.org/#/builders/41/builds/57549 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/16275 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/9559 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/51332 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/94024 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/86156 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9635 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108860 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99965 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/28484 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/20957 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/1/builds/86179 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28846 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87751 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85736 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21812 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/30456 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/8168 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/22600 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/28415 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33694 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123590 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/28226 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34376 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/31546 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29785 "Built successfully") | | | 
<!--EWS-Status-Bubble-End-->


Diff:
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index a1d851517c28..51c559c55d6e 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -4208,7 +4208,7 @@ void JSObject::putOwnDataPropertyBatching(VM& vm, UniquedStringImpl** properties
 
             structure = newStructure;
             return offset;
-        });
+        }, NulloptBehavior::Abort);
 
         // Flush batching here. Note that it is possible that offsets.size() is not equal to size, if we stop batching due to transition-watchpoint-firing.
 
diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp
index dbe2413621d6..fbdeda9c2fc4 100644
--- a/Source/JavaScriptCore/runtime/MathObject.cpp
+++ b/Source/JavaScriptCore/runtime/MathObject.cpp
@@ -240,7 +240,7 @@ JSC_DEFINE_HOST_FUNCTION(mathProtoFuncHypot, (JSGlobalObject* globalObject, Call
         double argument = callFrame->uncheckedArgument(i).toNumber(globalObject);
         RETURN_IF_EXCEPTION(scope, std::nullopt);
         return argument;
-    });
+    }, NulloptBehavior::Abort);
     RETURN_IF_EXCEPTION(scope, { });
 
     double max = 0;
diff --git a/Source/WTF/wtf/Vector.h b/Source/WTF/wtf/Vector.h
index b120a39a5ff3..b9b1e0fc1ab8 100644
--- a/Source/WTF/wtf/Vector.h
+++ b/Source/WTF/wtf/Vector.h
@@ -55,6 +55,8 @@ namespace WTF {
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Vector);
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(VectorBuffer);
 
+enum class NulloptBehavior : bool { Ignore, Abort };
+
 template <bool needsDestruction, typename T>
 struct VectorDestructor;
 
@@ -734,23 +736,32 @@ class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {
     }
 
     template<std::invocable<size_t> Functor>
+    requires (!std::is_same_v<std::invoke_result_t<Functor, size_t>, std::optional<T>>)
     Vector(size_t size, NOESCAPE const Functor& valueGenerator)
     {
         reserveInitialCapacity(size);
 
         asanSetInitialBufferSizeTo(size);
 
-        if constexpr (std::is_same_v<std::invoke_result_t<Functor, size_t>, std::optional<T>>) {
-            for (size_t i = 0; i < size; ++i) {
-                if (auto item = valueGenerator(i))
-                    unsafeAppendWithoutCapacityCheck(WTFMove(*item));
-                else
-                    return;
-            }
-        } else {
-            for (size_t i = 0; i < size; ++i)
-                unsafeAppendWithoutCapacityCheck(valueGenerator(i));
+        for (size_t i = 0; i < size; ++i)
+            unsafeAppendWithoutCapacityCheck(valueGenerator(i));
+    }
+
+    template<std::invocable<size_t> Functor>
+    requires (std::is_same_v<std::invoke_result_t<Functor, size_t>, std::optional<T>>)
+    Vector(size_t size, NOESCAPE const Functor& valueGenerator, NulloptBehavior nulloptBehavior = NulloptBehavior::Ignore)
+    {
+        reserveInitialCapacity(size);
+
+        asanSetInitialBufferSizeTo(size);
+
+        for (size_t i = 0; i < size; ++i) {
+            if (auto item = valueGenerator(i))
+                unsafeAppendWithoutCapacityCheck(WTFMove(*item));
+            else if (nulloptBehavior == NulloptBehavior::Abort)
+                break;
         }
+        shrinkToFit();
     }
 
     template<typename U, size_t Extent>
@@ -2119,6 +2130,7 @@ template<typename T, size_t Extent> Vector(std::span<const T, Extent>) -> Vector
 
 } // namespace WTF
 
+using WTF::NulloptBehavior;
 using WTF::UnsafeVectorOverflow;
 using WTF::Vector;
 using WTF::copyToVector;
diff --git a/Source/WTF/wtf/cf/VectorCF.h b/Source/WTF/wtf/cf/VectorCF.h
index 933da2eb344c..d1dfa522aae4 100644
--- a/Source/WTF/wtf/cf/VectorCF.h
+++ b/Source/WTF/wtf/cf/VectorCF.h
@@ -125,18 +125,12 @@ template<typename CollectionType, typename MapFunctionType> RetainPtr<CFMutableA
 
 template<typename VectorElementType, typename CFType> Vector<VectorElementType> makeVector(CFArrayRef array)
 {
-    Vector<VectorElementType> vector;
-    CFIndex count = CFArrayGetCount(array);
-    vector.reserveInitialCapacity(count);
-    for (CFIndex i = 0; i < count; ++i) {
+    return Vector<VectorElementType>(CFArrayGetCount(array), [&](size_t index) -> std::optional<VectorElementType> {
         constexpr const VectorElementType* typedNull = nullptr;
-        if (RetainPtr element = dynamic_cf_cast<CFType>(CFArrayGetValueAtIndex(array, i))) {
-            if (auto vectorElement = makeVectorElement(typedNull, element.get()))
-                vector.append(WTFMove(*vectorElement));
-        }
-    }
-    vector.shrinkToFit();
-    return vector;
+        if (RetainPtr element = dynamic_cf_cast<CFType>(CFArrayGetValueAtIndex(array, index)))
+            return makeVectorElement(typedNull, element.get());
+        return std::nullopt;
+    });
 }
 
 template<typename MapLambdaType> Vector<typename LambdaTypeTraits<MapLambdaType>::returnType::value_type> makeVector(CFArrayRef array, MapLambdaType&& lambda)
@@ -147,17 +141,11 @@ template<typename MapLambdaType> Vector<typename LambdaTypeTraits<MapLambdaType>
     static_assert(std::is_same_v<typename LambdaTypeTraits<MapLambdaType>::returnType, std::optional<ElementType>>, "MapLambdaType returns std::optional<ElementType>");
     static_assert(LambdaTypeTraits<MapLambdaType>::paramCount == 1, "MapLambdaType takes a single CFTypeRef argument");
 
-    Vector<ElementType> vector;
-    CFIndex count = CFArrayGetCount(array);
-    vector.reserveInitialCapacity(count);
-    for (CFIndex i = 0; i < count; ++i) {
-        if (RetainPtr element = dynamic_cf_cast<CFType>(CFArrayGetValueAtIndex(array, i))) {
-            if (auto vectorElement = std::invoke(std::forward<MapLambdaType>(lambda), element.get()))
-                vector.append(WTFMove(*vectorElement));
-        }
-    }
-    vector.shrinkToFit();
-    return vector;
+    return Vector<ElementType>(CFArrayGetCount(array), [&](size_t index) -> std::optional<ElementType> {
+        if (RetainPtr element = dynamic_cf_cast<CFType>(CFArrayGetValueAtIndex(array, index)))
+            return std::invoke(std::forward<MapLambdaType>(lambda), element.get());
+        return std::nullopt;
+    });
 }
 
 inline std::span<const char> CFStringGetASCIICStringSpan(CFStringRef string)
diff --git a/Source/WTF/wtf/cocoa/VectorCocoa.h b/Source/WTF/wtf/cocoa/VectorCocoa.h
index d3fc45a8a904..2424a7f1d673 100644
--- a/Source/WTF/wtf/cocoa/VectorCocoa.h
+++ b/Source/WTF/wtf/cocoa/VectorCocoa.h
@@ -91,33 +91,17 @@ template<typename CollectionType, typename MapFunctionType> RetainPtr<NSMutableA
 
 template<typename VectorElementType> Vector<VectorElementType> makeVector(NSArray *array)
 {
-    if (!array)
-        return { };
-
-    Vector<VectorElementType> vector;
-    vector.reserveInitialCapacity(array.count);
-    for (id element in array) {
+    return Vector<VectorElementType>(array.count, [&](size_t index) {
         constexpr const VectorElementType* typedNull = nullptr;
-        if (auto vectorElement = makeVectorElement(typedNull, element))
-            vector.append(WTFMove(*vectorElement));
-    }
-    vector.shrinkToFit();
-    return vector;
+        return makeVectorElement(typedNull, array[index]);
+    });
 }
 
 template<typename MapFunctionType> Vector<typename std::invoke_result_t<MapFunctionType, id>::value_type> makeVector(NSArray *array, NOESCAPE MapFunctionType&& function)
 {
-    if (!array)
-        return { };
-
-    Vector<typename std::invoke_result_t<MapFunctionType, id>::value_type> vector;
-    vector.reserveInitialCapacity(array.count);
-    for (id element in array) {
-        if (auto vectorElement = std::invoke(std::forward<MapFunctionType>(function), element))
-            vector.append(WTFMove(*vectorElement));
-    }
-    vector.shrinkToFit();
-    return vector;
+    return Vector<typename std::invoke_result_t<MapFunctionType, id>::value_type>(array.count, [&](size_t index) {
+        return std::invoke(std::forward<MapFunctionType>(function), array[index]);
+    });
 }
 
 inline Vector<uint8_t> makeVector(NSData *data)


Reviews:
user: login: darinadler
body: I’m guessing not, but is there a measurable speedup?
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-18T23:53:15Z
user: login: cdumez
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-19T00:35:16Z
user: login: cdumez
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-19T00:54:46Z
user: login: darinadler
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-29T02:57:07Z
user: login: cdumez
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-29T16:24:56Z

Review comments:
diff_hunk: @@ -745,8 +745,9 @@ class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {
                 if (auto item = valueGenerator(i))
                     unsafeAppendWithoutCapacityCheck(WTFMove(*item));
                 else
-                    return;
+                    continue;
path: Source/WTF/wtf/Vector.h
user: login: darinadler
body: Are you sure no one is accidentally depending on "first `nullopt` stops the iteration" behavior?
created_at: 2025-04-18T23:52:24Z
author_association: MEMBER
diff_hunk: @@ -745,8 +745,9 @@ class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {
                 if (auto item = valueGenerator(i))
                     unsafeAppendWithoutCapacityCheck(WTFMove(*item));
                 else
-                    return;
+                    continue;
path: Source/WTF/wtf/Vector.h
user: login: cdumez
body: I will try and find out. It would result in correct behavior but I guess your point is that it may be slower.
created_at: 2025-04-19T00:35:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -745,8 +745,9 @@ class Vector : private VectorBuffer<T, inlineCapacity, Malloc> {
                 if (auto item = valueGenerator(i))
                     unsafeAppendWithoutCapacityCheck(WTFMove(*item));
                 else
-                    return;
+                    continue;
path: Source/WTF/wtf/Vector.h
user: login: cdumez
body: Oh actually, this can lead to trouble if the lambda doesn't expect to get called with future indexes. I will rework the PR.
created_at: 2025-04-19T00:54:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -55,6 +55,8 @@ namespace WTF {
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Vector);
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(VectorBuffer);
 
+enum class NulloptBehavior : bool { Ignore, Abort };
path: Source/WTF/wtf/Vector.h
user: login: darinadler
body: Annoying that we have to add this but I think we do! Or maybe we could use a `std::variant` with a type other than `std::nullopt_t` for the abort behavior.

Should we make ignore the default?
created_at: 2025-04-29T02:57:02Z
author_association: MEMBER
diff_hunk: @@ -55,6 +55,8 @@ namespace WTF {
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(Vector);
 DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(VectorBuffer);
 
+enum class NulloptBehavior : bool { Ignore, Abort };
path: Source/WTF/wtf/Vector.h
user: login: cdumez
body: I liked the idea of returning a std::optional since this is what we do for `compactMap()` for example. I feel that using `std::variant` would add some complexity. However, I think it would make sense to make "Ignore" the default.
created_at: 2025-04-29T16:24:55Z
author_association: CONTRIBUTOR

PR comments:
user: login: webkit-early-warning-system
created_at: 2025-04-18T20:45:25Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/e9f7afeda3c997b2ca300a142e38f0c5a55423e5)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/100152 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/19800 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/10099 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/105282 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/50734 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/20106 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/28273 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/76255 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/33305 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/103159 "Passed tests") | [❌ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/15367 "Found 1 new test failure: fast/forms/ios/file-upload-panel-dismiss-when-view-removed-from-window.html (failure)") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/90457 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/56616 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/15183 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/8454 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/50103 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/92810 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/85094 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/8537 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/107641 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/98759 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/27265 "Built successfully") | [❌ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/19974 "Found 1 new test failure: fast/css/view-transitions-hide-under-page-background-color.html (failure)") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/85210 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/27628 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/86663 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/84746 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/29409 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/7144 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/21120 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/27202 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/32435 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/122385 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/27013 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34159 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/30329 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/28572 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: cdumez
created_at: 2025-04-19T00:33:17Z
body: > I’m guessing not, but is there a measurable speedup?

I didn't measure. I will schedule A/B testing but I do not know how much ObjC is in hot code path, probably not a lot.
author_association: CONTRIBUTOR
user: login: webkit-early-warning-system
created_at: 2025-04-28T23:38:02Z
body: EWS run on previous version of this PR (hash https://github.com/WebKit/WebKit/commit/495db8bb8d7896ccc29ee2784eabad71892e90db)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/101212 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/20874 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/11177 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/106361 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51839 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/21183 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/29368 "Built successfully") | [✅ 🧪 wpe-wk2](https://ews-build.webkit.org/#/builders/34/builds/77088 "Passed tests") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/34131 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/104219 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/16333 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91430 "Passed tests") | [✅ 🧪 api-wpe](https://ews-build.webkit.org/#/builders/41/builds/57463 "Passed tests") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/16149 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/9440 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/51187 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/93879 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/86036 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9515 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108717 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99821 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/28340 "Built successfully") | [✅ 🧪 mac-AS-debug-wk2](https://ews-build.webkit.org/#/builders/122/builds/20863 "Passed tests") | [✅ 🧪 gtk-wk2](https://ews-build.webkit.org/#/builders/1/builds/86071 "Passed tests") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28702 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87635 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85621 "Passed tests") | 
| | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/30342 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/8056 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/22439 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/28270 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33541 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123447 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/28082 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34357 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/31402 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29640 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-early-warning-system
created_at: 2025-04-29T17:01:42Z
body: EWS run on current version of this PR (hash https://github.com/WebKit/WebKit/commit/addfe039bf2a9f980370f5f7d415c47718ed76ef)<details>

| Misc | iOS, visionOS, tvOS & watchOS  | macOS  | Linux |  Windows |
| ----- | ---------------------- | ------- |  ----- |  --------- |
| [✅ 🧪 style](https://ews-build.webkit.org/#/builders/38/builds/101355 "Passed style check") | [✅ 🛠 ios](https://ews-build.webkit.org/#/builders/131/builds/21019 "Built successfully") | [✅ 🛠 mac](https://ews-build.webkit.org/#/builders/138/builds/11324 "Built successfully") | [✅ 🛠 wpe](https://ews-build.webkit.org/#/builders/5/builds/106508 "Built successfully") | [✅ 🛠 win](https://ews-build.webkit.org/#/builders/59/builds/51984 "Built successfully") 
| | [✅ 🛠 ios-sim](https://ews-build.webkit.org/#/builders/130/builds/21327 "Built successfully") | [✅ 🛠 mac-AS-debug](https://ews-build.webkit.org/#/builders/123/builds/29513 "Built successfully") | [  ~~🧪 wpe-wk2~~](https://ews-build.webkit.org/#/builders/34/builds/77208 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [✅ 🧪 win-tests](https://ews-build.webkit.org/#/builders/60/builds/34234 "Passed tests") 
| [✅ 🧪 webkitperl](https://ews-build.webkit.org/#/builders/11/builds/104362 "Passed tests") | [✅ 🧪 ios-wk2](https://ews-build.webkit.org/#/builders/132/builds/16455 "Passed tests") | [✅ 🧪 api-mac](https://ews-build.webkit.org/#/builders/18/builds/91549 "Passed tests") | [  ~~🧪 api-wpe~~](https://ews-build.webkit.org/#/builders/41/builds/57549 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | 
| | [✅ 🧪 ios-wk2-wpt](https://ews-build.webkit.org/#/builders/133/builds/16275 "Passed tests") | [✅ 🧪 mac-wk1](https://ews-build.webkit.org/#/builders/135/builds/9559 "Passed tests") | [✅ 🛠 wpe-cairo](https://ews-build.webkit.org/#/builders/65/builds/51332 "Built successfully") | 
| [✅ 🛠 🧪 jsc](https://ews-build.webkit.org/#/builders/20/builds/94024 "Built successfully and passed tests") | [✅ 🧪 api-ios](https://ews-build.webkit.org/#/builders/13/builds/86156 "Passed tests") | [✅ 🧪 mac-wk2](https://ews-build.webkit.org/#/builders/136/builds/9635 "Passed tests") | [✅ 🛠 gtk](https://ews-build.webkit.org/#/builders/2/builds/108860 "Built successfully") | 
| [✅ 🛠 🧪 jsc-arm64](https://ews-build.webkit.org/#/builders/12/builds/99965 "Built successfully and passed tests") | [✅ 🛠 vision](https://ews-build.webkit.org/#/builders/128/builds/28484 "Built successfully") | [  ~~🧪 mac-AS-debug-wk2~~](https://ews-build.webkit.org/#/builders/122/builds/20957 "The change is no longer eligible for processing. Pull Request was already closed when EWS attempted to process it.") | [  ~~🧪 gtk-wk2~~](https://ews-build.webkit.org/#/builders/1/builds/86179 "The change is no longer eligible for processing. Commit was outdated when EWS attempted to process it.") | 
| | [✅ 🛠 vision-sim](https://ews-build.webkit.org/#/builders/121/builds/28846 "Built successfully") | [✅ 🧪 mac-wk2-stress](https://ews-build.webkit.org/#/builders/8/builds/87751 "Passed tests") | [✅ 🧪 api-gtk](https://ews-build.webkit.org/#/builders/21/builds/85736 "Passed tests") | 
| [✅ 🛠 🧪 merge](https://ews-build.webkit.org/#/builders/19/builds/21812 "Built successfully and passed tests") | [✅ 🧪 vision-wk2](https://ews-build.webkit.org/#/builders/126/builds/30456 "Passed tests") | [✅ 🧪 mac-intel-wk2](https://ews-build.webkit.org/#/builders/137/builds/8168 "Passed tests") | [✅ 🛠 playstation](https://ews-build.webkit.org/#/builders/134/builds/22600 "Built successfully") | 
| | [✅ 🛠 tv](https://ews-build.webkit.org/#/builders/127/builds/28415 "Built successfully") | [✅ 🛠 mac-safer-cpp](https://ews-build.webkit.org/#/builders/120/builds/33694 "Built successfully") | [✅ 🛠 jsc-armv7](https://ews-build.webkit.org/#/builders/35/builds/123590 "Built successfully") | 
| | [✅ 🛠 tv-sim](https://ews-build.webkit.org/#/builders/125/builds/28226 "Built successfully") | | [✅ 🧪 jsc-armv7-tests](https://ews-build.webkit.org/#/builders/25/builds/34376 "Passed tests") | 
| | [✅ 🛠 watch](https://ews-build.webkit.org/#/builders/129/builds/31546 "Built successfully") | | | 
| | [✅ 🛠 watch-sim](https://ews-build.webkit.org/#/builders/124/builds/29785 "Built successfully") | | | </details>
author_association: COLLABORATOR
user: login: webkit-commit-queue
created_at: 2025-04-29T19:24:40Z
body: Committed 294292@main (d8e283330a31): <https://commits.webkit.org/294292@main>

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