From 8cc9fee456eb61b4cb0c268bc12dd3d8e38a7a6e Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Mon, 17 Aug 2026 17:20:08 -0700 Subject: [PATCH] [JSC] Stop forcing the generic typed array prototype functions inline Every genericTypedArrayViewProto* is reached from a 12-way type switch (CALL_GENERIC_TYPEDARRAY_PROTOTYPE_FUNCTION) that tail-calls it and returns. ALWAYS_INLINE on the entry points gains nothing there and puts twelve copies of each body (and, for sort/toSorted, twelve copies of the whole stable-sort implementation) into one host function: typedArrayViewProtoFuncSort and ToSorted are 290 KB each in a release JavaScriptCore, the two largest functions in the binary. Demote the entry points and SortImpl to plain inline so the per-ViewClass instantiations are separate functions again; the loop helpers that specialise on a functor (typedArrayViewForEachImpl, typedArrayIndexOfImpl, typedArrayLastIndexOfImpl) stay ALWAYS_INLINE. Same for ArrayPrototype's sortImpl, which was being duplicated into both arrayProtoFuncSort and arrayProtoFuncToSorted (~64 KB each). --- .../JavaScriptCore/runtime/ArrayPrototype.cpp | 2 +- ...SGenericTypedArrayViewPrototypeFunctions.h | 62 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index bb639c5da9609..1eee79f12c281 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -1064,7 +1064,7 @@ static ALWAYS_INLINE void sortCommit(JSGlobalObject* globalObject, JSObject* thi } } -static ALWAYS_INLINE void sortImpl(JSGlobalObject* globalObject, JSObject* thisObject, uint64_t length, JSValue comparatorValue) +static inline void sortImpl(JSGlobalObject* globalObject, JSObject* thisObject, uint64_t length, JSValue comparatorValue) { VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); diff --git a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h index d539bfd26201e..8c3b64b99d2e6 100644 --- a/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h +++ b/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h @@ -266,7 +266,7 @@ static ALWAYS_INLINE void typedArrayViewForEachImpl(JSGlobalObject* globalObject } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSet(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncSet(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -311,7 +311,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSet(VM& vm, JSGlobalO } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncCopyWithin(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncCopyWithin(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -487,7 +487,7 @@ static ALWAYS_INLINE size_t typedArrayLastIndexOfImpl(typename ViewClass::Elemen } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncIncludes(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncIncludes(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -552,7 +552,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncIncludes(VM& vm, JSGl } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncIndexOf(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncIndexOf(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -597,7 +597,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncIndexOf(VM& vm, JSGlo } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncJoin(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncJoin(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -656,7 +656,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncJoin(VM& vm, JSGlobal } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFill(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFill(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill auto scope = DECLARE_THROW_SCOPE(vm); @@ -718,7 +718,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFill(VM& vm, JSGlobal } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncLastIndexOf(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncLastIndexOf(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -776,7 +776,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncLastIndexOf(VM& vm, J } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncBuffer(VM&, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoGetterFuncBuffer(VM&, JSGlobalObject* globalObject, CallFrame* callFrame) { // 22.2.3.3 ViewClass* thisObject = uncheckedDowncast(callFrame->thisValue()); @@ -785,7 +785,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncBuffer(VM&, JSG } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncLength(VM&, JSGlobalObject*, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoGetterFuncLength(VM&, JSGlobalObject*, CallFrame* callFrame) { // 22.2.3.17 ViewClass* thisObject = uncheckedDowncast(callFrame->thisValue()); @@ -794,7 +794,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncLength(VM&, JSG } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncByteLength(VM&, JSGlobalObject*, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoGetterFuncByteLength(VM&, JSGlobalObject*, CallFrame* callFrame) { // 22.2.3.2 ViewClass* thisObject = uncheckedDowncast(callFrame->thisValue()); @@ -803,7 +803,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncByteLength(VM&, } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncByteOffset(VM&, JSGlobalObject*, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoGetterFuncByteOffset(VM&, JSGlobalObject*, CallFrame* callFrame) { // 22.2.3.3 ViewClass* thisObject = uncheckedDowncast(callFrame->thisValue()); @@ -812,7 +812,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoGetterFuncByteOffset(VM&, } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncForEach(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncForEach(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.foreach auto scope = DECLARE_THROW_SCOPE(vm); @@ -872,7 +872,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncForEach(VM& vm, JSGlo } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncMap(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncMap(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.map auto scope = DECLARE_THROW_SCOPE(vm); @@ -979,7 +979,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncMap(VM& vm, JSGlobalO } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFilter(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFilter(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.filter auto scope = DECLARE_THROW_SCOPE(vm); @@ -1072,7 +1072,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFilter(VM& vm, JSGlob #undef JSC_DISPATCH_TYPED_ARRAY template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFind(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFind(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.find auto scope = DECLARE_THROW_SCOPE(vm); @@ -1145,7 +1145,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFind(VM& vm, JSGlobal } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindIndex(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFindIndex(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.findindex auto scope = DECLARE_THROW_SCOPE(vm); @@ -1218,7 +1218,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindIndex(VM& vm, JSG } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindLast(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFindLast(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.findlast auto scope = DECLARE_THROW_SCOPE(vm); @@ -1291,7 +1291,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindLast(VM& vm, JSGl } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindLastIndex(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncFindLastIndex(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.findlastindex auto scope = DECLARE_THROW_SCOPE(vm); @@ -1364,7 +1364,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncFindLastIndex(VM& vm, } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncEvery(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncEvery(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.every auto scope = DECLARE_THROW_SCOPE(vm); @@ -1437,7 +1437,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncEvery(VM& vm, JSGloba } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSome(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncSome(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.some auto scope = DECLARE_THROW_SCOPE(vm); @@ -1510,7 +1510,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSome(VM& vm, JSGlobal } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReduce(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncReduce(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce auto scope = DECLARE_THROW_SCOPE(vm); @@ -1585,7 +1585,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReduce(VM& vm, JSGlob } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReduceRight(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncReduceRight(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduceright auto scope = DECLARE_THROW_SCOPE(vm); @@ -1661,7 +1661,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReduceRight(VM& vm, J } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReverse(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncReverse(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -1677,7 +1677,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncReverse(VM& vm, JSGlo } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncToReversed(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncToReversed(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toReversed @@ -1706,7 +1706,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncToReversed(VM& vm, JS } template -static ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSortImpl(VM& vm, JSGlobalObject* globalObject, ViewClass* thisObject, JSValue comparatorValue) +static inline EncodedJSValue genericTypedArrayViewProtoFuncSortImpl(VM& vm, JSGlobalObject* globalObject, ViewClass* thisObject, JSValue comparatorValue) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -1802,7 +1802,7 @@ static ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSortImpl(VM& v } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSort(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncSort(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -1819,7 +1819,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSort(VM& vm, JSGlobal } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncToSorted(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncToSorted(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSorted @@ -1850,7 +1850,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncToSorted(VM& vm, JSGl } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewPrivateFuncFromFast(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewPrivateFuncFromFast(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -1913,7 +1913,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewPrivateFuncFromFast(VM& vm, JS } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSlice(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncSlice(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { auto scope = DECLARE_THROW_SCOPE(vm); @@ -2037,7 +2037,7 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSlice(VM& vm, JSGloba } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncSubarray(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncSubarray(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray @@ -2124,7 +2124,7 @@ static inline void validateIntegerIndex(JSGlobalObject* globalObject, ViewClass* } template -ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncWith(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) +inline EncodedJSValue genericTypedArrayViewProtoFuncWith(VM& vm, JSGlobalObject* globalObject, CallFrame* callFrame) { // https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with