summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/atomics/optimization-tests.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/atomics/optimization-tests.js')
-rw-r--r--js/src/jit-test/tests/atomics/optimization-tests.js103
1 files changed, 103 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/atomics/optimization-tests.js b/js/src/jit-test/tests/atomics/optimization-tests.js
new file mode 100644
index 0000000000..65b2055dc6
--- /dev/null
+++ b/js/src/jit-test/tests/atomics/optimization-tests.js
@@ -0,0 +1,103 @@
+// Some optimization tests for the Atomics primitives.
+//
+// These do not test atomicity, just code generation on a single
+// thread.
+//
+// It's useful to look at the code generated for this test with -D to
+// the JS shell.
+//
+// Bug 1138348 - unconstrained use of byte registers on x64
+// Bug 1077014 - code generation for Atomic operations for effect,
+// all platforms
+// Bug 1141121 - immediate operand in atomic operations on x86/x64
+
+function test(SharedOrUnsharedArrayBuffer) {
+var sum = 0;
+
+function f(ia, k) {
+ // For effect, variable value. The generated code on x86/x64
+ // should be one LOCK ADDB. (On ARM, there should be no
+ // sign-extend of the current value in the cell, otherwise this is
+ // still a LDREX/STREX loop.)
+ Atomics.add(ia, 0, k);
+
+ // Ditto constant value. Here the LOCK ADDB should have an
+ // immediate operand.
+ Atomics.add(ia, 0, 1);
+}
+
+function f2(ia, k) {
+ // For effect, variable value and constant value. The generated
+ // code on x86/x64 should be one LOCK SUBB.
+ Atomics.sub(ia, 2, k);
+
+ // Ditto constant value. Here the LOCK SUBB should have an
+ // immediate operand.
+ Atomics.sub(ia, 2, 1);
+}
+
+function f4(ia, k) {
+ // For effect, variable value. The generated code on x86/x64
+ // should be one LOCK ORB. (On ARM, there should be no
+ // sign-extend of the current value in the cell, otherwise this is
+ // still a LDREX/STREX loop.)
+ Atomics.or(ia, 6, k);
+
+ // Ditto constant value. Here the LOCK ORB should have an
+ // immediate operand.
+ Atomics.or(ia, 6, 1);
+}
+
+function g(ia, k) {
+ // For its value, variable value. The generated code on x86/x64
+ // should be one LOCK XADDB.
+ sum += Atomics.add(ia, 1, k);
+
+ // Ditto constant value. XADD does not admit an immediate
+ // operand, so in the second case there should be a preliminary
+ // MOV of the immediate to the output register.
+ sum += Atomics.add(ia, 1, 1);
+}
+
+function g2(ia, k) {
+ // For its value, variable value. The generated code on x86/x64
+ // should be one LOCK XADDB, preceded by a NEG into the output
+ // register instead of a MOV.
+ sum += Atomics.sub(ia, 3, k);
+
+ // Ditto constant value. XADD does not admit an immediate
+ // operand, so in the second case there should be a preliminary
+ // MOV of the negated immediate to the output register.
+ sum += Atomics.sub(ia, 3, 1);
+}
+
+function g4(ia, k) {
+ // For its value, variable value. The generated code on x86/x64
+ // should be a loop around ORB ; CMPXCHGB
+ sum += Atomics.or(ia, 7, k);
+
+ // Ditto constant value. Here the ORB in the loop should have
+ // an immediate operand.
+ sum += Atomics.or(ia, 7, 1);
+}
+
+var i8a = new Int8Array(new SharedOrUnsharedArrayBuffer(65536));
+for ( var i=0 ; i < 10000 ; i++ ) {
+ f(i8a, i % 10);
+ g(i8a, i % 10);
+ f2(i8a, i % 10);
+ g2(i8a, i % 10);
+ f4(i8a, i % 10);
+ g4(i8a, i % 10);
+}
+
+assertEq(i8a[0], ((10000 + 10000*4.5) << 24) >> 24);
+assertEq(i8a[1], ((10000 + 10000*4.5) << 24) >> 24);
+assertEq(i8a[2], ((-10000 + -10000*4.5) << 24) >> 24);
+assertEq(i8a[3], ((-10000 + -10000*4.5) << 24) >> 24);
+assertEq(i8a[6], 15);
+assertEq(i8a[7], 15);
+}
+
+test(SharedArrayBuffer);
+test(ArrayBuffer); \ No newline at end of file