v8/test/mjsunit/rab-gsab-transfer-to-worker.js
Marja Hölttä 45642bf199 [rab/gsab] Enable transferring RAB / GSAB to workers
1) When transferring ArrayBuffers, retain resizability

2) Fix transmitting TypedArray flags; we cannot set the flags after
TypedArray creation, since the map would then be wrong.

Bug: v8:11111
Change-Id: Ic2fa3e6a4db1cb82a3751d2b114353fb477a54c9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4064463
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84628}
2022-12-05 08:06:11 +00:00

233 lines
6.8 KiB
JavaScript

// Copyright 2022 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
(function TransferArrayBuffer() {
function workerCode() {
onmessage = function(msg) {
const ab = msg.data;
postMessage(ab.byteLength + ' ' + ab.maxByteLength);
postMessage(ab.resizable + ' ' + ab.growable);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const ab = new ArrayBuffer(16);
worker.postMessage({data: ab}, [ab]);
assertEquals('16 16', worker.getMessage());
assertEquals('false undefined', worker.getMessage());
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
worker.postMessage({data: rab}, [rab]);
assertEquals('16 1024', worker.getMessage());
assertEquals('true undefined', worker.getMessage());
const sab = new SharedArrayBuffer(16);
worker.postMessage({data: sab});
assertEquals('16 16', worker.getMessage());
assertEquals('undefined false', worker.getMessage());
const gsab = new SharedArrayBuffer(16, {maxByteLength: 1024});
worker.postMessage({data: gsab});
assertEquals('16 1024', worker.getMessage());
assertEquals('undefined true', worker.getMessage());
})();
(function TransferLengthTrackingRabBackedTypedArray() {
function workerCode() {
onmessage = function(msg) {
postMessage(msg.data.length);
msg.data.buffer.resize(150);
postMessage(msg.data.length);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(rab);
worker.postMessage({data: ta}, [rab]);
assertEquals(16, worker.getMessage());
assertEquals(150, worker.getMessage());
})();
(function TransferLengthTrackingGsabBackedTypedArray() {
function workerCode() {
onmessage = function(msg) {
postMessage(msg.data.length);
msg.data.buffer.grow(150);
postMessage(msg.data.length);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const gsab = new SharedArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(gsab);
worker.postMessage({data: ta});
assertEquals(16, worker.getMessage());
assertEquals(150, worker.getMessage());
})();
(function TransferFixedLengthRabBackedTypedArray() {
function workerCode() {
onmessage = function(msg) {
const ta = msg.data;
postMessage(`${ta.length} ${ta[0]} ${ta[1]} ${ta[2]}`);
ta.buffer.resize(2);
postMessage(`${ta.length}`);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(rab, 0, 10);
ta[0] = 30;
ta[1] = 11;
ta[2] = 22;
worker.postMessage({data: ta}, [rab]);
assertEquals('10 30 11 22', worker.getMessage());
assertEquals('0', worker.getMessage());
})();
(function TransferOutOfBoundsFixedLengthTypedArray() {
function workerCode() {
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(rab, 0, 10);
rab.resize(0);
assertThrows(() => { worker.postMessage({data: ta}, [rab]) });
})();
(function TransferGsabBackedFixedLengthTypedArray() {
function workerCode() {
onmessage = function(msg) {
const ta = msg.data;
postMessage(`${ta.length} ${ta[0]} ${ta[1]} ${ta[2]}`);
ta.buffer.grow(20);
postMessage(`${ta.length} ${ta[0]} ${ta[1]} ${ta[2]}`);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const gsab = new SharedArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(gsab, 0, 10);
ta[0] = 30;
ta[1] = 11;
ta[2] = 22;
worker.postMessage({data: ta});
assertEquals('10 30 11 22', worker.getMessage());
assertEquals('10 30 11 22', worker.getMessage());
})();
(function TransferLengthTrackingDataView() {
function workerCode() {
onmessage = function(msg) {
const dv = msg.data;
postMessage(dv.byteLength);
dv.buffer.resize(150);
postMessage(dv.byteLength);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const dv = new DataView(rab);
worker.postMessage({data: dv}, [rab]);
assertEquals(16, worker.getMessage());
assertEquals(150, worker.getMessage());
})();
(function TransferFixedLengthDataView() {
function workerCode() {
onmessage = function(msg) {
const dv = msg.data;
postMessage(`${dv.byteLength} ${dv.getUint8(0)} ${dv.getUint8(1)}`);
dv.buffer.resize(2);
try {
dv.byteLength;
} catch(e) {
postMessage('byteLength getter threw');
}
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const ta = new Uint8Array(rab);
ta[0] = 30;
ta[1] = 11;
worker.postMessage({data: new DataView(rab, 0, 10)}, [rab]);
assertEquals('10 30 11', worker.getMessage());
assertEquals('byteLength getter threw', worker.getMessage());
})();
(function TransferOutOfBoundsDataView1() {
function workerCode() {}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const dv = new Uint8Array(rab, 0, 10);
rab.resize(0);
assertThrows(() => { worker.postMessage({data: dv}, [rab]) });
})();
(function TransferOutOfBoundsDataView2() {
function workerCode() {}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
const dv = new Uint8Array(rab, 2);
rab.resize(1);
assertThrows(() => { worker.postMessage({data: dv}, [rab]) });
})();
(function TransferZeroLengthDataView1() {
function workerCode() {
onmessage = function(msg) {
const dv = msg.data;
postMessage(`${dv.byteLength}`);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
worker.postMessage({data: new DataView(rab, 16)}, [rab]);
assertEquals('0', worker.getMessage());
})();
(function TransferZeroLengthDataView2() {
function workerCode() {
onmessage = function(msg) {
const dv = msg.data;
postMessage(`${dv.byteLength}`);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
worker.postMessage({data: new DataView(rab, 16, 0)}, [rab]);
assertEquals('0', worker.getMessage());
})();
(function TransferZeroLengthDataView3() {
function workerCode() {
onmessage = function(msg) {
const dv = msg.data;
postMessage(`${dv.byteLength}`);
}
}
const worker = new Worker(workerCode, {type: 'function'});
const rab = new ArrayBuffer(16, {maxByteLength: 1024});
worker.postMessage({data: new DataView(rab, 5, 0)}, [rab]);
assertEquals('0', worker.getMessage());
})();