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

Side by Side Diff: src/builtins/builtins-sharedarraybuffer.cc

Issue 2649703002: [Atomics] Make Atomics.compareExchange a builtin using TF (Closed)
Patch Set: rebase and move cmpxchg to builtins-sharedarraybuffer-gen.cc Created 3 years, 9 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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/base/macros.h" 5 #include "src/base/macros.h"
6 #include "src/base/platform/mutex.h" 6 #include "src/base/platform/mutex.h"
7 #include "src/base/platform/time.h" 7 #include "src/base/platform/time.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 179
180 return FutexEmulation::Wait(isolate, array_buffer, addr, value_int32, 180 return FutexEmulation::Wait(isolate, array_buffer, addr, value_int32,
181 timeout_number); 181 timeout_number);
182 } 182 }
183 183
184 namespace { 184 namespace {
185 185
186 #if V8_CC_GNU 186 #if V8_CC_GNU
187 187
188 template <typename T> 188 template <typename T>
189 inline T CompareExchangeSeqCst(T* p, T oldval, T newval) {
190 (void)__atomic_compare_exchange_n(p, &oldval, newval, 0, __ATOMIC_SEQ_CST,
191 __ATOMIC_SEQ_CST);
192 return oldval;
193 }
194
195 template <typename T>
196 inline T AddSeqCst(T* p, T value) { 189 inline T AddSeqCst(T* p, T value) {
197 return __atomic_fetch_add(p, value, __ATOMIC_SEQ_CST); 190 return __atomic_fetch_add(p, value, __ATOMIC_SEQ_CST);
198 } 191 }
199 192
200 template <typename T> 193 template <typename T>
201 inline T SubSeqCst(T* p, T value) { 194 inline T SubSeqCst(T* p, T value) {
202 return __atomic_fetch_sub(p, value, __ATOMIC_SEQ_CST); 195 return __atomic_fetch_sub(p, value, __ATOMIC_SEQ_CST);
203 } 196 }
204 197
205 template <typename T> 198 template <typename T>
206 inline T AndSeqCst(T* p, T value) { 199 inline T AndSeqCst(T* p, T value) {
207 return __atomic_fetch_and(p, value, __ATOMIC_SEQ_CST); 200 return __atomic_fetch_and(p, value, __ATOMIC_SEQ_CST);
208 } 201 }
209 202
210 template <typename T> 203 template <typename T>
211 inline T OrSeqCst(T* p, T value) { 204 inline T OrSeqCst(T* p, T value) {
212 return __atomic_fetch_or(p, value, __ATOMIC_SEQ_CST); 205 return __atomic_fetch_or(p, value, __ATOMIC_SEQ_CST);
213 } 206 }
214 207
215 template <typename T> 208 template <typename T>
216 inline T XorSeqCst(T* p, T value) { 209 inline T XorSeqCst(T* p, T value) {
217 return __atomic_fetch_xor(p, value, __ATOMIC_SEQ_CST); 210 return __atomic_fetch_xor(p, value, __ATOMIC_SEQ_CST);
218 } 211 }
219 212
220 #elif V8_CC_MSVC 213 #elif V8_CC_MSVC
221 214
222 #define InterlockedCompareExchange32 _InterlockedCompareExchange
223 #define InterlockedExchange32 _InterlockedExchange
224 #define InterlockedExchangeAdd32 _InterlockedExchangeAdd 215 #define InterlockedExchangeAdd32 _InterlockedExchangeAdd
225 #define InterlockedAnd32 _InterlockedAnd 216 #define InterlockedAnd32 _InterlockedAnd
226 #define InterlockedOr32 _InterlockedOr 217 #define InterlockedOr32 _InterlockedOr
227 #define InterlockedXor32 _InterlockedXor 218 #define InterlockedXor32 _InterlockedXor
228 #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16 219 #define InterlockedExchangeAdd16 _InterlockedExchangeAdd16
229 #define InterlockedCompareExchange8 _InterlockedCompareExchange8
230 #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8 220 #define InterlockedExchangeAdd8 _InterlockedExchangeAdd8
231 221
232 #define ATOMIC_OPS(type, suffix, vctype) \ 222 #define ATOMIC_OPS(type, suffix, vctype) \
233 inline type AddSeqCst(type* p, type value) { \ 223 inline type AddSeqCst(type* p, type value) { \
234 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \ 224 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \
235 bit_cast<vctype>(value)); \ 225 bit_cast<vctype>(value)); \
236 } \ 226 } \
237 inline type SubSeqCst(type* p, type value) { \ 227 inline type SubSeqCst(type* p, type value) { \
238 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \ 228 return InterlockedExchangeAdd##suffix(reinterpret_cast<vctype*>(p), \
239 -bit_cast<vctype>(value)); \ 229 -bit_cast<vctype>(value)); \
240 } \ 230 } \
241 inline type AndSeqCst(type* p, type value) { \ 231 inline type AndSeqCst(type* p, type value) { \
242 return InterlockedAnd##suffix(reinterpret_cast<vctype*>(p), \ 232 return InterlockedAnd##suffix(reinterpret_cast<vctype*>(p), \
243 bit_cast<vctype>(value)); \ 233 bit_cast<vctype>(value)); \
244 } \ 234 } \
245 inline type OrSeqCst(type* p, type value) { \ 235 inline type OrSeqCst(type* p, type value) { \
246 return InterlockedOr##suffix(reinterpret_cast<vctype*>(p), \ 236 return InterlockedOr##suffix(reinterpret_cast<vctype*>(p), \
247 bit_cast<vctype>(value)); \ 237 bit_cast<vctype>(value)); \
248 } \ 238 } \
249 inline type XorSeqCst(type* p, type value) { \ 239 inline type XorSeqCst(type* p, type value) { \
250 return InterlockedXor##suffix(reinterpret_cast<vctype*>(p), \ 240 return InterlockedXor##suffix(reinterpret_cast<vctype*>(p), \
251 bit_cast<vctype>(value)); \ 241 bit_cast<vctype>(value)); \
252 } \
253 inline type CompareExchangeSeqCst(type* p, type oldval, type newval) { \
254 return InterlockedCompareExchange##suffix(reinterpret_cast<vctype*>(p), \
255 bit_cast<vctype>(newval), \
256 bit_cast<vctype>(oldval)); \
257 } 242 }
258 243
259 ATOMIC_OPS(int8_t, 8, char) 244 ATOMIC_OPS(int8_t, 8, char)
260 ATOMIC_OPS(uint8_t, 8, char) 245 ATOMIC_OPS(uint8_t, 8, char)
261 ATOMIC_OPS(int16_t, 16, short) /* NOLINT(runtime/int) */ 246 ATOMIC_OPS(int16_t, 16, short) /* NOLINT(runtime/int) */
262 ATOMIC_OPS(uint16_t, 16, short) /* NOLINT(runtime/int) */ 247 ATOMIC_OPS(uint16_t, 16, short) /* NOLINT(runtime/int) */
263 ATOMIC_OPS(int32_t, 32, long) /* NOLINT(runtime/int) */ 248 ATOMIC_OPS(int32_t, 32, long) /* NOLINT(runtime/int) */
264 ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */ 249 ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */
265 250
266 #undef ATOMIC_OPS_INTEGER 251 #undef ATOMIC_OPS_INTEGER
267 #undef ATOMIC_OPS 252 #undef ATOMIC_OPS
268 253
269 #undef InterlockedCompareExchange32
270 #undef InterlockedExchange32
271 #undef InterlockedExchangeAdd32 254 #undef InterlockedExchangeAdd32
272 #undef InterlockedAnd32 255 #undef InterlockedAnd32
273 #undef InterlockedOr32 256 #undef InterlockedOr32
274 #undef InterlockedXor32 257 #undef InterlockedXor32
275 #undef InterlockedExchangeAdd16 258 #undef InterlockedExchangeAdd16
276 #undef InterlockedCompareExchange8
277 #undef InterlockedExchangeAdd8 259 #undef InterlockedExchangeAdd8
278 260
279 #else 261 #else
280 262
281 #error Unsupported platform! 263 #error Unsupported platform!
282 264
283 #endif 265 #endif
284 266
285 template <typename T> 267 template <typename T>
286 T FromObject(Handle<Object> number); 268 T FromObject(Handle<Object> number);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 309
328 inline Object* ToObject(Isolate* isolate, int32_t t) { 310 inline Object* ToObject(Isolate* isolate, int32_t t) {
329 return *isolate->factory()->NewNumber(t); 311 return *isolate->factory()->NewNumber(t);
330 } 312 }
331 313
332 inline Object* ToObject(Isolate* isolate, uint32_t t) { 314 inline Object* ToObject(Isolate* isolate, uint32_t t) {
333 return *isolate->factory()->NewNumber(t); 315 return *isolate->factory()->NewNumber(t);
334 } 316 }
335 317
336 template <typename T> 318 template <typename T>
337 inline Object* DoCompareExchange(Isolate* isolate, void* buffer, size_t index,
338 Handle<Object> oldobj, Handle<Object> newobj) {
339 T oldval = FromObject<T>(oldobj);
340 T newval = FromObject<T>(newobj);
341 T result =
342 CompareExchangeSeqCst(static_cast<T*>(buffer) + index, oldval, newval);
343 return ToObject(isolate, result);
344 }
345
346 template <typename T>
347 inline Object* DoAdd(Isolate* isolate, void* buffer, size_t index, 319 inline Object* DoAdd(Isolate* isolate, void* buffer, size_t index,
348 Handle<Object> obj) { 320 Handle<Object> obj) {
349 T value = FromObject<T>(obj); 321 T value = FromObject<T>(obj);
350 T result = AddSeqCst(static_cast<T*>(buffer) + index, value); 322 T result = AddSeqCst(static_cast<T*>(buffer) + index, value);
351 return ToObject(isolate, result); 323 return ToObject(isolate, result);
352 } 324 }
353 325
354 template <typename T> 326 template <typename T>
355 inline Object* DoSub(Isolate* isolate, void* buffer, size_t index, 327 inline Object* DoSub(Isolate* isolate, void* buffer, size_t index,
356 Handle<Object> obj) { 328 Handle<Object> obj) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // Duplicated from objects.h 360 // Duplicated from objects.h
389 // V has parameters (Type, type, TYPE, C type, element_size) 361 // V has parameters (Type, type, TYPE, C type, element_size)
390 #define INTEGER_TYPED_ARRAYS(V) \ 362 #define INTEGER_TYPED_ARRAYS(V) \
391 V(Uint8, uint8, UINT8, uint8_t, 1) \ 363 V(Uint8, uint8, UINT8, uint8_t, 1) \
392 V(Int8, int8, INT8, int8_t, 1) \ 364 V(Int8, int8, INT8, int8_t, 1) \
393 V(Uint16, uint16, UINT16, uint16_t, 2) \ 365 V(Uint16, uint16, UINT16, uint16_t, 2) \
394 V(Int16, int16, INT16, int16_t, 2) \ 366 V(Int16, int16, INT16, int16_t, 2) \
395 V(Uint32, uint32, UINT32, uint32_t, 4) \ 367 V(Uint32, uint32, UINT32, uint32_t, 4) \
396 V(Int32, int32, INT32, int32_t, 4) 368 V(Int32, int32, INT32, int32_t, 4)
397 369
398 // ES #sec-atomics.wait
399 // Atomics.compareExchange( typedArray, index, expectedValue, replacementValue )
400 BUILTIN(AtomicsCompareExchange) {
401 HandleScope scope(isolate);
402 Handle<Object> array = args.atOrUndefined(isolate, 1);
403 Handle<Object> index = args.atOrUndefined(isolate, 2);
404 Handle<Object> expected_value = args.atOrUndefined(isolate, 3);
405 Handle<Object> replacement_value = args.atOrUndefined(isolate, 4);
406
407 Handle<JSTypedArray> sta;
408 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
409 isolate, sta, ValidateSharedIntegerTypedArray(isolate, array));
410
411 Maybe<size_t> maybe_index = ValidateAtomicAccess(isolate, sta, index);
412 if (maybe_index.IsNothing()) return isolate->heap()->exception();
413 size_t i = maybe_index.FromJust();
414
415 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
416 isolate, expected_value, Object::ToInteger(isolate, expected_value));
417
418 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
419 isolate, replacement_value,
420 Object::ToInteger(isolate, replacement_value));
421
422 uint8_t* source = static_cast<uint8_t*>(sta->GetBuffer()->backing_store()) +
423 NumberToSize(sta->byte_offset());
424
425 switch (sta->type()) {
426 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
427 case kExternal##Type##Array: \
428 return DoCompareExchange<ctype>(isolate, source, i, expected_value, \
429 replacement_value);
430
431 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
432 #undef TYPED_ARRAY_CASE
433
434 default:
435 break;
436 }
437
438 UNREACHABLE();
439 return isolate->heap()->undefined_value();
440 }
441
442 // ES #sec-atomics.add 370 // ES #sec-atomics.add
443 // Atomics.add( typedArray, index, value ) 371 // Atomics.add( typedArray, index, value )
444 BUILTIN(AtomicsAdd) { 372 BUILTIN(AtomicsAdd) {
445 HandleScope scope(isolate); 373 HandleScope scope(isolate);
446 Handle<Object> array = args.atOrUndefined(isolate, 1); 374 Handle<Object> array = args.atOrUndefined(isolate, 1);
447 Handle<Object> index = args.atOrUndefined(isolate, 2); 375 Handle<Object> index = args.atOrUndefined(isolate, 2);
448 Handle<Object> value = args.atOrUndefined(isolate, 3); 376 Handle<Object> value = args.atOrUndefined(isolate, 3);
449 377
450 Handle<JSTypedArray> sta; 378 Handle<JSTypedArray> sta;
451 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 379 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 default: 552 default:
625 break; 553 break;
626 } 554 }
627 555
628 UNREACHABLE(); 556 UNREACHABLE();
629 return isolate->heap()->undefined_value(); 557 return isolate->heap()->undefined_value();
630 } 558 }
631 559
632 } // namespace internal 560 } // namespace internal
633 } // namespace v8 561 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698