Commit 2176ead6 authored by Marja Hölttä's avatar Marja Hölttä Committed by V8 LUCI CQ

[rab/gsab] Atomics.wait + waitAsync: Support GSAB

Bug: v8:11111
Change-Id: Ifb3776bce308d869064120d5e28a2ea7df943757
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3578652Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80142}
parent fce1047f
......@@ -99,7 +99,7 @@ V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
Nothing<size_t>());
size_t access_index;
size_t typed_array_length = typed_array->length();
size_t typed_array_length = typed_array->GetLength();
if (!TryNumberToSize(*access_index_obj, &access_index) ||
access_index >= typed_array_length) {
isolate->Throw(*isolate->factory()->NewRangeError(
......
......@@ -312,7 +312,7 @@ template <typename T>
Object FutexEmulation::Wait(Isolate* isolate, WaitMode mode,
Handle<JSArrayBuffer> array_buffer, size_t addr,
T value, double rel_timeout_ms) {
DCHECK_LT(addr, array_buffer->byte_length());
DCHECK_LT(addr, array_buffer->GetByteLength());
bool use_timeout = rel_timeout_ms != V8_INFINITY;
int64_t rel_timeout_ns = -1;
......@@ -653,7 +653,7 @@ Object FutexEmulation::WaitAsync(Isolate* isolate,
Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr,
uint32_t num_waiters_to_wake) {
DCHECK_LT(addr, array_buffer->byte_length());
DCHECK_LT(addr, array_buffer->GetByteLength());
int waiters_woken = 0;
std::shared_ptr<BackingStore> backing_store = array_buffer->GetBackingStore();
......@@ -916,7 +916,7 @@ void FutexEmulation::IsolateDeinit(Isolate* isolate) {
Object FutexEmulation::NumWaitersForTesting(Handle<JSArrayBuffer> array_buffer,
size_t addr) {
DCHECK_LT(addr, array_buffer->byte_length());
DCHECK_LT(addr, array_buffer->GetByteLength());
std::shared_ptr<BackingStore> backing_store = array_buffer->GetBackingStore();
NoGarbageCollectionMutexGuard lock_guard(g_mutex.Pointer());
......@@ -961,7 +961,7 @@ Object FutexEmulation::NumAsyncWaitersForTesting(Isolate* isolate) {
Object FutexEmulation::NumUnresolvedAsyncPromisesForTesting(
Handle<JSArrayBuffer> array_buffer, size_t addr) {
DCHECK_LT(addr, array_buffer->byte_length());
DCHECK_LT(addr, array_buffer->GetByteLength());
std::shared_ptr<BackingStore> backing_store = array_buffer->GetBackingStore();
NoGarbageCollectionMutexGuard lock_guard(g_mutex.Pointer());
......
......@@ -27,7 +27,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
size_t index = NumberToSize(args[1]);
CHECK(!sta->WasDetached());
CHECK(sta->GetBuffer()->is_shared());
CHECK_LT(index, sta->length());
CHECK_LT(index, sta->GetLength());
CHECK_EQ(sta->type(), kExternalInt32Array);
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
......@@ -48,7 +48,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsNumUnresolvedAsyncPromisesForTesting) {
size_t index = NumberToSize(args[1]);
CHECK(!sta->WasDetached());
CHECK(sta->GetBuffer()->is_shared());
CHECK_LT(index, sta->length());
CHECK_LT(index, sta->GetLength());
CHECK_EQ(sta->type(), kExternalInt32Array);
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-rab-gsab --allow-natives-syntax
"use strict";
d8.file.execute('test/mjsunit/typedarray-helpers.js');
(function AtomicsWait() {
const gsab = CreateGrowableSharedArrayBuffer(16, 32);
const i32a = new Int32Array(gsab);
const workerScript = function() {
onmessage = function(msg) {
const i32a = new Int32Array(msg.gsab, msg.offset);
const result = Atomics.wait(i32a, 0, 0, 5000);
postMessage(result);
};
}
const worker = new Worker(workerScript, {type: 'function'});
worker.postMessage({gsab: gsab, offset: 0});
// Spin until the worker is waiting on the futex.
while (%AtomicsNumWaitersForTesting(i32a, 0) != 1) {}
Atomics.notify(i32a, 0, 1);
assertEquals("ok", worker.getMessage());
worker.terminate();
})();
(function AtomicsWaitAfterGrowing() {
// Test that Atomics.wait works on indices that are valid only after growing.
const gsab = CreateGrowableSharedArrayBuffer(4 * 4, 8 * 4);
const i32a = new Int32Array(gsab);
gsab.grow(6 * 4);
const index = 5;
const workerScript = function() {
onmessage = function(msg) {
const i32a = new Int32Array(msg.gsab, msg.offset);
const result = Atomics.wait(i32a, 5, 0, 5000);
postMessage(result);
};
}
const worker = new Worker(workerScript, {type: 'function'});
worker.postMessage({gsab: gsab, offset: 0});
// Spin until the worker is waiting on the futex.
while (%AtomicsNumWaitersForTesting(i32a, index) != 1) {}
Atomics.notify(i32a, index, 1);
assertEquals("ok", worker.getMessage());
worker.terminate();
})();
(function AtomicsWaitAsync() {
for (let ctor of [Int32Array, BigInt64Array, MyBigInt64Array]) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab, 0);
const initialValue = false; // Can be converted to both Number and BigInt.
const result = Atomics.waitAsync(lengthTracking, 0, initialValue);
let wokeUp = false;
result.value.then(
(value) => { assertEquals("ok", value); wokeUp = true; },
() => { assertUnreachable(); });
assertEquals(true, result.async);
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
const notifyReturnValue = Atomics.notify(lengthTracking, 0, 1);
assertEquals(1, notifyReturnValue);
function continuation() {
assertTrue(wokeUp);
}
setTimeout(continuation, 0);
}
})();
(function AtomicsWaitAsyncAfterGrowing() {
for (let ctor of [Int32Array, BigInt64Array, MyBigInt64Array]) {
const gsab = CreateGrowableSharedArrayBuffer(4 * ctor.BYTES_PER_ELEMENT,
8 * ctor.BYTES_PER_ELEMENT);
const lengthTracking = new ctor(gsab, 0);
gsab.grow(6 * ctor.BYTES_PER_ELEMENT);
const index = 5;
const initialValue = false; // Can be converted to both Number and BigInt.
const result = Atomics.waitAsync(lengthTracking, index, initialValue);
let wokeUp = false;
result.value.then(
(value) => { assertEquals("ok", value); wokeUp = true; },
() => { assertUnreachable(); });
assertEquals(true, result.async);
const notifyReturnValue = Atomics.notify(lengthTracking, index, 1);
assertEquals(1, notifyReturnValue);
function continuation() {
assertTrue(wokeUp);
}
setTimeout(continuation, 0);
}
})();
(function AtomicsWaitFailWithWrongArrayTypes() {
const gsab = CreateGrowableSharedArrayBuffer(400, 800);
const i8a = new Int8Array(gsab);
const i16a = new Int16Array(gsab);
const ui8a = new Uint8Array(gsab);
const ui8ca = new Uint8ClampedArray(gsab);
const ui16a = new Uint16Array(gsab);
const ui32a = new Uint32Array(gsab);
const f32a = new Float32Array(gsab);
const f64a = new Float64Array(gsab);
const myui8 = new MyUint8Array(gsab);
const bui64 = new BigUint64Array(gsab);
[i8a, i16a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a, myui8, bui64].forEach(
function(ta) {
// Can be converted both to Number and BigInt.
const exampleValue = false;
assertThrows(() => { Atomics.wait(ta, 0, exampleValue); },
TypeError);
assertThrows(() => { Atomics.notify(ta, 0, 1); },
TypeError);
assertThrows(() => { Atomics.waitAsync(ta, 0, exampleValue); },
TypeError);
});
})();
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