From 99bef81d09db455f67b2def7fce118cd2708b8fc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 1 Dec 2025 12:08:11 +0100 Subject: [PATCH] LibJS: Fast path for TypedArray.slice() We now try to do a bulk memcpy() when possible. This is significantly faster than going byte-at-a-time. --- .../LibJS/Runtime/TypedArrayPrototype.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp index 6f977d6c529..04f7e92cb52 100644 --- a/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp @@ -1740,19 +1740,26 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice) return array; } - // ix. Repeat, while targetByteIndex < limit, - while (target_byte_index < limit) { - // 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered). - auto value = source_buffer.get_value(source_byte_index.value(), true, ArrayBuffer::Unordered); + // OPTIMIZATION: If the buffers are not detached and not shared, we can do a single bulk copy. + if (!target_buffer.is_detached() && !target_buffer.is_shared_array_buffer() + && !source_buffer.is_detached() && !source_buffer.is_shared_array_buffer() + && &target_buffer.buffer() != &source_buffer.buffer()) { + target_buffer.buffer().overwrite(target_byte_index, source_buffer.buffer().data() + source_byte_index.value(), limit.value() - target_byte_index); + } else { + // ix. Repeat, while targetByteIndex < limit, + while (target_byte_index < limit) { + // 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered). + auto value = source_buffer.get_value(source_byte_index.value(), true, ArrayBuffer::Unordered); - // 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered). - target_buffer.set_value(target_byte_index, value, true, ArrayBuffer::Unordered); + // 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered). + target_buffer.set_value(target_byte_index, value, true, ArrayBuffer::Unordered); - // 3. Set srcByteIndex to srcByteIndex + 1. - ++source_byte_index; + // 3. Set srcByteIndex to srcByteIndex + 1. + ++source_byte_index; - // 4. Set targetByteIndex to targetByteIndex + 1. - ++target_byte_index; + // 4. Set targetByteIndex to targetByteIndex + 1. + ++target_byte_index; + } } } // i. Else,