| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --harmony-atomics --harmony-sharedarraybuffer | 5 // Flags: --harmony-atomics --harmony-sharedarraybuffer |
| 6 // | 6 // |
| 7 | 7 |
| 8 function toRangeWrapped(value) { |
| 9 var range = this.max - this.min + 1; |
| 10 while (value < this.min) { |
| 11 value += range; |
| 12 } |
| 13 while (value > this.max) { |
| 14 value -= range; |
| 15 } |
| 16 return value; |
| 17 } |
| 18 |
| 19 function toRangeClamped(value) { |
| 20 if (value < this.min) return this.min; |
| 21 if (value > this.max) return this.max; |
| 22 return value; |
| 23 } |
| 24 |
| 25 function makeConstructorObject(constr, min, max, toRange) { |
| 26 var o = {constr: constr, min: min, max: max}; |
| 27 o.toRange = toRange.bind(o); |
| 28 return o; |
| 29 } |
| 30 |
| 8 var IntegerTypedArrayConstructors = [ | 31 var IntegerTypedArrayConstructors = [ |
| 9 {constr: Int8Array, min: -128, max: 127}, | 32 makeConstructorObject(Int8Array, -128, 127, toRangeWrapped), |
| 10 {constr: Int16Array, min: -32768, max: 32767}, | 33 makeConstructorObject(Int16Array, -32768, 32767, toRangeWrapped), |
| 11 {constr: Int32Array, min: -0x80000000, max: 0x7fffffff}, | 34 makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff, toRangeWrapped), |
| 12 {constr: Uint8Array, min: 0, max: 255}, | 35 makeConstructorObject(Uint8Array, 0, 255, toRangeWrapped), |
| 13 // TODO(binji): support? | 36 makeConstructorObject(Uint8ClampedArray, 0, 255, toRangeClamped), |
| 14 // {constr: Uint8ClampedArray, min: 0, max: 255}, | 37 makeConstructorObject(Uint16Array, 0, 65535, toRangeWrapped), |
| 15 {constr: Uint16Array, min: 0, max: 65535}, | 38 makeConstructorObject(Uint32Array, 0, 0xffffffff, toRangeWrapped), |
| 16 {constr: Uint32Array, min: 0, max: 0xffffffff}, | |
| 17 ]; | 39 ]; |
| 18 | 40 |
| 19 var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([ | 41 var TypedArrayConstructors = IntegerTypedArrayConstructors.concat([ |
| 20 {constr: Float32Array}, | 42 {constr: Float32Array}, |
| 21 {constr: Float64Array}, | 43 {constr: Float64Array}, |
| 22 ]); | 44 ]); |
| 23 | 45 |
| 24 (function TestBadArray() { | 46 (function TestBadArray() { |
| 25 var ab = new ArrayBuffer(16); | 47 var ab = new ArrayBuffer(16); |
| 26 var u32a = new Uint32Array(16); | 48 var u32a = new Uint32Array(16); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 // sta[i] == 0, CAS will store | 156 // sta[i] == 0, CAS will store |
| 135 assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name); | 157 assertEquals(0, Atomics.compareExchange(sta, i, 0, 50), name); |
| 136 assertEquals(50, sta[i], name); | 158 assertEquals(50, sta[i], name); |
| 137 | 159 |
| 138 // sta[i] == 50, CAS will not store | 160 // sta[i] == 50, CAS will not store |
| 139 assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name); | 161 assertEquals(50, Atomics.compareExchange(sta, i, 0, 100), name); |
| 140 assertEquals(50, sta[i], name); | 162 assertEquals(50, sta[i], name); |
| 141 } | 163 } |
| 142 }); | 164 }); |
| 143 | 165 |
| 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 | 166 // * Exact float values should be OK |
| 172 // * Infinity, -Infinity should be OK (has exact representation) | 167 // * Infinity, -Infinity should be OK (has exact representation) |
| 173 // * NaN is not OK, it has many representations, cannot ensure successful CAS | 168 // * NaN is not OK, it has many representations, cannot ensure successful CAS |
| 174 // because it does a bitwise compare | 169 // because it does a bitwise compare |
| 175 [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) { | 170 [1.5, 4.25, -1e8, -Infinity, Infinity].forEach(function(v) { |
| 176 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); | 171 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); |
| 177 var sf32a = new Float32Array(sab); | 172 var sf32a = new Float32Array(sab); |
| 178 sf32a[0] = 0; | 173 sf32a[0] = 0; |
| 179 assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v)); | 174 assertEquals(0, Atomics.compareExchange(sf32a, 0, 0, v)); |
| 180 assertEquals(v, sf32a[0]); | 175 assertEquals(v, sf32a[0]); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 var name = Object.prototype.toString.call(sta); | 207 var name = Object.prototype.toString.call(sta); |
| 213 for (var i = 0; i < 10; ++i) { | 208 for (var i = 0; i < 10; ++i) { |
| 214 assertEquals(50, Atomics.store(sta, i, 50), name); | 209 assertEquals(50, Atomics.store(sta, i, 50), name); |
| 215 assertEquals(50, sta[i], name); | 210 assertEquals(50, sta[i], name); |
| 216 | 211 |
| 217 assertEquals(100, Atomics.store(sta, i, 100), name); | 212 assertEquals(100, Atomics.store(sta, i, 100), name); |
| 218 assertEquals(100, sta[i], name); | 213 assertEquals(100, sta[i], name); |
| 219 } | 214 } |
| 220 }); | 215 }); |
| 221 | 216 |
| 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) { | 217 [1.5, 4.25, -1e8, -Infinity, Infinity, NaN].forEach(function(v) { |
| 245 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); | 218 var sab = new SharedArrayBuffer(10 * Float32Array.BYTES_PER_ELEMENT); |
| 246 var sf32a = new Float32Array(sab); | 219 var sf32a = new Float32Array(sab); |
| 247 sf32a[0] = 0; | 220 sf32a[0] = 0; |
| 248 assertEquals(v, Atomics.store(sf32a, 0, v)); | 221 assertEquals(v, Atomics.store(sf32a, 0, v)); |
| 249 assertEquals(v, sf32a[0]); | 222 assertEquals(v, sf32a[0]); |
| 250 | 223 |
| 251 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT); | 224 var sab2 = new SharedArrayBuffer(10 * Float64Array.BYTES_PER_ELEMENT); |
| 252 var sf64a = new Float64Array(sab2); | 225 var sf64a = new Float64Array(sab2); |
| 253 sf64a[0] = 0; | 226 sf64a[0] = 0; |
| 254 assertEquals(v, Atomics.store(sf64a, 0, v)); | 227 assertEquals(v, Atomics.store(sf64a, 0, v)); |
| 255 assertEquals(v, sf64a[0]); | 228 assertEquals(v, sf64a[0]); |
| 256 }); | 229 }); |
| 257 })(); | 230 })(); |
| 258 | 231 |
| 259 (function TestAdd() { | 232 (function TestAdd() { |
| 260 IntegerTypedArrayConstructors.forEach(function(t) { | 233 IntegerTypedArrayConstructors.forEach(function(t) { |
| 261 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 234 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 262 var sta = new t.constr(sab); | 235 var sta = new t.constr(sab); |
| 263 var name = Object.prototype.toString.call(sta); | 236 var name = Object.prototype.toString.call(sta); |
| 264 for (var i = 0; i < 10; ++i) { | 237 for (var i = 0; i < 10; ++i) { |
| 265 assertEquals(0, Atomics.add(sta, i, 50), name); | 238 assertEquals(0, Atomics.add(sta, i, 50), name); |
| 266 assertEquals(50, sta[i], name); | 239 assertEquals(50, sta[i], name); |
| 267 | 240 |
| 268 assertEquals(50, Atomics.add(sta, i, 70), name); | 241 assertEquals(50, Atomics.add(sta, i, 70), name); |
| 269 assertEquals(120, sta[i], name); | 242 assertEquals(120, sta[i], name); |
| 270 } | 243 } |
| 271 }); | 244 }); |
| 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 })(); | 245 })(); |
| 291 | 246 |
| 292 (function TestSub() { | 247 (function TestSub() { |
| 293 IntegerTypedArrayConstructors.forEach(function(t) { | 248 IntegerTypedArrayConstructors.forEach(function(t) { |
| 294 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 249 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 295 var sta = new t.constr(sab); | 250 var sta = new t.constr(sab); |
| 296 var name = Object.prototype.toString.call(sta); | 251 var name = Object.prototype.toString.call(sta); |
| 297 for (var i = 0; i < 10; ++i) { | 252 for (var i = 0; i < 10; ++i) { |
| 298 sta[i] = 120; | 253 sta[i] = 120; |
| 299 assertEquals(120, Atomics.sub(sta, i, 50), name); | 254 assertEquals(120, Atomics.sub(sta, i, 50), name); |
| 300 assertEquals(70, sta[i], name); | 255 assertEquals(70, sta[i], name); |
| 301 | 256 |
| 302 assertEquals(70, Atomics.sub(sta, i, 70), name); | 257 assertEquals(70, Atomics.sub(sta, i, 70), name); |
| 303 assertEquals(0, sta[i], name); | 258 assertEquals(0, sta[i], name); |
| 304 } | 259 } |
| 305 }); | 260 }); |
| 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 })(); | 261 })(); |
| 325 | 262 |
| 326 (function TestAnd() { | 263 (function TestAnd() { |
| 327 IntegerTypedArrayConstructors.forEach(function(t) { | 264 IntegerTypedArrayConstructors.forEach(function(t) { |
| 328 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 265 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 329 var sta = new t.constr(sab); | 266 var sta = new t.constr(sab); |
| 330 var name = Object.prototype.toString.call(sta); | 267 var name = Object.prototype.toString.call(sta); |
| 331 for (var i = 0; i < 10; ++i) { | 268 for (var i = 0; i < 10; ++i) { |
| 332 sta[i] = 0x3f; | 269 sta[i] = 0x3f; |
| 333 assertEquals(0x3f, Atomics.and(sta, i, 0x30), name); | 270 assertEquals(0x3f, Atomics.and(sta, i, 0x30), name); |
| 334 assertEquals(0x30, sta[i], name); | 271 assertEquals(0x30, sta[i], name); |
| 335 | 272 |
| 336 assertEquals(0x30, Atomics.and(sta, i, 0x20), name); | 273 assertEquals(0x30, Atomics.and(sta, i, 0x20), name); |
| 337 assertEquals(0x20, sta[i], name); | 274 assertEquals(0x20, sta[i], name); |
| 338 } | 275 } |
| 339 }); | 276 }); |
| 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 })(); | 277 })(); |
| 357 | 278 |
| 358 (function TestOr() { | 279 (function TestOr() { |
| 359 IntegerTypedArrayConstructors.forEach(function(t) { | 280 IntegerTypedArrayConstructors.forEach(function(t) { |
| 360 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 281 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 361 var sta = new t.constr(sab); | 282 var sta = new t.constr(sab); |
| 362 var name = Object.prototype.toString.call(sta); | 283 var name = Object.prototype.toString.call(sta); |
| 363 for (var i = 0; i < 10; ++i) { | 284 for (var i = 0; i < 10; ++i) { |
| 364 sta[i] = 0x30; | 285 sta[i] = 0x30; |
| 365 assertEquals(0x30, Atomics.or(sta, i, 0x1c), name); | 286 assertEquals(0x30, Atomics.or(sta, i, 0x1c), name); |
| 366 assertEquals(0x3c, sta[i], name); | 287 assertEquals(0x3c, sta[i], name); |
| 367 | 288 |
| 368 assertEquals(0x3c, Atomics.or(sta, i, 0x09), name); | 289 assertEquals(0x3c, Atomics.or(sta, i, 0x09), name); |
| 369 assertEquals(0x3d, sta[i], name); | 290 assertEquals(0x3d, sta[i], name); |
| 370 } | 291 } |
| 371 }); | 292 }); |
| 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 })(); | 293 })(); |
| 389 | 294 |
| 390 (function TestXor() { | 295 (function TestXor() { |
| 391 IntegerTypedArrayConstructors.forEach(function(t) { | 296 IntegerTypedArrayConstructors.forEach(function(t) { |
| 392 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 297 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 393 var sta = new t.constr(sab); | 298 var sta = new t.constr(sab); |
| 394 var name = Object.prototype.toString.call(sta); | 299 var name = Object.prototype.toString.call(sta); |
| 395 for (var i = 0; i < 10; ++i) { | 300 for (var i = 0; i < 10; ++i) { |
| 396 sta[i] = 0x30; | 301 sta[i] = 0x30; |
| 397 assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name); | 302 assertEquals(0x30, Atomics.xor(sta, i, 0x1c), name); |
| 398 assertEquals(0x2c, sta[i], name); | 303 assertEquals(0x2c, sta[i], name); |
| 399 | 304 |
| 400 assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name); | 305 assertEquals(0x2c, Atomics.xor(sta, i, 0x09), name); |
| 401 assertEquals(0x25, sta[i], name); | 306 assertEquals(0x25, sta[i], name); |
| 402 } | 307 } |
| 403 }); | 308 }); |
| 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 })(); | 309 })(); |
| 421 | 310 |
| 422 (function TestExchange() { | 311 (function TestExchange() { |
| 423 IntegerTypedArrayConstructors.forEach(function(t) { | 312 IntegerTypedArrayConstructors.forEach(function(t) { |
| 424 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); | 313 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 425 var sta = new t.constr(sab); | 314 var sta = new t.constr(sab); |
| 426 var name = Object.prototype.toString.call(sta); | 315 var name = Object.prototype.toString.call(sta); |
| 427 for (var i = 0; i < 10; ++i) { | 316 for (var i = 0; i < 10; ++i) { |
| 428 sta[i] = 0x30; | 317 sta[i] = 0x30; |
| 429 assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name); | 318 assertEquals(0x30, Atomics.exchange(sta, i, 0x1c), name); |
| 430 assertEquals(0x1c, sta[i], name); | 319 assertEquals(0x1c, sta[i], name); |
| 431 | 320 |
| 432 assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name); | 321 assertEquals(0x1c, Atomics.exchange(sta, i, 0x09), name); |
| 433 assertEquals(0x09, sta[i], name); | 322 assertEquals(0x09, sta[i], name); |
| 434 } | 323 } |
| 435 }); | 324 }); |
| 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 })(); | 325 })(); |
| 453 | 326 |
| 454 (function TestIsLockFree() { | 327 (function TestIsLockFree() { |
| 455 // For all platforms we support, 1, 2 and 4 bytes should be lock-free. | 328 // For all platforms we support, 1, 2 and 4 bytes should be lock-free. |
| 456 assertEquals(true, Atomics.isLockFree(1)); | 329 assertEquals(true, Atomics.isLockFree(1)); |
| 457 assertEquals(true, Atomics.isLockFree(2)); | 330 assertEquals(true, Atomics.isLockFree(2)); |
| 458 assertEquals(true, Atomics.isLockFree(4)); | 331 assertEquals(true, Atomics.isLockFree(4)); |
| 459 | 332 |
| 460 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return | 333 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return |
| 461 // false. | 334 // false. |
| 462 var validSizes = {}; | 335 var validSizes = {}; |
| 463 TypedArrayConstructors.forEach(function(t) { | 336 TypedArrayConstructors.forEach(function(t) { |
| 464 validSizes[t.constr.BYTES_PER_ELEMENT] = true; | 337 validSizes[t.constr.BYTES_PER_ELEMENT] = true; |
| 465 }); | 338 }); |
| 466 | 339 |
| 467 for (var i = 0; i < 1000; ++i) { | 340 for (var i = 0; i < 1000; ++i) { |
| 468 if (!validSizes[i]) { | 341 if (!validSizes[i]) { |
| 469 assertEquals(false, Atomics.isLockFree(i)); | 342 assertEquals(false, Atomics.isLockFree(i)); |
| 470 } | 343 } |
| 471 } | 344 } |
| 472 })(); | 345 })(); |
| 346 |
| 347 (function TestWrapping() { |
| 348 IntegerTypedArrayConstructors.forEach(function(t) { |
| 349 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); |
| 350 var sta = new t.constr(sab); |
| 351 var name = Object.prototype.toString.call(sta); |
| 352 var range = t.max - t.min + 1; |
| 353 var offset; |
| 354 var operand; |
| 355 var val, newVal; |
| 356 var valWrapped, newValWrapped; |
| 357 |
| 358 for (offset = -range; offset <= range; offset += range) { |
| 359 // CompareExchange |
| 360 sta[0] = val = 0; |
| 361 newVal = val + offset + 1; |
| 362 newValWrapped = t.toRange(newVal); |
| 363 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
| 364 assertEquals(newValWrapped, sta[0], name); |
| 365 |
| 366 sta[0] = val = t.min; |
| 367 newVal = val + offset - 1; |
| 368 newValWrapped = t.toRange(newVal); |
| 369 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name); |
| 370 assertEquals(newValWrapped, sta[0], name); |
| 371 |
| 372 // Store |
| 373 sta[0] = 0; |
| 374 val = t.max + offset + 1; |
| 375 valWrapped = t.toRange(val); |
| 376 assertEquals(val, Atomics.store(sta, 0, val), name); |
| 377 assertEquals(valWrapped, sta[0], name); |
| 378 |
| 379 sta[0] = val = t.min + offset - 1; |
| 380 valWrapped = t.toRange(val); |
| 381 assertEquals(val, Atomics.store(sta, 0, val), name); |
| 382 assertEquals(valWrapped, sta[0], name); |
| 383 |
| 384 // Add |
| 385 sta[0] = val = t.max; |
| 386 operand = offset + 1; |
| 387 valWrapped = t.toRange(val + operand); |
| 388 assertEquals(val, Atomics.add(sta, 0, operand), name); |
| 389 assertEquals(valWrapped, sta[0], name); |
| 390 |
| 391 sta[0] = val = t.min; |
| 392 operand = offset - 1; |
| 393 valWrapped = t.toRange(val + operand); |
| 394 assertEquals(val, Atomics.add(sta, 0, operand), name); |
| 395 assertEquals(valWrapped, sta[0], name); |
| 396 |
| 397 // Sub |
| 398 sta[0] = val = t.max; |
| 399 operand = offset - 1; |
| 400 valWrapped = t.toRange(val - operand); |
| 401 assertEquals(val, Atomics.sub(sta, 0, operand), name); |
| 402 assertEquals(valWrapped, sta[0], name); |
| 403 |
| 404 sta[0] = val = t.min; |
| 405 operand = offset + 1; |
| 406 valWrapped = t.toRange(val - operand); |
| 407 assertEquals(val, Atomics.sub(sta, 0, operand), name); |
| 408 assertEquals(valWrapped, sta[0], name); |
| 409 |
| 410 // There's no way to wrap results with logical operators, just test that |
| 411 // using an out-of-range value is properly wrapped/clamped when written |
| 412 // to memory. |
| 413 |
| 414 // And |
| 415 sta[0] = val = 0xf; |
| 416 operand = 0x3 + offset; |
| 417 valWrapped = t.toRange(val & operand); |
| 418 assertEquals(val, Atomics.and(sta, 0, operand), name); |
| 419 assertEquals(valWrapped, sta[0], name); |
| 420 |
| 421 // Or |
| 422 sta[0] = val = 0x12; |
| 423 operand = 0x22 + offset; |
| 424 valWrapped = t.toRange(val | operand); |
| 425 assertEquals(val, Atomics.or(sta, 0, operand), name); |
| 426 assertEquals(valWrapped, sta[0], name); |
| 427 |
| 428 // Xor |
| 429 sta[0] = val = 0x12; |
| 430 operand = 0x22 + offset; |
| 431 valWrapped = t.toRange(val ^ operand); |
| 432 assertEquals(val, Atomics.xor(sta, 0, operand), name); |
| 433 assertEquals(valWrapped, sta[0], name); |
| 434 |
| 435 // Exchange |
| 436 sta[0] = val = 0x12; |
| 437 operand = 0x22 + offset; |
| 438 valWrapped = t.toRange(operand); |
| 439 assertEquals(val, Atomics.exchange(sta, 0, operand), name); |
| 440 assertEquals(valWrapped, sta[0], name); |
| 441 } |
| 442 |
| 443 }); |
| 444 })(); |
| OLD | NEW |