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

Side by Side Diff: src/runtime/runtime-atomics.cc

Issue 2799863002: [Atomics] use TFJ builtins for atomic add, sub, and, or, and xor (Closed)
Patch Set: [Atomics] use TFJ builtins for atomic add, sub, and, or, and xor Created 3 years, 8 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 #include "src/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include "src/arguments.h" 7 #include "src/arguments.h"
8 #include "src/base/macros.h" 8 #include "src/base/macros.h"
9 #include "src/base/platform/mutex.h" 9 #include "src/base/platform/mutex.h"
10 #include "src/conversions-inl.h" 10 #include "src/conversions-inl.h"
(...skipping 15 matching lines...) Expand all
26 return __atomic_exchange_n(p, value, __ATOMIC_SEQ_CST); 26 return __atomic_exchange_n(p, value, __ATOMIC_SEQ_CST);
27 } 27 }
28 28
29 template <typename T> 29 template <typename T>
30 inline T CompareExchangeSeqCst(T* p, T oldval, T newval) { 30 inline T CompareExchangeSeqCst(T* p, T oldval, T newval) {
31 (void)__atomic_compare_exchange_n(p, &oldval, newval, 0, __ATOMIC_SEQ_CST, 31 (void)__atomic_compare_exchange_n(p, &oldval, newval, 0, __ATOMIC_SEQ_CST,
32 __ATOMIC_SEQ_CST); 32 __ATOMIC_SEQ_CST);
33 return oldval; 33 return oldval;
34 } 34 }
35 35
36 template <typename T>
37 inline T AddSeqCst(T* p, T value) {
38 return __atomic_fetch_add(p, value, __ATOMIC_SEQ_CST);
39 }
40
41 template <typename T>
42 inline T SubSeqCst(T* p, T value) {
43 return __atomic_fetch_sub(p, value, __ATOMIC_SEQ_CST);
44 }
45
46 template <typename T>
47 inline T AndSeqCst(T* p, T value) {
48 return __atomic_fetch_and(p, value, __ATOMIC_SEQ_CST);
49 }
50
51 template <typename T>
52 inline T OrSeqCst(T* p, T value) {
53 return __atomic_fetch_or(p, value, __ATOMIC_SEQ_CST);
54 }
55
56 template <typename T>
57 inline T XorSeqCst(T* p, T value) {
58 return __atomic_fetch_xor(p, value, __ATOMIC_SEQ_CST);
59 }
60
36 #elif V8_CC_MSVC 61 #elif V8_CC_MSVC
37 62
38 #define InterlockedExchange32 _InterlockedExchange 63 #define InterlockedExchange32 _InterlockedExchange
39 #define InterlockedCompareExchange32 _InterlockedCompareExchange 64 #define InterlockedCompareExchange32 _InterlockedCompareExchange
40 #define InterlockedCompareExchange8 _InterlockedCompareExchange8 65 #define InterlockedCompareExchange8 _InterlockedCompareExchange8
66 #define InterlockedExchangeAdd32 _InterlockedExchangeAdd
67 #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16
68 #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8
69 #define InterlockedAnd32 _InterlockedAnd
70 #define InterlockedOr32 _InterlockedOr
71 #define InterlockedXor32 _InterlockedXor
41 72
42 #define ATOMIC_OPS(type, suffix, vctype) \ 73 #define ATOMIC_OPS(type, suffix, vctype) \
43 inline type ExchangeSeqCst(type* p, type value) { \ 74 inline type ExchangeSeqCst(type* p, type value) { \
44 return InterlockedExchange##suffix(reinterpret_cast<vctype*>(p), \ 75 return InterlockedExchange##suffix(reinterpret_cast<vctype*>(p), \
45 bit_cast<vctype>(value)); \ 76 bit_cast<vctype>(value)); \
46 } \ 77 } \
47 inline type CompareExchangeSeqCst(type* p, type oldval, type newval) { \ 78 inline type CompareExchangeSeqCst(type* p, type oldval, type newval) { \
48 return InterlockedCompareExchange##suffix(reinterpret_cast<vctype*>(p), \ 79 return InterlockedCompareExchange##suffix(reinterpret_cast<vctype*>(p), \
49 bit_cast<vctype>(newval), \ 80 bit_cast<vctype>(newval), \
50 bit_cast<vctype>(oldval)); \ 81 bit_cast<vctype>(oldval)); \
82 } \
83 inline type AddSeqCst(type* p, type value) { \
84 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \
85 bit_cast<vctype>(value)); \
86 } \
87 inline type SubSeqCst(type* p, type value) { \
88 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \
89 -bit_cast<vctype>(value)); \
90 } \
91 inline type AndSeqCst(type* p, type value) { \
92 return InterlockedAnd##suffix(reinterpret_cast<vctype*>(p), \
93 bit_cast<vctype>(value)); \
94 } \
95 inline type OrSeqCst(type* p, type value) { \
96 return InterlockedOr##suffix(reinterpret_cast<vctype*>(p), \
97 bit_cast<vctype>(value)); \
98 } \
99 inline type XorSeqCst(type* p, type value) { \
100 return InterlockedXor##suffix(reinterpret_cast<vctype*>(p), \
101 bit_cast<vctype>(value)); \
51 } 102 }
52 103
53 ATOMIC_OPS(int8_t, 8, char) 104 ATOMIC_OPS(int8_t, 8, char)
54 ATOMIC_OPS(uint8_t, 8, char) 105 ATOMIC_OPS(uint8_t, 8, char)
55 ATOMIC_OPS(int16_t, 16, short) /* NOLINT(runtime/int) */ 106 ATOMIC_OPS(int16_t, 16, short) /* NOLINT(runtime/int) */
56 ATOMIC_OPS(uint16_t, 16, short) /* NOLINT(runtime/int) */ 107 ATOMIC_OPS(uint16_t, 16, short) /* NOLINT(runtime/int) */
57 ATOMIC_OPS(int32_t, 32, long) /* NOLINT(runtime/int) */ 108 ATOMIC_OPS(int32_t, 32, long) /* NOLINT(runtime/int) */
58 ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */ 109 ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */
59 110
60 #undef ATOMIC_OPS_INTEGER 111 #undef ATOMIC_OPS_INTEGER
61 #undef ATOMIC_OPS 112 #undef ATOMIC_OPS
62 113
63 #undef InterlockedExchange32 114 #undef InterlockedExchange32
64 #undef InterlockedCompareExchange32 115 #undef InterlockedCompareExchange32
65 #undef InterlockedCompareExchange8 116 #undef InterlockedCompareExchange8
117 #undef InterlockedExchangeAdd32
118 #undef InterlockedExchangeAdd16
119 #undef InterlockedExchangeAdd8
120 #undef InterlockedAnd32
121 #undef InterlockedOr32
122 #undef InterlockedXor32
66 123
67 #else 124 #else
68 125
69 #error Unsupported platform! 126 #error Unsupported platform!
70 127
71 #endif 128 #endif
72 129
73 template <typename T> 130 template <typename T>
74 T FromObject(Handle<Object> number); 131 T FromObject(Handle<Object> number);
75 132
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 template <typename T> 190 template <typename T>
134 inline Object* DoCompareExchange(Isolate* isolate, void* buffer, size_t index, 191 inline Object* DoCompareExchange(Isolate* isolate, void* buffer, size_t index,
135 Handle<Object> oldobj, Handle<Object> newobj) { 192 Handle<Object> oldobj, Handle<Object> newobj) {
136 T oldval = FromObject<T>(oldobj); 193 T oldval = FromObject<T>(oldobj);
137 T newval = FromObject<T>(newobj); 194 T newval = FromObject<T>(newobj);
138 T result = 195 T result =
139 CompareExchangeSeqCst(static_cast<T*>(buffer) + index, oldval, newval); 196 CompareExchangeSeqCst(static_cast<T*>(buffer) + index, oldval, newval);
140 return ToObject(isolate, result); 197 return ToObject(isolate, result);
141 } 198 }
142 199
200 template <typename T>
201 inline Object* DoAdd(Isolate* isolate, void* buffer, size_t index,
202 Handle<Object> obj) {
203 T value = FromObject<T>(obj);
204 T result = AddSeqCst(static_cast<T*>(buffer) + index, value);
205 return ToObject(isolate, result);
206 }
207
208 template <typename T>
209 inline Object* DoSub(Isolate* isolate, void* buffer, size_t index,
210 Handle<Object> obj) {
211 T value = FromObject<T>(obj);
212 T result = SubSeqCst(static_cast<T*>(buffer) + index, value);
213 return ToObject(isolate, result);
214 }
215
216 template <typename T>
217 inline Object* DoAnd(Isolate* isolate, void* buffer, size_t index,
218 Handle<Object> obj) {
219 T value = FromObject<T>(obj);
220 T result = AndSeqCst(static_cast<T*>(buffer) + index, value);
221 return ToObject(isolate, result);
222 }
223
224 template <typename T>
225 inline Object* DoOr(Isolate* isolate, void* buffer, size_t index,
226 Handle<Object> obj) {
227 T value = FromObject<T>(obj);
228 T result = OrSeqCst(static_cast<T*>(buffer) + index, value);
229 return ToObject(isolate, result);
230 }
231
232 template <typename T>
233 inline Object* DoXor(Isolate* isolate, void* buffer, size_t index,
234 Handle<Object> obj) {
235 T value = FromObject<T>(obj);
236 T result = XorSeqCst(static_cast<T*>(buffer) + index, value);
237 return ToObject(isolate, result);
238 }
239
143 } // anonymous namespace 240 } // anonymous namespace
144 241
145 // Duplicated from objects.h 242 // Duplicated from objects.h
146 // V has parameters (Type, type, TYPE, C type, element_size) 243 // V has parameters (Type, type, TYPE, C type, element_size)
147 #define INTEGER_TYPED_ARRAYS(V) \ 244 #define INTEGER_TYPED_ARRAYS(V) \
148 V(Uint8, uint8, UINT8, uint8_t, 1) \ 245 V(Uint8, uint8, UINT8, uint8_t, 1) \
149 V(Int8, int8, INT8, int8_t, 1) \ 246 V(Int8, int8, INT8, int8_t, 1) \
150 V(Uint16, uint16, UINT16, uint16_t, 2) \ 247 V(Uint16, uint16, UINT16, uint16_t, 2) \
151 V(Int16, int16, INT16, int16_t, 2) \ 248 V(Int16, int16, INT16, int16_t, 2) \
152 V(Uint32, uint32, UINT32, uint32_t, 4) \ 249 V(Uint32, uint32, UINT32, uint32_t, 4) \
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 #undef TYPED_ARRAY_CASE 323 #undef TYPED_ARRAY_CASE
227 324
228 default: 325 default:
229 break; 326 break;
230 } 327 }
231 328
232 UNREACHABLE(); 329 UNREACHABLE();
233 return isolate->heap()->undefined_value(); 330 return isolate->heap()->undefined_value();
234 } 331 }
235 332
333 // ES #sec-atomics.add
334 // Atomics.add( typedArray, index, value )
335 RUNTIME_FUNCTION(Runtime_AtomicsAdd) {
336 HandleScope scope(isolate);
337 DCHECK_EQ(3, args.length());
338 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
339 CONVERT_SIZE_ARG_CHECKED(index, 1);
340 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
341 CHECK(sta->GetBuffer()->is_shared());
342 CHECK_LT(index, NumberToSize(sta->length()));
343
344 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
345 NumberToSize(sta->byte_offset());
346
347 switch (sta->type()) {
348 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
349 case kExternal##Type##Array: \
350 return DoAdd<ctype>(isolate, source, index, value);
351
352 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
353 #undef TYPED_ARRAY_CASE
354
355 default:
356 break;
357 }
358
359 UNREACHABLE();
360 return isolate->heap()->undefined_value();
361 }
362
363 // ES #sec-atomics.sub
364 // Atomics.sub( typedArray, index, value )
365 RUNTIME_FUNCTION(Runtime_AtomicsSub) {
366 HandleScope scope(isolate);
367 DCHECK_EQ(3, args.length());
368 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
369 CONVERT_SIZE_ARG_CHECKED(index, 1);
370 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
371 CHECK(sta->GetBuffer()->is_shared());
372 CHECK_LT(index, NumberToSize(sta->length()));
373
374 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
375 NumberToSize(sta->byte_offset());
376
377 switch (sta->type()) {
378 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
379 case kExternal##Type##Array: \
380 return DoSub<ctype>(isolate, source, index, value);
381
382 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
383 #undef TYPED_ARRAY_CASE
384
385 default:
386 break;
387 }
388
389 UNREACHABLE();
390 return isolate->heap()->undefined_value();
391 }
392
393 // ES #sec-atomics.and
394 // Atomics.and( typedArray, index, value )
395 RUNTIME_FUNCTION(Runtime_AtomicsAnd) {
396 HandleScope scope(isolate);
397 DCHECK_EQ(3, args.length());
398 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
399 CONVERT_SIZE_ARG_CHECKED(index, 1);
400 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
401 CHECK(sta->GetBuffer()->is_shared());
402 CHECK_LT(index, NumberToSize(sta->length()));
403
404 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
405 NumberToSize(sta->byte_offset());
406
407 switch (sta->type()) {
408 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
409 case kExternal##Type##Array: \
410 return DoAnd<ctype>(isolate, source, index, value);
411
412 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
413 #undef TYPED_ARRAY_CASE
414
415 default:
416 break;
417 }
418
419 UNREACHABLE();
420 return isolate->heap()->undefined_value();
421 }
422
423 // ES #sec-atomics.or
424 // Atomics.or( typedArray, index, value )
425 RUNTIME_FUNCTION(Runtime_AtomicsOr) {
426 HandleScope scope(isolate);
427 DCHECK_EQ(3, args.length());
428 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
429 CONVERT_SIZE_ARG_CHECKED(index, 1);
430 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
431 CHECK(sta->GetBuffer()->is_shared());
432 CHECK_LT(index, NumberToSize(sta->length()));
433
434 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
435 NumberToSize(sta->byte_offset());
436
437 switch (sta->type()) {
438 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
439 case kExternal##Type##Array: \
440 return DoOr<ctype>(isolate, source, index, value);
441
442 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
443 #undef TYPED_ARRAY_CASE
444
445 default:
446 break;
447 }
448
449 UNREACHABLE();
450 return isolate->heap()->undefined_value();
451 }
452
453 // ES #sec-atomics.xor
454 // Atomics.xor( typedArray, index, value )
455 RUNTIME_FUNCTION(Runtime_AtomicsXor) {
456 HandleScope scope(isolate);
457 DCHECK_EQ(3, args.length());
458 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
459 CONVERT_SIZE_ARG_CHECKED(index, 1);
460 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
461 CHECK(sta->GetBuffer()->is_shared());
462 CHECK_LT(index, NumberToSize(sta->length()));
463
464 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
465 NumberToSize(sta->byte_offset());
466
467 switch (sta->type()) {
468 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
469 case kExternal##Type##Array: \
470 return DoXor<ctype>(isolate, source, index, value);
471
472 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
473 #undef TYPED_ARRAY_CASE
474
475 default:
476 break;
477 }
478
479 UNREACHABLE();
480 return isolate->heap()->undefined_value();
481 }
482
236 } // namespace internal 483 } // namespace internal
237 } // namespace v8 484 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698