From 40a355a42d4a9444dc753c04c6608dade2f06a23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:27 +0200 Subject: Adding upstream version 125.0.1. Signed-off-by: Daniel Baumann --- ...y-barrier-bytelength-with-non-growable-write.js | 102 ++++++++++++++++++++ .../growable-sab-memory-barrier-bytelength.js | 67 ++++++++++++++ ...-dataview-bytelength-with-non-growable-write.js | 103 +++++++++++++++++++++ ...wable-sab-memory-barrier-dataview-bytelength.js | 68 ++++++++++++++ ...ypedarray-bytelength-with-non-growable-write.js | 103 +++++++++++++++++++++ ...ble-sab-memory-barrier-typedarray-bytelength.js | 67 ++++++++++++++ ...er-typedarray-length-with-non-growable-write.js | 103 +++++++++++++++++++++ ...rowable-sab-memory-barrier-typedarray-length.js | 67 ++++++++++++++ 8 files changed, 680 insertions(+) create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength-with-non-growable-write.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength-with-non-growable-write.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength-with-non-growable-write.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length-with-non-growable-write.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length.js (limited to 'js/src/jit-test/tests/sharedbuf') diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength-with-non-growable-write.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength-with-non-growable-write.js new file mode 100644 index 0000000000..32005f4725 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength-with-non-growable-write.js @@ -0,0 +1,102 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab, sab) { + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta2, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + var sab = new SharedArrayBuffer(12); + + // Start the worker. + { + let buffers = [gsab, sab]; + + // Shared memory locations: + // + // 0: Number of buffers + // 1: Ready-Flag Worker + // 2: Ready-Flag Main + let sync = new Int32Array(new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT)); + sync[0] = buffers.length; + + setSharedObject(sync.buffer); + + evalInWorker(` + let buffers = []; + let sync = new Int32Array(getSharedObject()); + let n = sync[0]; + for (let i = 0; i < n; ++i) { + // Notify we're ready to receive. + Atomics.store(sync, 1, 1); + + // Wait until buffer is in mailbox. + while (Atomics.compareExchange(sync, 2, 1, 0) !== 1); + + buffers.push(getSharedObject()); + } + (${worker})(...buffers); + `); + + for (let buffer of buffers) { + // Wait until worker is ready. + while (Atomics.compareExchange(sync, 1, 1, 0) !== 1); + + setSharedObject(buffer); + + // Notify buffer is in mailbox. + Atomics.store(sync, 2, 1); + } + } + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return {gsab, sab}; +} + +function testGrowableSharedArrayBufferByteLength() { + var {gsab, sab} = setup(); + var ta2 = new Int32Array(sab); + var r = 0; + + // |gsab.byteLength| is a seq-cst load, so it must prevent reordering any + // other loads, including unordered loads like |ta2[2]|. + while (gsab.byteLength <= 12) { + // |ta2[2]| is an unordered load, so it's hoistable by default. + r += ta2[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "gsab.byteLength acts as a memory barrier, so ta2[2] can't be hoisted" + ); +} +testGrowableSharedArrayBufferByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength.js new file mode 100644 index 0000000000..c2f27d967c --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-bytelength.js @@ -0,0 +1,67 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab) { + var ta = new Int32Array(gsab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + + // Pass |gsab| to the mailbox. + setSharedObject(gsab); + + // Start the worker. + evalInWorker(` + (${worker})(getSharedObject()); + `); + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return gsab; +} + +function testGrowableSharedArrayBufferByteLength() { + var gsab = setup(); + var ta = new Int32Array(gsab); + var r = 0; + + // |gsab.byteLength| is a seq-cst load, so it must prevent reordering any + // other loads, including unordered loads like |ta[2]|. + while (gsab.byteLength <= 12) { + // |ta[2]| is an unordered load, so it's hoistable by default. + r += ta[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "gsab.byteLength acts as a memory barrier, so ta[2] can't be hoisted" + ); +} +testGrowableSharedArrayBufferByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength-with-non-growable-write.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength-with-non-growable-write.js new file mode 100644 index 0000000000..fc05df3ab1 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength-with-non-growable-write.js @@ -0,0 +1,103 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab, sab) { + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta2, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + var sab = new SharedArrayBuffer(12); + + // Start the worker. + { + let buffers = [gsab, sab]; + + // Shared memory locations: + // + // 0: Number of buffers + // 1: Ready-Flag Worker + // 2: Ready-Flag Main + let sync = new Int32Array(new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT)); + sync[0] = buffers.length; + + setSharedObject(sync.buffer); + + evalInWorker(` + let buffers = []; + let sync = new Int32Array(getSharedObject()); + let n = sync[0]; + for (let i = 0; i < n; ++i) { + // Notify we're ready to receive. + Atomics.store(sync, 1, 1); + + // Wait until buffer is in mailbox. + while (Atomics.compareExchange(sync, 2, 1, 0) !== 1); + + buffers.push(getSharedObject()); + } + (${worker})(...buffers); + `); + + for (let buffer of buffers) { + // Wait until worker is ready. + while (Atomics.compareExchange(sync, 1, 1, 0) !== 1); + + setSharedObject(buffer); + + // Notify buffer is in mailbox. + Atomics.store(sync, 2, 1); + } + } + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return {gsab, sab}; +} + +function testDataViewByteLength() { + var {gsab, sab} = setup(); + var dv = new DataView(gsab); + var ta2 = new Int32Array(sab); + var r = 0; + + // |dv.byteLength| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta2[2]|. + while (dv.byteLength <= 12) { + // |ta2[2]| is an unordered load, so it's hoistable by default. + r += ta2[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "dv.byteLength acts as a memory barrier, so ta2[2] can't be hoisted" + ); +} +testDataViewByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength.js new file mode 100644 index 0000000000..51ed63f254 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-dataview-bytelength.js @@ -0,0 +1,68 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab) { + var ta = new Int32Array(gsab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + + // Pass |gsab| to the mailbox. + setSharedObject(gsab); + + // Start the worker. + evalInWorker(` + (${worker})(getSharedObject()); + `); + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return gsab; +} + +function testDataViewByteLength() { + var gsab = setup(); + var ta = new Int32Array(gsab); + var dv = new DataView(gsab); + var r = 0; + + // |dv.byteLength| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta[2]|. + while (dv.byteLength <= 12) { + // |ta[2]| is an unordered load, so it's hoistable by default. + r += ta[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "dv.byteLength acts as a memory barrier, so ta[2] can't be hoisted" + ); +} +testDataViewByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength-with-non-growable-write.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength-with-non-growable-write.js new file mode 100644 index 0000000000..fd92ff615a --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength-with-non-growable-write.js @@ -0,0 +1,103 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab, sab) { + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta2, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + var sab = new SharedArrayBuffer(12); + + // Start the worker. + { + let buffers = [gsab, sab]; + + // Shared memory locations: + // + // 0: Number of buffers + // 1: Ready-Flag Worker + // 2: Ready-Flag Main + let sync = new Int32Array(new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT)); + sync[0] = buffers.length; + + setSharedObject(sync.buffer); + + evalInWorker(` + let buffers = []; + let sync = new Int32Array(getSharedObject()); + let n = sync[0]; + for (let i = 0; i < n; ++i) { + // Notify we're ready to receive. + Atomics.store(sync, 1, 1); + + // Wait until buffer is in mailbox. + while (Atomics.compareExchange(sync, 2, 1, 0) !== 1); + + buffers.push(getSharedObject()); + } + (${worker})(...buffers); + `); + + for (let buffer of buffers) { + // Wait until worker is ready. + while (Atomics.compareExchange(sync, 1, 1, 0) !== 1); + + setSharedObject(buffer); + + // Notify buffer is in mailbox. + Atomics.store(sync, 2, 1); + } + } + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return {gsab, sab}; +} + +function testTypedArrayByteLength() { + var {gsab, sab} = setup(); + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + var r = 0; + + // |ta.byteLength| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta2[2]|. + while (ta.byteLength <= 12) { + // |ta2[2]| is an unordered load, so it's hoistable by default. + r += ta2[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "ta.byteLength acts as a memory barrier, so ta2[2] can't be hoisted" + ); +} +testTypedArrayByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength.js new file mode 100644 index 0000000000..843f7dce15 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-bytelength.js @@ -0,0 +1,67 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab) { + var ta = new Int32Array(gsab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + + // Pass |gsab| to the mailbox. + setSharedObject(gsab); + + // Start the worker. + evalInWorker(` + (${worker})(getSharedObject()); + `); + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return gsab; +} + +function testTypedArrayByteLength() { + var gsab = setup(); + var ta = new Int32Array(gsab); + var r = 0; + + // |ta.byteLength| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta[2]|. + while (ta.byteLength <= 12) { + // |ta[2]| is an unordered load, so it's hoistable by default. + r += ta[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "ta.byteLength acts as a memory barrier, so ta[2] can't be hoisted" + ); +} +testTypedArrayByteLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length-with-non-growable-write.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length-with-non-growable-write.js new file mode 100644 index 0000000000..4371dd2b00 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length-with-non-growable-write.js @@ -0,0 +1,103 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab, sab) { + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta2, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + var sab = new SharedArrayBuffer(12); + + // Start the worker. + { + let buffers = [gsab, sab]; + + // Shared memory locations: + // + // 0: Number of buffers + // 1: Ready-Flag Worker + // 2: Ready-Flag Main + let sync = new Int32Array(new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT)); + sync[0] = buffers.length; + + setSharedObject(sync.buffer); + + evalInWorker(` + let buffers = []; + let sync = new Int32Array(getSharedObject()); + let n = sync[0]; + for (let i = 0; i < n; ++i) { + // Notify we're ready to receive. + Atomics.store(sync, 1, 1); + + // Wait until buffer is in mailbox. + while (Atomics.compareExchange(sync, 2, 1, 0) !== 1); + + buffers.push(getSharedObject()); + } + (${worker})(...buffers); + `); + + for (let buffer of buffers) { + // Wait until worker is ready. + while (Atomics.compareExchange(sync, 1, 1, 0) !== 1); + + setSharedObject(buffer); + + // Notify buffer is in mailbox. + Atomics.store(sync, 2, 1); + } + } + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return {gsab, sab}; +} + +function testTypedArrayLength() { + var {gsab, sab} = setup(); + var ta = new Int32Array(gsab); + var ta2 = new Int32Array(sab); + var r = 0; + + // |ta.length| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta2[2]|. + while (ta.length <= 3) { + // |ta2[2]| is an unordered load, so it's hoistable by default. + r += ta2[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "ta.length acts as a memory barrier, so ta2[2] can't be hoisted" + ); +} +testTypedArrayLength(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length.js b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length.js new file mode 100644 index 0000000000..b32af6ae78 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-memory-barrier-typedarray-length.js @@ -0,0 +1,67 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !ArrayBuffer.prototype.resize||!this.SharedArrayBuffer||helperThreadCount()===0 + +function setup() { + // Shared memory locations: + // + // 0: Lock + // 1: Sleep + // 2: Data + // 3: Unused + + function worker(gsab) { + var ta = new Int32Array(gsab); + + // Notify the main thread that the worker is ready. + Atomics.store(ta, 0, 1); + + // Sleep to give the main thread time to execute and tier-up the loop. + Atomics.wait(ta, 1, 0, 500); + + // Modify the memory read in the loop. + Atomics.store(ta, 2, 1); + + // Sleep again to give the main thread time to execute the loop. + Atomics.wait(ta, 1, 0, 100); + + // Grow the buffer. This modifies the loop condition. + gsab.grow(16); + } + + var gsab = new SharedArrayBuffer(12, {maxByteLength: 16}); + + // Pass |gsab| to the mailbox. + setSharedObject(gsab); + + // Start the worker. + evalInWorker(` + (${worker})(getSharedObject()); + `); + + // Wait until worker is ready. + var ta = new Int32Array(gsab); + while (Atomics.load(ta, 0) === 0); + + return gsab; +} + +function testTypedArrayLength() { + var gsab = setup(); + var ta = new Int32Array(gsab); + var r = 0; + + // |ta.length| is a seq-cst load, so it must prevent reordering any other + // loads, including unordered loads like |ta[2]|. + while (ta.length <= 3) { + // |ta[2]| is an unordered load, so it's hoistable by default. + r += ta[2]; + } + + // The memory location is first modified and then the buffer is grown, so we + // must observe reads of the modified memory location before exiting the loop. + assertEq( + r > 0, + true, + "ta.length acts as a memory barrier, so ta[2] can't be hoisted" + ); +} +testTypedArrayLength(); -- cgit v1.2.3