[rab/gsab] Move length computation for RAB/GSAB-backed TAs OOL

Computing the length for variable-length TAs is a lot of code and was
regressing microbenchmarks.

Bug: v8:11111
Change-Id: Ia7c3c92bfb43938068aaf539b290f6a30b049c18
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3583898
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79961}
This commit is contained in:
Shu-yu Guo 2022-04-12 09:25:01 -07:00 committed by V8 LUCI CQ
parent 0d57754cbf
commit 9fc1a57c4d
3 changed files with 36 additions and 27 deletions

View File

@ -200,34 +200,10 @@ bool JSArrayBufferView::IsVariableLength() const {
size_t JSTypedArray::GetLengthOrOutOfBounds(bool& out_of_bounds) const {
DCHECK(!out_of_bounds);
if (WasDetached()) return 0;
if (is_length_tracking()) {
if (is_backed_by_rab()) {
if (byte_offset() > buffer().byte_length()) {
out_of_bounds = true;
return 0;
}
return (buffer().byte_length() - byte_offset()) / element_size();
}
if (byte_offset() >
buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst)) {
out_of_bounds = true;
return 0;
}
return (buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst) -
byte_offset()) /
element_size();
if (IsVariableLength()) {
return GetVariableLengthOrOutOfBounds(out_of_bounds);
}
size_t array_length = LengthUnchecked();
if (is_backed_by_rab()) {
// The sum can't overflow, since we have managed to allocate the
// JSTypedArray.
if (byte_offset() + array_length * element_size() >
buffer().byte_length()) {
out_of_bounds = true;
return 0;
}
}
return array_length;
return LengthUnchecked();
}
size_t JSTypedArray::GetLength() const {

View File

@ -380,5 +380,35 @@ size_t JSTypedArray::LengthTrackingGsabBackedTypedArrayLength(
return (backing_byte_length - array.byte_offset()) / element_byte_size;
}
size_t JSTypedArray::GetVariableLengthOrOutOfBounds(bool& out_of_bounds) const {
DCHECK(!WasDetached());
if (is_length_tracking()) {
if (is_backed_by_rab()) {
if (byte_offset() > buffer().byte_length()) {
out_of_bounds = true;
return 0;
}
return (buffer().byte_length() - byte_offset()) / element_size();
}
if (byte_offset() >
buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst)) {
out_of_bounds = true;
return 0;
}
return (buffer().GetBackingStore()->byte_length(std::memory_order_seq_cst) -
byte_offset()) /
element_size();
}
DCHECK(is_backed_by_rab());
size_t array_length = LengthUnchecked();
// The sum can't overflow, since we have managed to allocate the
// JSTypedArray.
if (byte_offset() + array_length * element_size() > buffer().byte_length()) {
out_of_bounds = true;
return 0;
}
return array_length;
}
} // namespace internal
} // namespace v8

View File

@ -301,6 +301,9 @@ class JSTypedArray
inline bool is_on_heap() const;
inline bool is_on_heap(AcquireLoadTag tag) const;
// Only valid to call when IsVariableLength() is true.
size_t GetVariableLengthOrOutOfBounds(bool& out_of_bounds) const;
inline size_t GetLengthOrOutOfBounds(bool& out_of_bounds) const;
inline size_t GetLength() const;
inline size_t GetByteLength() const;