From 72cee4c88bfb7f2fe4a9bad4890450f66db1e14e Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 27 Feb 2024 10:53:09 -0500 Subject: [PATCH] LibJS: Add a fast path for creating a TA witness record for attached TAs In IsValidIntegerIndex, we check if the TA is detached before invoking MakeTypedArrayWithBufferWitnessRecord. There's no need to check it again. On https://cyxx.github.io/another_js, this reduces the runtime of IsValidIntegerIndex from 10.7% to 9.9%. --- .../Libraries/LibJS/Runtime/TypedArray.cpp | 19 ++++++------------- Userland/Libraries/LibJS/Runtime/TypedArray.h | 13 ++++++++++++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index 7a8b63fb90..18245cfc9c 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -588,26 +588,19 @@ JS_ENUMERATE_TYPED_ARRAYS #undef __JS_ENUMERATE // 10.4.5.9 MakeTypedArrayWithBufferWitnessRecord ( obj, order ), https://tc39.es/ecma262/#sec-maketypedarraywithbufferwitnessrecord -TypedArrayWithBufferWitness make_typed_array_with_buffer_witness_record(TypedArrayBase const& typed_array, ArrayBuffer::Order order) +TypedArrayWithBufferWitness make_typed_array_with_buffer_witness_record_for_known_attached_array(TypedArrayBase const& typed_array, ArrayBuffer::Order order) { // 1. Let buffer be obj.[[ViewedArrayBuffer]]. auto* buffer = typed_array.viewed_array_buffer(); - ByteLength byte_length { 0 }; - // 2. If IsDetachedBuffer(buffer) is true, then - if (buffer->is_detached()) { - // a. Let byteLength be detached. - byte_length = ByteLength::detached(); - } + // a. Let byteLength be detached. // 3. Else, - else { - // a. Let byteLength be ArrayBufferByteLength(buffer, order). - byte_length = array_buffer_byte_length(*buffer, order); - } + // a. Let byteLength be ArrayBufferByteLength(buffer, order). + auto byte_length = array_buffer_byte_length(*buffer, order); // 4. Return the TypedArray With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }. - return { .object = typed_array, .cached_buffer_byte_length = move(byte_length) }; + return { .object = typed_array, .cached_buffer_byte_length = byte_length }; } // 10.4.5.11 TypedArrayByteLength ( taRecord ), https://tc39.es/ecma262/#sec-typedarraybytelength @@ -719,7 +712,7 @@ bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalIndex pr return false; // 4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, unordered). - auto typed_array_record = make_typed_array_with_buffer_witness_record(typed_array, ArrayBuffer::Unordered); + auto typed_array_record = make_typed_array_with_buffer_witness_record_for_known_attached_array(typed_array, ArrayBuffer::Unordered); // NOTE: Bounds checking is not a synchronizing operation when O's backing buffer is a growable SharedArrayBuffer. diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index e01c4f8990..eee89855bb 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -92,11 +92,22 @@ struct TypedArrayWithBufferWitness { ByteLength cached_buffer_byte_length; // [[CachedBufferByteLength]] }; -TypedArrayWithBufferWitness make_typed_array_with_buffer_witness_record(TypedArrayBase const&, ArrayBuffer::Order); u32 typed_array_byte_length(TypedArrayWithBufferWitness const&); bool is_typed_array_out_of_bounds(TypedArrayWithBufferWitness const&); bool is_valid_integer_index(TypedArrayBase const&, CanonicalIndex); +// Fast-path version of MakeTypedArrayWithBufferWitnessRecord when you already know the TA is not detached. +TypedArrayWithBufferWitness make_typed_array_with_buffer_witness_record_for_known_attached_array(TypedArrayBase const&, ArrayBuffer::Order); + +// 10.4.5.9 MakeTypedArrayWithBufferWitnessRecord ( obj, order ), https://tc39.es/ecma262/#sec-maketypedarraywithbufferwitnessrecord +inline TypedArrayWithBufferWitness make_typed_array_with_buffer_witness_record(TypedArrayBase const& typed_array, ArrayBuffer::Order order) +{ + if (typed_array.viewed_array_buffer()->is_detached()) + return { .object = typed_array, .cached_buffer_byte_length = ByteLength::detached() }; + + return make_typed_array_with_buffer_witness_record_for_known_attached_array(typed_array, order); +} + // Fast-path version of TypedArrayLength when you already know the TA is within its bounds, // i.e. you previously checked IsTypedArrayOutOfBounds. u32 typed_array_length_with_known_valid_bounds(TypedArrayWithBufferWitness const&);