Commit 3530299c authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[rab/gsab] TA.p.{entries,keys,values}: Support RAB / GSAB

Bug: v8:11111
Change-Id: I10409756af4ba1a04c1bca21cbdab375003a7f42
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3177225
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77077}
parent 9899864a
......@@ -155,8 +155,8 @@ TF_BUILTIN(TypedArrayPrototypeByteOffset, TypedArrayBuiltinsAssembler) {
// Default to zero if the {receiver}s buffer was detached / out of bounds.
Label detached_or_oob(this), not_detached_nor_oob(this);
IsTypedArrayDetachedOrOutOfBounds(CAST(receiver), &detached_or_oob,
&not_detached_nor_oob);
IsJSTypedArrayDetachedOrOutOfBounds(CAST(receiver), &detached_or_oob,
&not_detached_nor_oob);
BIND(&detached_or_oob);
Return(ChangeUintPtrToTagged(UintPtrConstant(0)));
......
......@@ -170,15 +170,19 @@ extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOnHeapDataPtr(
JSTypedArray, ByteArray, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::SetJSTypedArrayOffHeapDataPtr(
JSTypedArray, RawPtr, uintptr): void;
extern macro IsJSTypedArrayDetachedOrOutOfBounds(JSTypedArray):
never labels Detached, NotDetached;
// AttachedJSTypedArray guards that the array's buffer is not detached.
transient type AttachedJSTypedArray extends JSTypedArray;
macro EnsureAttached(array: JSTypedArray): AttachedJSTypedArray
labels Detached {
// TODO(v8:11111): Add OOB check for RAB / GSAB.
if (IsDetachedBuffer(array.buffer)) goto Detached;
return %RawDownCast<AttachedJSTypedArray>(array);
try {
IsJSTypedArrayDetachedOrOutOfBounds(array) otherwise Detached, NotDetached;
} label NotDetached {
return %RawDownCast<AttachedJSTypedArray>(array);
}
}
struct AttachedJSTypedArrayWitness {
......
......@@ -13916,7 +13916,7 @@ TNode<UintPtrT> CodeStubAssembler::LoadVariableLengthJSTypedArrayLength(
return result.value();
}
void CodeStubAssembler::IsTypedArrayDetachedOrOutOfBounds(
void CodeStubAssembler::IsJSTypedArrayDetachedOrOutOfBounds(
TNode<JSTypedArray> array, Label* detached_or_oob,
Label* not_detached_nor_oob) {
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(array);
......
......@@ -3563,9 +3563,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<UintPtrT> LoadVariableLengthJSTypedArrayByteLength(
TNode<Context> context, TNode<JSTypedArray> array,
TNode<JSArrayBuffer> buffer);
void IsTypedArrayDetachedOrOutOfBounds(TNode<JSTypedArray> array,
Label* detached_or_oob,
Label* not_detached_nor_oob);
void IsJSTypedArrayDetachedOrOutOfBounds(TNode<JSTypedArray> array,
Label* detached_or_oob,
Label* not_detached_nor_oob);
TNode<IntPtrT> RabGsabElementsKindToElementByteSize(
TNode<Int32T> elementsKind);
......
......@@ -462,7 +462,12 @@ function TestIterationAndGrow(ta, expected, gsab, grow_after,
let values = [];
let grown = false;
for (const value of ta) {
values.push(Number(value));
if (value instanceof Array) {
// When iterating via entries(), the values will be arrays [key, value].
values.push([value[0], Number(value[1])]);
} else {
values.push(Number(value));
}
if (!grown && values.length == grow_after) {
gsab.grow(new_byte_length);
grown = true;
......@@ -933,3 +938,205 @@ function TestIterationAndGrow(ta, expected, gsab, grow_after,
assertEquals([2, 3, 2, 3, 4, 5], ToNumbers(lengthTracking));
}
})();
(function EntriesKeysValues() {
for (let ctor of ctors) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const fixedLength = new ctor(gsab, 0, 4);
const fixedLengthWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT, 2);
const lengthTracking = new ctor(gsab, 0);
const lengthTrackingWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT);
// Write some data into the array.
const taWrite = new ctor(gsab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(taWrite, i, 2 * i);
}
// Orig. array: [0, 2, 4, 6]
// [0, 2, 4, 6] << fixedLength
// [4, 6] << fixedLengthWithOffset
// [0, 2, 4, 6, ...] << lengthTracking
// [4, 6, ...] << lengthTrackingWithOffset
assertEquals([0, 2, 4, 6], ToNumbersWithEntries(fixedLength));
assertEquals([0, 2, 4, 6], ValuesToNumbers(fixedLength));
assertEquals([0, 1, 2, 3], Keys(fixedLength));
assertEquals([4, 6], ToNumbersWithEntries(fixedLengthWithOffset));
assertEquals([4, 6], ValuesToNumbers(fixedLengthWithOffset));
assertEquals([0, 1], Keys(fixedLengthWithOffset));
assertEquals([0, 2, 4, 6], ToNumbersWithEntries(lengthTracking));
assertEquals([0, 2, 4, 6], ValuesToNumbers(lengthTracking));
assertEquals([0, 1, 2, 3], Keys(lengthTracking));
assertEquals([4, 6], ToNumbersWithEntries(lengthTrackingWithOffset));
assertEquals([4, 6], ValuesToNumbers(lengthTrackingWithOffset));
assertEquals([0, 1], Keys(lengthTrackingWithOffset));
// Grow.
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
for (let i = 0; i < 6; ++i) {
WriteToTypedArray(taWrite, i, 2 * i);
}
// Orig. array: [0, 2, 4, 6, 8, 10]
// [0, 2, 4, 6] << fixedLength
// [4, 6] << fixedLengthWithOffset
// [0, 2, 4, 6, 8, 10, ...] << lengthTracking
// [4, 6, 8, 10, ...] << lengthTrackingWithOffset
assertEquals([0, 2, 4, 6], ToNumbersWithEntries(fixedLength));
assertEquals([0, 2, 4, 6], ValuesToNumbers(fixedLength));
assertEquals([0, 1, 2, 3], Keys(fixedLength));
assertEquals([4, 6], ToNumbersWithEntries(fixedLengthWithOffset));
assertEquals([4, 6], ValuesToNumbers(fixedLengthWithOffset));
assertEquals([0, 1], Keys(fixedLengthWithOffset));
assertEquals([0, 2, 4, 6, 8, 10], ToNumbersWithEntries(lengthTracking));
assertEquals([0, 2, 4, 6, 8, 10], ValuesToNumbers(lengthTracking));
assertEquals([0, 1, 2, 3, 4, 5], Keys(lengthTracking));
assertEquals([4, 6, 8, 10], ToNumbersWithEntries(lengthTrackingWithOffset));
assertEquals([4, 6, 8, 10], ValuesToNumbers(lengthTrackingWithOffset));
assertEquals([0, 1, 2, 3], Keys(lengthTrackingWithOffset));
}
})();
(function EntriesKeysValuesGrowMidIteration() {
// Orig. array: [0, 2, 4, 6]
// [0, 2, 4, 6] << fixedLength
// [4, 6] << fixedLengthWithOffset
// [0, 2, 4, 6, ...] << lengthTracking
// [4, 6, ...] << lengthTrackingWithOffset
function CreateGsabForTest(ctor) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
// Write some data into the array.
const taWrite = new ctor(gsab);
for (let i = 0; i < 4; ++i) {
WriteToTypedArray(taWrite, i, 2 * i);
}
return gsab;
}
// Iterating with entries() (the 4 loops below).
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLength = new ctor(gsab, 0, 4);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLength.entries(),
[[0, 0], [1, 2], [2, 4], [3, 6]],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLengthWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT, 2);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLengthWithOffset.entries(),
[[0, 4], [1, 6]],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTracking = new ctor(gsab, 0);
TestIterationAndGrow(lengthTracking.entries(),
[[0, 0], [1, 2], [2, 4], [3, 6], [4, 0], [5, 0]],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTrackingWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT);
TestIterationAndGrow(lengthTrackingWithOffset.entries(),
[[0, 4], [1, 6], [2, 0], [3, 0]],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
// Iterating with keys() (the 4 loops below).
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLength = new ctor(gsab, 0, 4);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLength.keys(),
[0, 1, 2, 3],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLengthWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT, 2);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLengthWithOffset.keys(),
[0, 1],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTracking = new ctor(gsab, 0);
TestIterationAndGrow(lengthTracking.keys(),
[0, 1, 2, 3, 4, 5],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTrackingWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT);
TestIterationAndGrow(lengthTrackingWithOffset.keys(),
[0, 1, 2, 3],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
// Iterating with values() (the 4 loops below).
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLength = new ctor(gsab, 0, 4);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLength.values(),
[0, 2, 4, 6],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const fixedLengthWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT, 2);
// The fixed length array is not affected by resizing.
TestIterationAndGrow(fixedLengthWithOffset.values(),
[4, 6],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTracking = new ctor(gsab, 0);
TestIterationAndGrow(lengthTracking.values(),
[0, 2, 4, 6, 0, 0],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
for (let ctor of ctors) {
const gsab = CreateGsabForTest(ctor);
const lengthTrackingWithOffset = new ctor(gsab, 2 * ctor.BYTES_PER_ELEMENT);
TestIterationAndGrow(lengthTrackingWithOffset.values(),
[4, 6, 0, 0],
gsab, 2, 6 * ctor.BYTES_PER_ELEMENT);
}
})();
......@@ -50,6 +50,33 @@ function ToNumbers(array) {
return result;
}
function ToNumbersWithEntries(array) {
let result = [];
let expectedKey = 0;
for (let [key, value] of array.entries()) {
assertEquals(expectedKey, key);
++expectedKey;
result.push(Number(value));
}
return result;
}
function Keys(array) {
let result = [];
for (let key of array.keys()) {
result.push(key);
}
return result;
}
function ValuesToNumbers(array) {
let result = [];
for (let value of array.values()) {
result.push(Number(value));
}
return result;
}
function AtHelper(array, index) {
let result = array.at(index);
if (typeof result == 'bigint') {
......
......@@ -330,8 +330,6 @@
'built-ins/DataView/prototype/setUint16/resizable-buffer': [FAIL],
'built-ins/DataView/prototype/setUint32/resizable-buffer': [FAIL],
'built-ins/DataView/prototype/setUint8/resizable-buffer': [FAIL],
'built-ins/TypedArray/prototype/entries/BigInt/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/entries/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/every/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/every/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/filter/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
......@@ -352,8 +350,6 @@
'built-ins/TypedArray/prototype/indexOf/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/join/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/join/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/keys/BigInt/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/keys/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/lastIndexOf/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/lastIndexOf/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/map/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
......@@ -373,8 +369,6 @@
'built-ins/TypedArray/prototype/sort/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/toLocaleString/BigInt/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/toLocaleString/return-abrupt-from-this-out-of-bounds': [SKIP],
'built-ins/TypedArray/prototype/values/BigInt/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArray/prototype/values/return-abrupt-from-this-out-of-bounds': [FAIL],
'built-ins/TypedArrayConstructors/ctors/typedarray-arg/out-of-bounds-when-species-retrieved-different-type': [FAIL],
'built-ins/TypedArrayConstructors/ctors/typedarray-arg/out-of-bounds-when-species-retrieved-same-type': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment