From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- js/src/jit-test/tests/sharedbuf/asm-link.js | 15 +++ js/src/jit-test/tests/sharedbuf/byteLength.js | 8 ++ js/src/jit-test/tests/sharedbuf/gc-one-view.js | 11 ++ js/src/jit-test/tests/sharedbuf/gc-two-views.js | 12 ++ .../tests/sharedbuf/growable-sab-over-mailbox.js | 40 +++++++ js/src/jit-test/tests/sharedbuf/inline-access.js | 26 +++++ js/src/jit-test/tests/sharedbuf/is-zeroed.js | 13 +++ ...ut-of-bounds-to-in-bounds-index-over-mailbox.js | 38 +++++++ .../sharedbuf/sab-construct-noargs-1068458.js | 14 +++ js/src/jit-test/tests/sharedbuf/sab-gating.js | 4 + .../jit-test/tests/sharedbuf/slice-same-memory.js | 25 +++++ js/src/jit-test/tests/sharedbuf/slice.js | 121 +++++++++++++++++++++ js/src/jit-test/tests/sharedbuf/subtypes.js | 52 +++++++++ ...from-sharedtypedarray-with-overridden-length.js | 24 ++++ 14 files changed, 403 insertions(+) create mode 100644 js/src/jit-test/tests/sharedbuf/asm-link.js create mode 100644 js/src/jit-test/tests/sharedbuf/byteLength.js create mode 100644 js/src/jit-test/tests/sharedbuf/gc-one-view.js create mode 100644 js/src/jit-test/tests/sharedbuf/gc-two-views.js create mode 100644 js/src/jit-test/tests/sharedbuf/growable-sab-over-mailbox.js create mode 100644 js/src/jit-test/tests/sharedbuf/inline-access.js create mode 100644 js/src/jit-test/tests/sharedbuf/is-zeroed.js create mode 100644 js/src/jit-test/tests/sharedbuf/resized-out-of-bounds-to-in-bounds-index-over-mailbox.js create mode 100644 js/src/jit-test/tests/sharedbuf/sab-construct-noargs-1068458.js create mode 100644 js/src/jit-test/tests/sharedbuf/sab-gating.js create mode 100644 js/src/jit-test/tests/sharedbuf/slice-same-memory.js create mode 100644 js/src/jit-test/tests/sharedbuf/slice.js create mode 100644 js/src/jit-test/tests/sharedbuf/subtypes.js create mode 100644 js/src/jit-test/tests/sharedbuf/typedarray-from-sharedtypedarray-with-overridden-length.js (limited to 'js/src/jit-test/tests/sharedbuf') diff --git a/js/src/jit-test/tests/sharedbuf/asm-link.js b/js/src/jit-test/tests/sharedbuf/asm-link.js new file mode 100644 index 0000000000..865cd10786 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/asm-link.js @@ -0,0 +1,15 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Don't assert on linking. +// Provide superficial functionality. + +function $(stdlib, foreign, heap) { + "use asm"; + var f64 = new stdlib.Float64Array(heap); + function f() { var v=0.0; v=+f64[0]; return +v; } + return f +} + +var heap = new SharedArrayBuffer(65536); +(new Float64Array(heap))[0] = 3.14159; +assertEq($(this, {}, heap)(), 3.14159); diff --git a/js/src/jit-test/tests/sharedbuf/byteLength.js b/js/src/jit-test/tests/sharedbuf/byteLength.js new file mode 100644 index 0000000000..f2501c55e3 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/byteLength.js @@ -0,0 +1,8 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// SharedArrayBuffer.prototype.byteLength + +load(libdir + "asserts.js"); + +let buffer = new SharedArrayBuffer(137); +assertEq(buffer.byteLength, 137); diff --git a/js/src/jit-test/tests/sharedbuf/gc-one-view.js b/js/src/jit-test/tests/sharedbuf/gc-one-view.js new file mode 100644 index 0000000000..03f1dddf8c --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/gc-one-view.js @@ -0,0 +1,11 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Test tracing of a single linked ArrayBufferViewObject. + +function f() { + var x = new SharedArrayBuffer(0x1000); + var y = new Int32Array(x); + gc(); +} + +f(); diff --git a/js/src/jit-test/tests/sharedbuf/gc-two-views.js b/js/src/jit-test/tests/sharedbuf/gc-two-views.js new file mode 100644 index 0000000000..6a16004b07 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/gc-two-views.js @@ -0,0 +1,12 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Test tracing of two views of a SharedArrayBuffer. Uses a different path. + +function f() { + var x = new SharedArrayBuffer(0x1000); + var y = new Int32Array(x); + var z = new Int8Array(x); + gc(); +} + +f(); diff --git a/js/src/jit-test/tests/sharedbuf/growable-sab-over-mailbox.js b/js/src/jit-test/tests/sharedbuf/growable-sab-over-mailbox.js new file mode 100644 index 0000000000..3ffb29cc3d --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/growable-sab-over-mailbox.js @@ -0,0 +1,40 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !this.SharedArrayBuffer?.prototype?.grow + +var gsab = new SharedArrayBuffer(4, {maxByteLength: 16}); + +// Test byte lengths are correct. +assertEq(gsab.byteLength, 4); +assertEq(gsab.maxByteLength, 16); + +// Pass |gsab| to the mailbox. +setSharedObject(gsab); + +// Retrieve again from the mailbox to create a new growable shared array buffer +// which points to the same memory. +var gsab2 = getSharedObject(); + +assertEq(gsab !== gsab2, true, "different objects expected"); + +// Byte lengths are correct for both objects. +assertEq(gsab.byteLength, 4); +assertEq(gsab.maxByteLength, 16); +assertEq(gsab2.byteLength, 4); +assertEq(gsab2.maxByteLength, 16); + +// Grow the original object. +gsab.grow(6); + +// Byte lengths are correct for both objects. +assertEq(gsab.byteLength, 6); +assertEq(gsab.maxByteLength, 16); +assertEq(gsab2.byteLength, 6); +assertEq(gsab2.maxByteLength, 16); + +// Grow the copy. +gsab2.grow(8); + +// Byte lengths are correct for both objects. +assertEq(gsab.byteLength, 8); +assertEq(gsab.maxByteLength, 16); +assertEq(gsab2.byteLength, 8); +assertEq(gsab2.maxByteLength, 16); diff --git a/js/src/jit-test/tests/sharedbuf/inline-access.js b/js/src/jit-test/tests/sharedbuf/inline-access.js new file mode 100644 index 0000000000..3672f65c1d --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/inline-access.js @@ -0,0 +1,26 @@ +// |jit-test| slow; skip-if: !this.SharedArrayBuffer +// +// This is for testing inlining behavior in the jits. +// +// For Baseline, run: +// $ IONFLAGS=bl-ic .../js --ion-off --baseline-eager inline-access.js +// Then inspect the output, there should be calls to "GetElem(TypedArray[Int32])", +// "GetProp(NativeObj/NativeGetter 0x...)", and "SetElem_TypedArray stub" +// for the read access, length access, and write access respectively, within f. +// +// For Ion, run: +// $ IONFLAGS=logs .../js --ion-offthread-compile=off inline-access.js +// Then postprocess with iongraph and verify (by inspecting MIR late in the pipeline) +// that it contains instructions like "typedarraylength", "loadtypedarrayelement", +// and "storetypedarrayelement". + +function f(ta) { + return (ta[2] = ta[0] + ta[1] + ta.length); +} + +var v = new Int32Array(new SharedArrayBuffer(4096)); +var sum = 0; +var iter = 1000; +for ( var i=0 ; i < iter ; i++ ) + sum += f(v); +assertEq(sum, v.length * iter); diff --git a/js/src/jit-test/tests/sharedbuf/is-zeroed.js b/js/src/jit-test/tests/sharedbuf/is-zeroed.js new file mode 100644 index 0000000000..e92b7013c8 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/is-zeroed.js @@ -0,0 +1,13 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Test that the SharedArrayBuffer memory is properly zeroed. + +function f() { + var x = new SharedArrayBuffer(4096); + var y = new Int32Array(x); + assertEq(y[0], 0); + assertEq(y[1], 0); + assertEq(y[1023], 0); +} + +f(); diff --git a/js/src/jit-test/tests/sharedbuf/resized-out-of-bounds-to-in-bounds-index-over-mailbox.js b/js/src/jit-test/tests/sharedbuf/resized-out-of-bounds-to-in-bounds-index-over-mailbox.js new file mode 100644 index 0000000000..5e5d61df25 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/resized-out-of-bounds-to-in-bounds-index-over-mailbox.js @@ -0,0 +1,38 @@ +// |jit-test| --enable-arraybuffer-resizable; skip-if: !this.SharedArrayBuffer?.prototype?.grow||helperThreadCount()===0 + +let gsab = new SharedArrayBuffer(3, {maxByteLength: 4}); + +setSharedObject(gsab); + +function worker(gsab) { + let ta = new Int8Array(gsab); + + // Wait until `valueOf` is called. + while (Atomics.load(ta, 0) === 0); + + // Now grow the buffer. + gsab.grow(4); + + // Notify the buffer has been resized. + Atomics.store(ta, 1, 1); +} + +evalInWorker(`(${worker})(getSharedObject());`); + +let ta = new Int8Array(gsab); + +let value = { + valueOf() { + // Notify we're in `valueOf()`. + Atomics.store(ta, 0, 1); + + // Wait until buffer has been resized. + while (Atomics.load(ta, 1) === 0); + + // Continue execution. + return 0; + } +}; + +// Write into currently out-of-bounds, but later in-bounds index. +ta[3] = value; diff --git a/js/src/jit-test/tests/sharedbuf/sab-construct-noargs-1068458.js b/js/src/jit-test/tests/sharedbuf/sab-construct-noargs-1068458.js new file mode 100644 index 0000000000..28333d4655 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/sab-construct-noargs-1068458.js @@ -0,0 +1,14 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Note that as of 2014-09-18 it is not correct to construct a SharedArrayBuffer without +// a length acceptable to asm.js: at-least 4K AND (power-of-two OR multiple-of-16M). +// That is likely to change however (see bug 1068684). The test case is constructed +// to take that into account by catching exceptions. That does not impact the +// original bug, which is an assertion in the implementation. + +try { + new SharedArrayBuffer // No arguments +} +catch (e) { + // Ignore it +} diff --git a/js/src/jit-test/tests/sharedbuf/sab-gating.js b/js/src/jit-test/tests/sharedbuf/sab-gating.js new file mode 100644 index 0000000000..0f7cd07c8d --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/sab-gating.js @@ -0,0 +1,4 @@ +// Check gating of shared memory features in plain js (bug 1231338). + +assertEq(sharedMemoryEnabled(), !!this.SharedArrayBuffer); +assertEq(sharedMemoryEnabled(), !!this.Atomics); diff --git a/js/src/jit-test/tests/sharedbuf/slice-same-memory.js b/js/src/jit-test/tests/sharedbuf/slice-same-memory.js new file mode 100644 index 0000000000..22c2215424 --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/slice-same-memory.js @@ -0,0 +1,25 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +load(libdir + "asserts.js"); + +var sab = new SharedArrayBuffer(1 * Int32Array.BYTES_PER_ELEMENT); + +// Make a copy, sharing the same memory +var sab2 = (setSharedObject(sab), getSharedObject()); + +// Assert it's not the same object +assertEq(sab === sab2, false); + +// Assert they're sharing memory +new Int32Array(sab)[0] = 0x12345678; +assertEq(new Int32Array(sab2)[0], 0x12345678) + +sab.constructor = { + [Symbol.species]: function(length) { + return sab2; + } +}; + +// This should throw because the buffer being sliced shares memory with the new +// buffer it constructs. +assertThrowsInstanceOf(() => sab.slice(), TypeError); diff --git a/js/src/jit-test/tests/sharedbuf/slice.js b/js/src/jit-test/tests/sharedbuf/slice.js new file mode 100644 index 0000000000..0ae188e79f --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/slice.js @@ -0,0 +1,121 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// SharedArrayBuffer.prototype.slice + +load(libdir + "asserts.js"); + +let buf = new SharedArrayBuffer(1024); +let bufAsI8 = new Int8Array(buf); +for ( let i=0 ; i < buf.length ; i++ ) + bufAsI8[i] = i; + +let base = 10; +let len = 10; + +let buf2 = buf.slice(base, base+len); + +// Smells right? +assertEq(buf2 instanceof SharedArrayBuffer, true); +assertEq(buf2.byteLength, len); + +// Data got copied correctly? +let buf2AsI8 = new Int8Array(buf2); +for ( let i=0 ; i < buf2AsI8.length ; i++ ) + assertEq(buf2AsI8[i], bufAsI8[base+i]); + +// Storage not shared? +let correct = bufAsI8[base]; +bufAsI8[base]++; +assertEq(buf2AsI8[0], correct); + +// Start beyond end +let notail = buf.slice(buf.byteLength+1); +assertEq(notail.byteLength, 0); + +// Negative start +let tail = buf.slice(-5, buf.byteLength); +assertEq(tail.byteLength, 5); +let tailAsI8 = new Int8Array(tail); +for ( let i=0 ; i < tailAsI8.length ; i++ ) + assertEq(tailAsI8[i], bufAsI8[buf.byteLength-5+i]); + +// Negative end +let head = buf.slice(0, -5); +assertEq(head.byteLength, buf.byteLength-5); +let headAsI8 = new Int8Array(head); +for ( let i=0 ; i < headAsI8.length ; i++ ) + assertEq(headAsI8[i], bufAsI8[i]); + +// Subtyping +class MySharedArrayBuffer1 extends SharedArrayBuffer { + constructor(n) { super(n) } +} + +let myBuf = new MySharedArrayBuffer1(1024); + +let myBufAsI8 = new Int8Array(myBuf); +for ( let i=0 ; i < myBuf.length ; i++ ) + myBufAsI8[i] = i; + +let myBufSlice = myBuf.slice(0, 20); + +assertEq(myBufSlice instanceof MySharedArrayBuffer1, true); + +assertEq(myBufSlice.byteLength, 20); + +let myBufSliceAsI8 = new Int8Array(myBufSlice); +for ( let i=0 ; i < myBufSlice.length ; i++ ) + assertEq(myBufAsI8[i], myBufSliceAsI8[i]); + +// Error mode: the method requires an object +assertThrowsInstanceOf(() => buf.slice.call(false, 0, 1), TypeError); + +// Error mode: the method is not generic. +assertThrowsInstanceOf(() => buf.slice.call([1,2,3], 0, 1), TypeError); + +// Error mode (step 15): the buffer constructed on behalf of slice +// is too short. + +class MySharedArrayBuffer2 extends SharedArrayBuffer { + constructor(n) { super(n-1) } +} + +let myBuf2 = new MySharedArrayBuffer2(10); + +assertThrowsInstanceOf(() => myBuf2.slice(0, 5), TypeError); + +// Error mode (step 13): the buffer constructed on behalf of slice +// is not a SharedArrayBuffer. + +let subvert = false; + +class MySharedArrayBuffer3 extends SharedArrayBuffer { + constructor(n) { + super(n); + if (subvert) + return new Array(n); + } +} + +let myBuf3 = new MySharedArrayBuffer3(10); + +subvert = true; +assertThrowsInstanceOf(() => myBuf3.slice(0, 5), TypeError); + +// Error mode (step 14): the buffer constructed on behalf of slice +// is the same as the input buffer. + +let sneaky = null; + +class MySharedArrayBuffer4 extends SharedArrayBuffer { + constructor(n) { + super(n); + if (sneaky) + return sneaky; + } +} + +let myBuf4 = new MySharedArrayBuffer4(10); + +sneaky = myBuf4; +assertThrowsInstanceOf(() => myBuf4.slice(0, 5), TypeError); diff --git a/js/src/jit-test/tests/sharedbuf/subtypes.js b/js/src/jit-test/tests/sharedbuf/subtypes.js new file mode 100644 index 0000000000..cf3adde3ce --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/subtypes.js @@ -0,0 +1,52 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// Test cases for subclasses of SharedArrayBuffer. + +load(libdir + "asserts.js"); + +// Basic subclassing. + +class MySharedArrayBuffer1 extends SharedArrayBuffer { + constructor(n) { super(n) } +} + +let mv1 = new MySharedArrayBuffer1(1024); +assertEq(mv1 instanceof SharedArrayBuffer, true); +assertEq(mv1 instanceof MySharedArrayBuffer1, true); +assertEq(mv1.byteLength, 1024); + +// Can construct views on the subclasses and read/write elements. + +let mva1 = new Int8Array(mv1); +assertEq(mva1.length, mv1.byteLength); +assertEq(mva1.buffer, mv1); + +for ( let i=1 ; i < mva1.length ; i++ ) + mva1[i] = i; + +for ( let i=1 ; i < mva1.length ; i++ ) + assertEq(mva1[i], (i << 24) >> 24); + +// Passing modified arguments to superclass to get a different length. + +class MySharedArrayBuffer2 extends SharedArrayBuffer { + constructor(n) { super(n-1) } +} + +let mv2 = new MySharedArrayBuffer2(10); +assertEq(mv2 instanceof SharedArrayBuffer, true); +assertEq(mv2 instanceof MySharedArrayBuffer2, true); +assertEq(mv2.byteLength, 9); + +// Returning a different object altogether. + +class MySharedArrayBuffer3 extends SharedArrayBuffer { + constructor(n) { + return new Array(n); + } +} + +let mv3 = new MySharedArrayBuffer3(10); +assertEq(mv3 instanceof Array, true); +assertEq(mv3 instanceof MySharedArrayBuffer3, false); +assertEq(mv3.length, 10); diff --git a/js/src/jit-test/tests/sharedbuf/typedarray-from-sharedtypedarray-with-overridden-length.js b/js/src/jit-test/tests/sharedbuf/typedarray-from-sharedtypedarray-with-overridden-length.js new file mode 100644 index 0000000000..100443495a --- /dev/null +++ b/js/src/jit-test/tests/sharedbuf/typedarray-from-sharedtypedarray-with-overridden-length.js @@ -0,0 +1,24 @@ +// |jit-test| skip-if: !this.SharedArrayBuffer + +// This would hit an assertion in debug builds due to an incorrect +// type guard in the code that copies data from STA to TA. + +// Original test case + +var sab = new SharedArrayBuffer(4); + +var x = new Int32Array(sab); +x.__proto__ = (function(){}); +new Uint8Array(x); // Would assert here + +// Supposedly equivalent test case, provoking the error directly + +var x = new Int32Array(sab); +Object.defineProperty(x, "length", { value: 0 }); +new Uint8Array(x); // Would assert here + +// Derived test case - would not tickle the bug, though. + +var x = new Int32Array(sab); +Object.defineProperty(x, "length", { value: 1 << 20 }); +new Uint8Array(x); -- cgit v1.2.3