From 5fd53652b714287d05fc06b9d24c128993b3c03a Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 27 Feb 2024 10:35:41 -0500 Subject: [PATCH] LibJS: Add a fast path for checking if attached TAs are out of bounds In IsValidIntegerIndex, we check if the TA is detached before invoking IsTypedArrayOutOfBounds. There's no need to check it again. On https://cyxx.github.io/another_js, this reduces the runtime of IsValidIntegerIndex from 11.5% to 10.7%. --- Userland/Libraries/LibJS/Runtime/TypedArray.cpp | 8 ++------ Userland/Libraries/LibJS/Runtime/TypedArray.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index dc101dc46e..7a8b63fb90 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -668,7 +668,7 @@ u32 typed_array_length_with_known_valid_bounds(TypedArrayWithBufferWitness const } // 10.4.5.13 IsTypedArrayOutOfBounds ( taRecord ), https://tc39.es/ecma262/#sec-istypedarrayoutofbounds -bool is_typed_array_out_of_bounds(TypedArrayWithBufferWitness const& typed_array_record) +bool is_typed_array_out_of_bounds_for_known_attached_array(TypedArrayWithBufferWitness const& typed_array_record) { // 1. Let O be taRecord.[[Object]]. auto object = typed_array_record.object; @@ -677,11 +677,7 @@ bool is_typed_array_out_of_bounds(TypedArrayWithBufferWitness const& typed_array auto const& buffer_byte_length = typed_array_record.cached_buffer_byte_length; // 3. Assert: IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is true if and only if bufferByteLength is detached. - VERIFY(object->viewed_array_buffer()->is_detached() == buffer_byte_length.is_detached()); - // 4. If bufferByteLength is detached, return true. - if (buffer_byte_length.is_detached()) - return true; // 5. Let byteOffsetStart be O.[[ByteOffset]]. auto byte_offset_start = object->byte_offset(); @@ -728,7 +724,7 @@ bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalIndex pr // NOTE: Bounds checking is not a synchronizing operation when O's backing buffer is a growable SharedArrayBuffer. // 6. If IsTypedArrayOutOfBounds(taRecord) is true, return false. - if (is_typed_array_out_of_bounds(typed_array_record)) + if (is_typed_array_out_of_bounds_for_known_attached_array(typed_array_record)) return false; // 7. Let length be TypedArrayLength(taRecord). diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index bc7f3941f8..e01c4f8990 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -110,6 +110,18 @@ inline u32 typed_array_length(TypedArrayWithBufferWitness const& typed_array_rec return typed_array_length_with_known_valid_bounds(typed_array_record); } +// Fast-path version of IsTypedArrayOutOfBounds when you already know the TA is not detached. +bool is_typed_array_out_of_bounds_for_known_attached_array(TypedArrayWithBufferWitness const&); + +// 10.4.5.13 IsTypedArrayOutOfBounds ( taRecord ), https://tc39.es/ecma262/#sec-istypedarrayoutofbounds +inline bool is_typed_array_out_of_bounds(TypedArrayWithBufferWitness const& typed_array_record) +{ + if (typed_array_record.cached_buffer_byte_length.is_detached()) + return true; + + return is_typed_array_out_of_bounds_for_known_attached_array(typed_array_record); +} + // 10.4.5.15 TypedArrayGetElement ( O, index ), https://tc39.es/ecma262/#sec-typedarraygetelement template inline ThrowCompletionOr typed_array_get_element(TypedArrayBase const& typed_array, CanonicalIndex property_index)