Skip to content

Commit 99bef81

Browse files
awesomeklinggmta
authored andcommitted
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.
1 parent 94fc8c4 commit 99bef81

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

Libraries/LibJS/Runtime/TypedArrayPrototype.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,19 +1740,26 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice)
17401740
return array;
17411741
}
17421742

1743-
// ix. Repeat, while targetByteIndex < limit,
1744-
while (target_byte_index < limit) {
1745-
// 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
1746-
auto value = source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered);
1747-
1748-
// 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
1749-
target_buffer.set_value<u8>(target_byte_index, value, true, ArrayBuffer::Unordered);
1750-
1751-
// 3. Set srcByteIndex to srcByteIndex + 1.
1752-
++source_byte_index;
1753-
1754-
// 4. Set targetByteIndex to targetByteIndex + 1.
1755-
++target_byte_index;
1743+
// OPTIMIZATION: If the buffers are not detached and not shared, we can do a single bulk copy.
1744+
if (!target_buffer.is_detached() && !target_buffer.is_shared_array_buffer()
1745+
&& !source_buffer.is_detached() && !source_buffer.is_shared_array_buffer()
1746+
&& &target_buffer.buffer() != &source_buffer.buffer()) {
1747+
target_buffer.buffer().overwrite(target_byte_index, source_buffer.buffer().data() + source_byte_index.value(), limit.value() - target_byte_index);
1748+
} else {
1749+
// ix. Repeat, while targetByteIndex < limit,
1750+
while (target_byte_index < limit) {
1751+
// 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
1752+
auto value = source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered);
1753+
1754+
// 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
1755+
target_buffer.set_value<u8>(target_byte_index, value, true, ArrayBuffer::Unordered);
1756+
1757+
// 3. Set srcByteIndex to srcByteIndex + 1.
1758+
++source_byte_index;
1759+
1760+
// 4. Set targetByteIndex to targetByteIndex + 1.
1761+
++target_byte_index;
1762+
}
17561763
}
17571764
}
17581765
// i. Else,

0 commit comments

Comments
 (0)