// Basic functional tests for the Atomics primitives. // // These do not test atomicity, just that calling and coercions and // indexing and exception behavior all work right. // // These do not test the wait/wake operations.
load(libdir + "asserts.js");
var DEBUG = false; // Set to true for useful printouts
function dprint(...xs) { if (!DEBUG) return; var s = ""; for ( var x in xs )
s += String(xs[x]);
print(s);
}
// Clone a function so that we get reliable inlining of primitives with --ion-eager. // For eg testMethod and testFunction that are polymorphic in the array a, // the inliner gets confused and stops inlining after Int8 -- not what we want. function CLONE(f) { returnthis.eval("(" + f.toString() + ")");
}
function testMethod(a, ...indices) {
dprint("Method: " + a.constructor.name); var poison; switch (a.BYTES_PER_ELEMENT) { case 1: poison = 0x5A; break; case 2: poison = 0x5A5A; break; case 4: poison = 0x5A5A5A5A; break;
} for ( var i=0 ; i < indices.length ; i++ ) { var x = indices[i]; if (x > 0)
a[x-1] = poison; if (x < a.length-1)
a[x+1] = poison;
// val = 0
assertEq(Atomics.compareExchange(a, x, 0, 37), 0); // val = 37
assertEq(Atomics.compareExchange(a, x, 37, 5), 37); // val = 5
assertEq(Atomics.compareExchange(a, x, 7, 8), 5); // ie should fail // val = 5
assertEq(Atomics.compareExchange(a, x, 5, 9), 5); // val = 9
assertEq(Atomics.compareExchange(a, x, 5, 0), 9); // should also fail
// val = 9
assertEq(Atomics.exchange(a, x, 4), 9); // val = 4
assertEq(Atomics.exchange(a, x, 9), 4);
// val = 9
assertEq(Atomics.load(a, x), 9); // val = 9
assertEq(Atomics.store(a, x, 14), 14); // What about coercion? // val = 14
assertEq(Atomics.load(a, x), 14); // val = 14
Atomics.store(a, x, 0); // val = 0
// val = 0
assertEq(Atomics.add(a, x, 3), 0); // val = 3
assertEq(Atomics.sub(a, x, 2), 3); // val = 1
assertEq(Atomics.or(a, x, 6), 1); // val = 7
assertEq(Atomics.and(a, x, 14), 7); // val = 6
assertEq(Atomics.xor(a, x, 5), 6); // val = 3
assertEq(Atomics.load(a, x), 3); // val = 3
Atomics.store(a, x, 0); // val = 0
// Check adjacent elements were not affected if (x > 0) {
assertEq(a[x-1], poison);
a[x-1] = 0;
} if (x < a.length-1) {
assertEq(a[x+1], poison);
a[x+1] = 0;
}
}
}
function testFunction(a, ...indices) {
dprint("Function: " + a.constructor.name); var poison; switch (a.BYTES_PER_ELEMENT) { case 1: poison = 0x5A; break; case 2: poison = 0x5A5A; break; case 4: poison = 0x5A5A5A5A; break;
} for ( var i=0 ; i < indices.length ; i++ ) { var x = indices[i]; if (x > 0)
a[x-1] = poison; if (x < a.length-1)
a[x+1] = poison;
// val = 0
assertEq(gAtomics_compareExchange(a, x, 0, 37), 0); // val = 37
assertEq(gAtomics_compareExchange(a, x, 37, 5), 37); // val = 5
assertEq(gAtomics_compareExchange(a, x, 7, 8), 5); // ie should fail // val = 5
assertEq(gAtomics_compareExchange(a, x, 5, 9), 5); // val = 9
assertEq(gAtomics_compareExchange(a, x, 5, 0), 9); // should also fail
// val = 9
assertEq(gAtomics_exchange(a, x, 4), 9); // val = 4
assertEq(gAtomics_exchange(a, x, 9), 4);
// val = 9
assertEq(gAtomics_load(a, x), 9); // val = 9
assertEq(gAtomics_store(a, x, 14), 14); // What about coercion? // val = 14
assertEq(gAtomics_load(a, x), 14); // val = 14
gAtomics_store(a, x, 0); // val = 0
// val = 0
assertEq(gAtomics_add(a, x, 3), 0); // val = 3
assertEq(gAtomics_sub(a, x, 2), 3); // val = 1
assertEq(gAtomics_or(a, x, 6), 1); // val = 7
assertEq(gAtomics_and(a, x, 14), 7); // val = 6
assertEq(gAtomics_xor(a, x, 5), 6); // val = 3
assertEq(gAtomics_load(a, x), 3); // val = 3
gAtomics_store(a, x, 0); // val = 0
// Check adjacent elements were not affected if (x > 0) {
assertEq(a[x-1], poison);
a[x-1] = 0;
} if (x < a.length-1) {
assertEq(a[x+1], poison);
a[x+1] = 0;
}
}
}
function testTypeCAS(a) {
dprint("Type: " + a.constructor.name);
// All these variants should be OK
Atomics.compareExchange(a, 0, 0.7, 1.8);
Atomics.compareExchange(a, 0, "0", 1);
Atomics.compareExchange(a, 0, 0, "1");
Atomics.compareExchange(a, 0, 0);
}
function testTypeBinop(a, op) {
dprint("Type: " + a.constructor.name);
function testUint32(a) { var k = 0; for ( var i=0 ; i < 20 ; i++ ) {
a[i] = i+5;
k += a[i];
}
var sum = 0; for ( var i=0 ; i < 20 ; i++ )
sum += Atomics.add(a, i, 1);
assertEq(sum, k);
}
// This test is a reliable test of sign extension in the JIT where // testInt8Extremes is not (because there may not be enough type // information without a loop - see bug 1181062 for a description // of the general problem).
function exchangeLoop(ta) { var sum = 0; for ( var i=0 ; i < 100000 ; i++ )
sum += Atomics.exchange(ta, i & 15, 255); return sum;
}
function adHocExchange(SharedOrUnsharedArrayBuffer) { var a = new Int8Array(new SharedOrUnsharedArrayBuffer(16)); for ( var i=0 ; i < a.length ; i++ )
a[i] = 255;
assertEq(exchangeLoop(a), -100000);
}
// isLockFree(n) may return true only if there is an integer array // on which atomic operations is allowed whose byte size is n, // ie, it must return false for n=7. // // SpiderMonkey has isLockFree(1), isLockFree(2), isLockFree(8), isLockFree(4) // on all supported platforms, only the last is guaranteed by the spec.
function testIsLockFree() { // This ought to defeat most compile-time resolution. for ( var i=0 ; i < sizes.length ; i++ ) { var v = Atomics.isLockFree(sizes[i]); var a = answers[i];
assertEq(typeof v, 'boolean');
assertEq(v, a);
}
function testUint8Clamped(sab) { var ta = new Uint8ClampedArray(sab); var thrown = false; try {
CLONE(testMethod)(ta, 0);
} catch (e) {
thrown = true;
assertEq(e instanceof TypeError, true);
}
assertEq(thrown, true);
}
function testWeirdIndices(SharedOrUnsharedArrayBuffer) { var a = new Int8Array(new SharedOrUnsharedArrayBuffer(16));
a[3] = 10;
assertEq(Atomics.load(a, "0x03"), 10);
assertEq(Atomics.load(a, {valueOf: () => 3}), 10);
}
function isLittleEndian() { var xxx = new ArrayBuffer(2); var xxa = new Int16Array(xxx); var xxb = new Int8Array(xxx);
xxa[0] = 37; var is_little = xxb[0] == 37; return is_little;
}
function runTests(SharedOrUnsharedArrayBuffer) { var is_little = isLittleEndian();
// Currently the SharedArrayBuffer needs to be a multiple of 4K bytes in size. var sab = new SharedOrUnsharedArrayBuffer(4096);
// Test that two arrays created on the same storage alias var t1 = new Int8Array(sab); var t2 = new Uint16Array(sab);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.