optimization-tests.js (3262B)
1 // Some optimization tests for the Atomics primitives. 2 // 3 // These do not test atomicity, just code generation on a single 4 // thread. 5 // 6 // It's useful to look at the code generated for this test with -D to 7 // the JS shell. 8 // 9 // Bug 1138348 - unconstrained use of byte registers on x64 10 // Bug 1077014 - code generation for Atomic operations for effect, 11 // all platforms 12 // Bug 1141121 - immediate operand in atomic operations on x86/x64 13 14 function test(SharedOrUnsharedArrayBuffer) { 15 var sum = 0; 16 17 function f(ia, k) { 18 // For effect, variable value. The generated code on x86/x64 19 // should be one LOCK ADDB. (On ARM, there should be no 20 // sign-extend of the current value in the cell, otherwise this is 21 // still a LDREX/STREX loop.) 22 Atomics.add(ia, 0, k); 23 24 // Ditto constant value. Here the LOCK ADDB should have an 25 // immediate operand. 26 Atomics.add(ia, 0, 1); 27 } 28 29 function f2(ia, k) { 30 // For effect, variable value and constant value. The generated 31 // code on x86/x64 should be one LOCK SUBB. 32 Atomics.sub(ia, 2, k); 33 34 // Ditto constant value. Here the LOCK SUBB should have an 35 // immediate operand. 36 Atomics.sub(ia, 2, 1); 37 } 38 39 function f4(ia, k) { 40 // For effect, variable value. The generated code on x86/x64 41 // should be one LOCK ORB. (On ARM, there should be no 42 // sign-extend of the current value in the cell, otherwise this is 43 // still a LDREX/STREX loop.) 44 Atomics.or(ia, 6, k); 45 46 // Ditto constant value. Here the LOCK ORB should have an 47 // immediate operand. 48 Atomics.or(ia, 6, 1); 49 } 50 51 function g(ia, k) { 52 // For its value, variable value. The generated code on x86/x64 53 // should be one LOCK XADDB. 54 sum += Atomics.add(ia, 1, k); 55 56 // Ditto constant value. XADD does not admit an immediate 57 // operand, so in the second case there should be a preliminary 58 // MOV of the immediate to the output register. 59 sum += Atomics.add(ia, 1, 1); 60 } 61 62 function g2(ia, k) { 63 // For its value, variable value. The generated code on x86/x64 64 // should be one LOCK XADDB, preceded by a NEG into the output 65 // register instead of a MOV. 66 sum += Atomics.sub(ia, 3, k); 67 68 // Ditto constant value. XADD does not admit an immediate 69 // operand, so in the second case there should be a preliminary 70 // MOV of the negated immediate to the output register. 71 sum += Atomics.sub(ia, 3, 1); 72 } 73 74 function g4(ia, k) { 75 // For its value, variable value. The generated code on x86/x64 76 // should be a loop around ORB ; CMPXCHGB 77 sum += Atomics.or(ia, 7, k); 78 79 // Ditto constant value. Here the ORB in the loop should have 80 // an immediate operand. 81 sum += Atomics.or(ia, 7, 1); 82 } 83 84 var i8a = new Int8Array(new SharedOrUnsharedArrayBuffer(65536)); 85 for ( var i=0 ; i < 10000 ; i++ ) { 86 f(i8a, i % 10); 87 g(i8a, i % 10); 88 f2(i8a, i % 10); 89 g2(i8a, i % 10); 90 f4(i8a, i % 10); 91 g4(i8a, i % 10); 92 } 93 94 assertEq(i8a[0], ((10000 + 10000*4.5) << 24) >> 24); 95 assertEq(i8a[1], ((10000 + 10000*4.5) << 24) >> 24); 96 assertEq(i8a[2], ((-10000 + -10000*4.5) << 24) >> 24); 97 assertEq(i8a[3], ((-10000 + -10000*4.5) << 24) >> 24); 98 assertEq(i8a[6], 15); 99 assertEq(i8a[7], 15); 100 } 101 102 test(SharedArrayBuffer); 103 test(ArrayBuffer);