Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: test/mjsunit/harmony/atomics.js

Issue 1162503002: Implement Atomics API (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add more symbols to anonymous namespace Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/mjsunit/asm/atomics-xor.js ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Flags: --harmony-atomics --harmony-sharedarraybuffer
6 //
7
8 var IntegerTypedArrayConstructors = [
9 {constr: Int8Array, min: -128, max: 127},
10 {constr: Int16Array, min: -32768, max: 32767},
11 {constr: Int32Array, min: -0x80000000, max: 0x7fffffff},
12 {constr: Uint8Array, min: 0, max: 255},
13 // TODO(binji): support?
14 // {constr: Uint8ClampedArray, min: 0, max: 255},
15 {constr: Uint16Array, min: 0, max: 65535},
16 {constr: Uint32Array, min: 0, max: 0xffffffff},
17 ];
18
19 var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([
20 {constr: Float32Array},
21 {constr: Float64Array},
22 ]);
23
24 (function TestBadArray() {
25 var ab = new ArrayBuffer(16);
26 var u32a = new Uint32Array(16);
27 var sab = new SharedArrayBuffer(128);
28 var sf32a = new Float32Array(sab);
29 var sf64a = new Float64Array(sab);
30
31 // Atomic ops required shared typed arrays
32 [undefined, 1, 'hi', 3.4, ab, u32a, sab].forEach(function(o) {
33 assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
34 TypeError);
35 assertThrows(function() { Atomics.load(o, 0); }, TypeError);
36 assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError);
37 assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
38 assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
39 assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
40 assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
41 assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
42 assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
43 });
44
45 // Arithmetic atomic ops require integer shared arrays
46 [sab, sf32a, sf64a].forEach(function(o) {
47 assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
48 assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
49 assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
50 assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
51 assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
52 assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
53 });
54 })();
55
56 function testAtomicOp(op, ia, index, expectedIndex, name) {
57 for (var i = 0; i < ia.length; ++i)
58 ia[i] = 22;
59
60 ia[expectedIndex] = 0;
61 assertEquals(0, op(ia, index, 0, 0), name);
62 assertEquals(0, ia[expectedIndex], name);
63
64 for (var i = 0; i < ia.length; ++i) {
65 if (i == expectedIndex) continue;
66 assertEquals(22, ia[i], name);
67 }
68 }
69
70 (function TestBadIndex() {
71 var sab = new SharedArrayBuffer(8);
72 var si32a = new Int32Array(sab);
73
74 // Non-integer indexes are converted to an integer first, so they should all
75 // operate on index 0.
76 [undefined, null, false, 'hi', {}].forEach(function(i) {
77 var name = String(i);
78
79 testAtomicOp(Atomics.compareExchange, si32a, i, 0, name);
80 testAtomicOp(Atomics.load, si32a, i, 0, name);
81 testAtomicOp(Atomics.store, si32a, i, 0, name);
82 testAtomicOp(Atomics.add, si32a, i, 0, name);
83 testAtomicOp(Atomics.sub, si32a, i, 0, name);
84 testAtomicOp(Atomics.and, si32a, i, 0, name);
85 testAtomicOp(Atomics.or, si32a, i, 0, name);
86 testAtomicOp(Atomics.xor, si32a, i, 0, name);
87 testAtomicOp(Atomics.exchange, si32a, i, 0, name);
88 });
89
90 // Out-of-bounds indexes should return undefined.
91 // TODO(binji): Should these throw RangeError instead?
92 [-1, 2, 100].forEach(function(i) {
93 var name = String(i);
94 assertEquals(undefined, Atomics.compareExchange(si32a, i, 0, 0), name);
95 assertEquals(undefined, Atomics.load(si32a, i), name);
96 assertEquals(undefined, Atomics.store(si32a, i, 0), name);
97 assertEquals(undefined, Atomics.add(si32a, i, 0), name);
98 assertEquals(undefined, Atomics.sub(si32a, i, 0), name);
99 assertEquals(undefined, Atomics.and(si32a, i, 0), name);
100 assertEquals(undefined, Atomics.or(si32a, i, 0), name);
101 assertEquals(undefined, Atomics.xor(si32a, i, 0), name);
102 assertEquals(undefined, Atomics.exchange(si32a, i, 0), name);
103 });
104 })();
105
106 (function TestGoodIndex() {
107 var sab = new SharedArrayBuffer(64);
108 var si32a = new Int32Array(sab);
109
110 var valueOf = {valueOf: function(){ return 3;}};
111 var toString = {toString: function(){ return '3';}};
112
113 [3, 3.5, '3', '3.5', valueOf, toString].forEach(function(i) {
114 var name = String(i);
115
116 testAtomicOp(Atomics.compareExchange, si32a, i, 3, name);
117 testAtomicOp(Atomics.load, si32a, i, 3, name);
118 testAtomicOp(Atomics.store, si32a, i, 3, name);
119 testAtomicOp(Atomics.add, si32a, i, 3, name);
120 testAtomicOp(Atomics.sub, si32a, i, 3, name);
121 testAtomicOp(Atomics.and, si32a, i, 3, name);
122 testAtomicOp(Atomics.or, si32a, i, 3, name);
123 testAtomicOp(Atomics.xor, si32a, i, 3, name);
124 testAtomicOp(Atomics.exchange, si32a, i, 3, name);
125 });
126 })();
127
128 (function TestCompareExchange() {
129 TypedArrayConstructors.forEach(function(t) {
130 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
131 var sta = new t.constr(sab);
132 var name = Object.prototype.toString.call(sta);
133 for (var i = 0; i < 10; ++i) {
134 // sta[i] == 0, CAS will store
135 assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name);
136 assertEquals(50, sta[i], name);
137
138 // sta[i] == 50, CAS will not store
139 assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name);
140 assertEquals(50, sta[i], name);
141 }
142 });
143
144 IntegerTypedArrayConstructors.forEach(function(t) {
145 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
146 var sta = new t.constr(sab);
147 var name = Object.prototype.toString.call(sta);
148 var range = t.max - t.min + 1;
149 var add;
150 var oldVal, oldValWrapped;
151 var newVal, newValWrapped;
152
153 for (add = -range; add <= range; add += range) {
154 sta[0] = oldVal = 0;
155 newVal = t.max + add + 1;
156 newValWrapped = t.min;
157 assertEquals(oldVal,
158 Atomics.compareExchange(sta, 0, oldVal, newVal), name);
159 assertEquals(newValWrapped, sta[0], name);
160
161 oldVal = newVal;
162 oldValWrapped = newValWrapped;
163 newVal = t.min + add - 1;
164 newValWrapped = t.max;
165 assertEquals(oldValWrapped,
166 Atomics.compareExchange(sta, 0, oldVal, newVal), name);
167 assertEquals(newValWrapped, sta[0], name);
168 }
169 });
170
171 // * Exact float values should be OK
172 // * Infinity, -Infinity should be OK (has exact representation)
173 // * NaN is not OK, it has many representations, cannot ensure successful CAS
174 // because it does a bitwise compare
175 [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) {
176 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT);
177 var sf32a = new Float32Array(sab);
178 sf32a[0] = 0;
179 assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v));
180 assertEquals(v, sf32a[0]);
181 assertEquals(v, Atomics.compareExchange(sf32a, 0, v, 0));
182 assertEquals(0, sf32a[0]);
183
184 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT);
185 var sf64a = new Float64Array(sab2);
186 sf64a[0] = 0;
187 assertEquals(0, Atomics.compareExchange(sf64a, 0, 0, v));
188 assertEquals(v, sf64a[0]);
189 assertEquals(v, Atomics.compareExchange(sf64a, 0, v, 0));
190 assertEquals(0, sf64a[0]);
191 });
192 })();
193
194 (function TestLoad() {
195 TypedArrayConstructors.forEach(function(t) {
196 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
197 var sta = new t.constr(sab);
198 var name = Object.prototype.toString.call(sta);
199 for (var i = 0; i < 10; ++i) {
200 sta[i] = 0;
201 assertEquals(0, Atomics.load(sta, i), name);
202 sta[i] = 50;
203 assertEquals(50, Atomics.load(sta, i), name);
204 }
205 });
206 })();
207
208 (function TestStore() {
209 TypedArrayConstructors.forEach(function(t) {
210 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
211 var sta = new t.constr(sab);
212 var name = Object.prototype.toString.call(sta);
213 for (var i = 0; i < 10; ++i) {
214 assertEquals(50, Atomics.store(sta, i, 50), name);
215 assertEquals(50, sta[i], name);
216
217 assertEquals(100, Atomics.store(sta, i, 100), name);
218 assertEquals(100, sta[i], name);
219 }
220 });
221
222 IntegerTypedArrayConstructors.forEach(function(t) {
223 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
224 var sta = new t.constr(sab);
225 var name = Object.prototype.toString.call(sta);
226 var range = t.max - t.min + 1;
227 var add;
228 var val, valWrapped;
229
230 for (add = -range; add <= range; add += range) {
231 sta[0] = 0;
232 val = t.max + add + 1;
233 valWrapped = t.min;
234 assertEquals(val, Atomics.store(sta, 0, val), name);
235 assertEquals(valWrapped, sta[0], name);
236
237 val = t.min + add - 1;
238 valWrapped = t.max;
239 assertEquals(val, Atomics.store(sta, 0, val), name);
240 assertEquals(valWrapped, sta[0], name);
241 }
242 });
243
244 [1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) {
245 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT);
246 var sf32a = new Float32Array(sab);
247 sf32a[0] = 0;
248 assertEquals(v, Atomics.store(sf32a, 0, v));
249 assertEquals(v, sf32a[0]);
250
251 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT);
252 var sf64a = new Float64Array(sab2);
253 sf64a[0] = 0;
254 assertEquals(v, Atomics.store(sf64a, 0, v));
255 assertEquals(v, sf64a[0]);
256 });
257 })();
258
259 (function TestAdd() {
260 IntegerTypedArrayConstructors.forEach(function(t) {
261 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
262 var sta = new t.constr(sab);
263 var name = Object.prototype.toString.call(sta);
264 for (var i = 0; i < 10; ++i) {
265 assertEquals(0, Atomics.add(sta, i, 50), name);
266 assertEquals(50, sta[i], name);
267
268 assertEquals(50, Atomics.add(sta, i, 70), name);
269 assertEquals(120, sta[i], name);
270 }
271 });
272
273 IntegerTypedArrayConstructors.forEach(function(t) {
274 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
275 var sta = new t.constr(sab);
276 var name = Object.prototype.toString.call(sta);
277 var range = t.max - t.min + 1;
278 var add;
279
280 for (add = -range; add <= range; add += range) {
281 sta[0] = t.max;
282 valWrapped = t.min;
283 assertEquals(t.max, Atomics.add(sta, 0, add + 1), name);
284 assertEquals(t.min, sta[0], name);
285
286 assertEquals(t.min, Atomics.add(sta, 0, add - 1), name);
287 assertEquals(t.max, sta[0], name);
288 }
289 });
290 })();
291
292 (function TestSub() {
293 IntegerTypedArrayConstructors.forEach(function(t) {
294 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
295 var sta = new t.constr(sab);
296 var name = Object.prototype.toString.call(sta);
297 for (var i = 0; i < 10; ++i) {
298 sta[i] = 120;
299 assertEquals(120, Atomics.sub(sta, i, 50), name);
300 assertEquals(70, sta[i], name);
301
302 assertEquals(70, Atomics.sub(sta, i, 70), name);
303 assertEquals(0, sta[i], name);
304 }
305 });
306
307 IntegerTypedArrayConstructors.forEach(function(t) {
308 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
309 var sta = new t.constr(sab);
310 var name = Object.prototype.toString.call(sta);
311 var range = t.max - t.min + 1;
312 var add;
313
314 for (add = -range; add <= range; add += range) {
315 sta[0] = t.max;
316 valWrapped = t.min;
317 assertEquals(t.max, Atomics.sub(sta, 0, add - 1), name);
318 assertEquals(t.min, sta[0], name);
319
320 assertEquals(t.min, Atomics.sub(sta, 0, add + 1), name);
321 assertEquals(t.max, sta[0], name);
322 }
323 });
324 })();
325
326 (function TestAnd() {
327 IntegerTypedArrayConstructors.forEach(function(t) {
328 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
329 var sta = new t.constr(sab);
330 var name = Object.prototype.toString.call(sta);
331 for (var i = 0; i < 10; ++i) {
332 sta[i] = 0x3f;
333 assertEquals(0x3f, Atomics.and(sta, i, 0x30), name);
334 assertEquals(0x30, sta[i], name);
335
336 assertEquals(0x30, Atomics.and(sta, i, 0x20), name);
337 assertEquals(0x20, sta[i], name);
338 }
339 });
340
341 IntegerTypedArrayConstructors.forEach(function(t) {
342 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
343 var sta = new t.constr(sab);
344 var name = Object.prototype.toString.call(sta);
345 var range = t.max - t.min + 1;
346 var add;
347
348 // There's no way to wrap results with logical operators, just test that
349 // using an out-of-range value is properly masked.
350 for (add = -range; add <= range; add += range) {
351 sta[0] = 0xf;
352 assertEquals(0xf, Atomics.and(sta, 0, 0x3 + add), name);
353 assertEquals(0x3, sta[0], name);
354 }
355 });
356 })();
357
358 (function TestOr() {
359 IntegerTypedArrayConstructors.forEach(function(t) {
360 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
361 var sta = new t.constr(sab);
362 var name = Object.prototype.toString.call(sta);
363 for (var i = 0; i < 10; ++i) {
364 sta[i] = 0x30;
365 assertEquals(0x30, Atomics.or(sta, i, 0x1c), name);
366 assertEquals(0x3c, sta[i], name);
367
368 assertEquals(0x3c, Atomics.or(sta, i, 0x09), name);
369 assertEquals(0x3d, sta[i], name);
370 }
371 });
372
373 IntegerTypedArrayConstructors.forEach(function(t) {
374 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
375 var sta = new t.constr(sab);
376 var name = Object.prototype.toString.call(sta);
377 var range = t.max - t.min + 1;
378 var add;
379
380 // There's no way to wrap results with logical operators, just test that
381 // using an out-of-range value is properly masked.
382 for (add = -range; add <= range; add += range) {
383 sta[0] = 0x12;
384 assertEquals(0x12, Atomics.or(sta, 0, 0x22 + add), name);
385 assertEquals(0x32, sta[0], name);
386 }
387 });
388 })();
389
390 (function TestXor() {
391 IntegerTypedArrayConstructors.forEach(function(t) {
392 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
393 var sta = new t.constr(sab);
394 var name = Object.prototype.toString.call(sta);
395 for (var i = 0; i < 10; ++i) {
396 sta[i] = 0x30;
397 assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name);
398 assertEquals(0x2c, sta[i], name);
399
400 assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name);
401 assertEquals(0x25, sta[i], name);
402 }
403 });
404
405 IntegerTypedArrayConstructors.forEach(function(t) {
406 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
407 var sta = new t.constr(sab);
408 var name = Object.prototype.toString.call(sta);
409 var range = t.max - t.min + 1;
410 var add;
411
412 // There's no way to wrap results with logical operators, just test that
413 // using an out-of-range value is properly masked.
414 for (add = -range; add <= range; add += range) {
415 sta[0] = 0x12;
416 assertEquals(0x12, Atomics.xor(sta, 0, 0x22 + add), name);
417 assertEquals(0x30, sta[0], name);
418 }
419 });
420 })();
421
422 (function TestExchange() {
423 IntegerTypedArrayConstructors.forEach(function(t) {
424 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
425 var sta = new t.constr(sab);
426 var name = Object.prototype.toString.call(sta);
427 for (var i = 0; i < 10; ++i) {
428 sta[i] = 0x30;
429 assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name);
430 assertEquals(0x1c, sta[i], name);
431
432 assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name);
433 assertEquals(0x09, sta[i], name);
434 }
435 });
436
437 IntegerTypedArrayConstructors.forEach(function(t) {
438 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
439 var sta = new t.constr(sab);
440 var name = Object.prototype.toString.call(sta);
441 var range = t.max - t.min + 1;
442 var add;
443
444 // There's no way to wrap results with logical operators, just test that
445 // using an out-of-range value is properly masked.
446 for (add = -range; add <= range; add += range) {
447 sta[0] = 0x12;
448 assertEquals(0x12, Atomics.exchange(sta, 0, 0x22 + add), name);
449 assertEquals(0x22, sta[0], name);
450 }
451 });
452 })();
453
454 (function TestIsLockFree() {
455 // For all platforms we support, 1, 2 and 4 bytes should be lock-free.
456 assertEquals(true, Atomics.isLockFree(1));
457 assertEquals(true, Atomics.isLockFree(2));
458 assertEquals(true, Atomics.isLockFree(4));
459
460 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return
461 // false.
462 var validSizes = {};
463 TypedArrayConstructors.forEach(function(t) {
464 validSizes[t.constr.BYTES_PER_ELEMENT] = true;
465 });
466
467 for (var i = 0; i < 1000; ++i) {
468 if (!validSizes[i]) {
469 assertEquals(false, Atomics.isLockFree(i));
470 }
471 }
472 })();
OLDNEW
« no previous file with comments | « test/mjsunit/asm/atomics-xor.js ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698