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

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

Issue 1201543002: Atomic operations on Uint8ClampedArray (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | test/mjsunit/harmony/atomics.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/v8.h" 5 #include "src/v8.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.h" 10 #include "src/conversions.h"
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index, 417 inline Object* DoExchange(Isolate* isolate, void* buffer, size_t index,
418 Handle<Object> obj) { 418 Handle<Object> obj) {
419 typedef typename FromObjectTraits<T>::atomic_type atomic_type; 419 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
420 typedef typename FromObjectTraits<T>::convert_type convert_type; 420 typedef typename FromObjectTraits<T>::convert_type convert_type;
421 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj)); 421 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
422 atomic_type result = 422 atomic_type result =
423 ExchangeSeqCst(static_cast<atomic_type*>(buffer) + index, value); 423 ExchangeSeqCst(static_cast<atomic_type*>(buffer) + index, value);
424 return ToObject<T>(isolate, FromAtomic<T>(result)); 424 return ToObject<T>(isolate, FromAtomic<T>(result));
425 } 425 }
426 426
427
428 // Uint8Clamped functions
429
430 uint8_t ClampToUint8(int32_t value) {
431 if (value < 0) return 0;
432 if (value > 255) return 255;
433 return value;
Jarin 2015/06/22 07:04:03 Hmm, I am really surprised this does not need any
binji 2015/06/22 18:21:04 I didn't notice it until you mentioned it. I check
434 }
435
436
437 inline Object* DoCompareExchangeUint8Clamped(Isolate* isolate, void* buffer,
438 size_t index,
439 Handle<Object> oldobj,
440 Handle<Object> newobj) {
441 typedef int32_t convert_type;
442 typedef uint8_t atomic_type;
443 atomic_type oldval = ClampToUint8(FromObject<convert_type>(oldobj));
444 atomic_type newval = ClampToUint8(FromObject<convert_type>(newobj));
445 atomic_type result = CompareExchangeSeqCst(
446 static_cast<atomic_type*>(buffer) + index, oldval, newval);
447 return ToObject<uint8_t>(isolate, FromAtomic<uint8_t>(result));
448 }
449
450
451 inline Object* DoStoreUint8Clamped(Isolate* isolate, void* buffer, size_t index,
452 Handle<Object> obj) {
453 typedef int32_t convert_type;
454 typedef uint8_t atomic_type;
455 atomic_type value = ClampToUint8(FromObject<convert_type>(obj));
456 StoreSeqCst(static_cast<atomic_type*>(buffer) + index, value);
457 return *obj;
458 }
459
460
461 #define DO_UINT8_CLAMPED_OP(name, op) \
462 inline Object* Do##name##Uint8Clamped(Isolate* isolate, void* buffer, \
463 size_t index, Handle<Object> obj) { \
464 typedef int32_t convert_type; \
465 typedef uint8_t atomic_type; \
466 atomic_type* p = static_cast<atomic_type*>(buffer) + index; \
467 convert_type operand = FromObject<convert_type>(obj); \
468 atomic_type expected; \
469 atomic_type result; \
470 do { \
471 expected = *p; \
472 result = ClampToUint8(static_cast<convert_type>(expected) op operand); \
473 } while (CompareExchangeSeqCst(p, expected, result) != expected); \
474 return ToObject<uint8_t>(isolate, expected); \
475 }
476
477 DO_UINT8_CLAMPED_OP(Add, +)
478 DO_UINT8_CLAMPED_OP(Sub, -)
479 DO_UINT8_CLAMPED_OP(And, &)
480 DO_UINT8_CLAMPED_OP(Or, | )
481 DO_UINT8_CLAMPED_OP(Xor, ^)
482
483 #undef DO_UINT8_CLAMPED_OP
484
485
486 inline Object* DoExchangeUint8Clamped(Isolate* isolate, void* buffer,
487 size_t index, Handle<Object> obj) {
488 typedef int32_t convert_type;
489 typedef uint8_t atomic_type;
490 atomic_type* p = static_cast<atomic_type*>(buffer) + index;
491 atomic_type result = ClampToUint8(FromObject<convert_type>(obj));
492 atomic_type expected;
493 do {
494 expected = *p;
495 } while (CompareExchangeSeqCst(p, expected, result) != expected);
496 return ToObject<uint8_t>(isolate, expected);
497 }
498
499
427 } // anonymous namespace 500 } // anonymous namespace
428 501
429 // Duplicated from objects.h 502 // Duplicated from objects.h
430 // V has parameters (Type, type, TYPE, C type, element_size) 503 // V has parameters (Type, type, TYPE, C type, element_size)
431 #define INTEGER_TYPED_ARRAYS(V) \ 504 #define INTEGER_TYPED_ARRAYS(V) \
432 V(Uint8, uint8, UINT8, uint8_t, 1) \ 505 V(Uint8, uint8, UINT8, uint8_t, 1) \
433 V(Int8, int8, INT8, int8_t, 1) \ 506 V(Int8, int8, INT8, int8_t, 1) \
434 V(Uint16, uint16, UINT16, uint16_t, 2) \ 507 V(Uint16, uint16, UINT16, uint16_t, 2) \
435 V(Int16, int16, INT16, int16_t, 2) \ 508 V(Int16, int16, INT16, int16_t, 2) \
436 V(Uint32, uint32, UINT32, uint32_t, 4) \ 509 V(Uint32, uint32, UINT32, uint32_t, 4) \
437 V(Int32, int32, INT32, int32_t, 4) \ 510 V(Int32, int32, INT32, int32_t, 4)
438 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
439 511
440 512
441 RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { 513 RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) {
442 HandleScope scope(isolate); 514 HandleScope scope(isolate);
443 DCHECK(args.length() == 4); 515 DCHECK(args.length() == 4);
444 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); 516 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
445 CONVERT_SIZE_ARG_CHECKED(index, 1); 517 CONVERT_SIZE_ARG_CHECKED(index, 1);
446 CONVERT_NUMBER_ARG_HANDLE_CHECKED(oldobj, 2); 518 CONVERT_NUMBER_ARG_HANDLE_CHECKED(oldobj, 2);
447 CONVERT_NUMBER_ARG_HANDLE_CHECKED(newobj, 3); 519 CONVERT_NUMBER_ARG_HANDLE_CHECKED(newobj, 3);
448 RUNTIME_ASSERT(sta->GetBuffer()->is_shared()); 520 RUNTIME_ASSERT(sta->GetBuffer()->is_shared());
449 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length())); 521 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length()));
450 522
451 void* buffer = sta->GetBuffer()->backing_store(); 523 void* buffer = sta->GetBuffer()->backing_store();
452 524
453 switch (sta->type()) { 525 switch (sta->type()) {
454 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 526 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
455 case kExternal##Type##Array: \ 527 case kExternal##Type##Array: \
456 return DoCompareExchange<ctype>(isolate, buffer, index, oldobj, newobj); 528 return DoCompareExchange<ctype>(isolate, buffer, index, oldobj, newobj);
457 529
458 TYPED_ARRAYS(TYPED_ARRAY_CASE) 530 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
459 #undef TYPED_ARRAY_CASE 531 #undef TYPED_ARRAY_CASE
460 532
533 case kExternalFloat32Array:
534 return DoCompareExchange<float>(isolate, buffer, index, oldobj, newobj);
535
536 case kExternalFloat64Array:
537 return DoCompareExchange<double>(isolate, buffer, index, oldobj, newobj);
538
539 case kExternalUint8ClampedArray:
540 return DoCompareExchangeUint8Clamped(isolate, buffer, index, oldobj,
541 newobj);
542
461 default: 543 default:
462 break; 544 break;
463 } 545 }
464 546
465 UNREACHABLE(); 547 UNREACHABLE();
466 return isolate->heap()->undefined_value(); 548 return isolate->heap()->undefined_value();
467 } 549 }
468 550
469 551
470 RUNTIME_FUNCTION(Runtime_AtomicsLoad) { 552 RUNTIME_FUNCTION(Runtime_AtomicsLoad) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 RUNTIME_ASSERT(sta->GetBuffer()->is_shared()); 585 RUNTIME_ASSERT(sta->GetBuffer()->is_shared());
504 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length())); 586 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length()));
505 587
506 void* buffer = sta->GetBuffer()->backing_store(); 588 void* buffer = sta->GetBuffer()->backing_store();
507 589
508 switch (sta->type()) { 590 switch (sta->type()) {
509 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 591 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
510 case kExternal##Type##Array: \ 592 case kExternal##Type##Array: \
511 return DoStore<ctype>(isolate, buffer, index, value); 593 return DoStore<ctype>(isolate, buffer, index, value);
512 594
513 TYPED_ARRAYS(TYPED_ARRAY_CASE) 595 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
514 #undef TYPED_ARRAY_CASE 596 #undef TYPED_ARRAY_CASE
515 597
598 case kExternalFloat32Array:
599 return DoStore<float>(isolate, buffer, index, value);
600
601 case kExternalFloat64Array:
602 return DoStore<double>(isolate, buffer, index, value);
603
604 case kExternalUint8ClampedArray:
605 return DoStoreUint8Clamped(isolate, buffer, index, value);
606
516 default: 607 default:
517 break; 608 break;
518 } 609 }
519 610
520 UNREACHABLE(); 611 UNREACHABLE();
521 return isolate->heap()->undefined_value(); 612 return isolate->heap()->undefined_value();
522 } 613 }
523 614
524 615
525 RUNTIME_FUNCTION(Runtime_AtomicsAdd) { 616 RUNTIME_FUNCTION(Runtime_AtomicsAdd) {
526 HandleScope scope(isolate); 617 HandleScope scope(isolate);
527 DCHECK(args.length() == 3); 618 DCHECK(args.length() == 3);
528 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); 619 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
529 CONVERT_SIZE_ARG_CHECKED(index, 1); 620 CONVERT_SIZE_ARG_CHECKED(index, 1);
530 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); 621 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
531 RUNTIME_ASSERT(sta->GetBuffer()->is_shared()); 622 RUNTIME_ASSERT(sta->GetBuffer()->is_shared());
532 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length())); 623 RUNTIME_ASSERT(index < NumberToSize(isolate, sta->length()));
533 624
534 void* buffer = sta->GetBuffer()->backing_store(); 625 void* buffer = sta->GetBuffer()->backing_store();
535 626
536 switch (sta->type()) { 627 switch (sta->type()) {
537 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 628 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
538 case kExternal##Type##Array: \ 629 case kExternal##Type##Array: \
539 return DoAdd<ctype>(isolate, buffer, index, value); 630 return DoAdd<ctype>(isolate, buffer, index, value);
540 631
541 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 632 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
542 #undef TYPED_ARRAY_CASE 633 #undef TYPED_ARRAY_CASE
543 634
635 case kExternalUint8ClampedArray:
636 return DoAddUint8Clamped(isolate, buffer, index, value);
637
544 case kExternalFloat32Array: 638 case kExternalFloat32Array:
545 case kExternalFloat64Array: 639 case kExternalFloat64Array:
546 default: 640 default:
547 break; 641 break;
548 } 642 }
549 643
550 UNREACHABLE(); 644 UNREACHABLE();
551 return isolate->heap()->undefined_value(); 645 return isolate->heap()->undefined_value();
552 } 646 }
553 647
(...skipping 10 matching lines...) Expand all
564 void* buffer = sta->GetBuffer()->backing_store(); 658 void* buffer = sta->GetBuffer()->backing_store();
565 659
566 switch (sta->type()) { 660 switch (sta->type()) {
567 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 661 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
568 case kExternal##Type##Array: \ 662 case kExternal##Type##Array: \
569 return DoSub<ctype>(isolate, buffer, index, value); 663 return DoSub<ctype>(isolate, buffer, index, value);
570 664
571 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 665 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
572 #undef TYPED_ARRAY_CASE 666 #undef TYPED_ARRAY_CASE
573 667
668 case kExternalUint8ClampedArray:
669 return DoSubUint8Clamped(isolate, buffer, index, value);
670
574 case kExternalFloat32Array: 671 case kExternalFloat32Array:
575 case kExternalFloat64Array: 672 case kExternalFloat64Array:
576 default: 673 default:
577 break; 674 break;
578 } 675 }
579 676
580 UNREACHABLE(); 677 UNREACHABLE();
581 return isolate->heap()->undefined_value(); 678 return isolate->heap()->undefined_value();
582 } 679 }
583 680
(...skipping 10 matching lines...) Expand all
594 void* buffer = sta->GetBuffer()->backing_store(); 691 void* buffer = sta->GetBuffer()->backing_store();
595 692
596 switch (sta->type()) { 693 switch (sta->type()) {
597 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 694 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
598 case kExternal##Type##Array: \ 695 case kExternal##Type##Array: \
599 return DoAnd<ctype>(isolate, buffer, index, value); 696 return DoAnd<ctype>(isolate, buffer, index, value);
600 697
601 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 698 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
602 #undef TYPED_ARRAY_CASE 699 #undef TYPED_ARRAY_CASE
603 700
701 case kExternalUint8ClampedArray:
702 return DoAndUint8Clamped(isolate, buffer, index, value);
703
604 case kExternalFloat32Array: 704 case kExternalFloat32Array:
605 case kExternalFloat64Array: 705 case kExternalFloat64Array:
606 default: 706 default:
607 break; 707 break;
608 } 708 }
609 709
610 UNREACHABLE(); 710 UNREACHABLE();
611 return isolate->heap()->undefined_value(); 711 return isolate->heap()->undefined_value();
612 } 712 }
613 713
(...skipping 10 matching lines...) Expand all
624 void* buffer = sta->GetBuffer()->backing_store(); 724 void* buffer = sta->GetBuffer()->backing_store();
625 725
626 switch (sta->type()) { 726 switch (sta->type()) {
627 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 727 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
628 case kExternal##Type##Array: \ 728 case kExternal##Type##Array: \
629 return DoOr<ctype>(isolate, buffer, index, value); 729 return DoOr<ctype>(isolate, buffer, index, value);
630 730
631 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 731 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
632 #undef TYPED_ARRAY_CASE 732 #undef TYPED_ARRAY_CASE
633 733
734 case kExternalUint8ClampedArray:
735 return DoOrUint8Clamped(isolate, buffer, index, value);
736
634 case kExternalFloat32Array: 737 case kExternalFloat32Array:
635 case kExternalFloat64Array: 738 case kExternalFloat64Array:
636 default: 739 default:
637 break; 740 break;
638 } 741 }
639 742
640 UNREACHABLE(); 743 UNREACHABLE();
641 return isolate->heap()->undefined_value(); 744 return isolate->heap()->undefined_value();
642 } 745 }
643 746
(...skipping 10 matching lines...) Expand all
654 void* buffer = sta->GetBuffer()->backing_store(); 757 void* buffer = sta->GetBuffer()->backing_store();
655 758
656 switch (sta->type()) { 759 switch (sta->type()) {
657 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 760 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
658 case kExternal##Type##Array: \ 761 case kExternal##Type##Array: \
659 return DoXor<ctype>(isolate, buffer, index, value); 762 return DoXor<ctype>(isolate, buffer, index, value);
660 763
661 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 764 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
662 #undef TYPED_ARRAY_CASE 765 #undef TYPED_ARRAY_CASE
663 766
767 case kExternalUint8ClampedArray:
768 return DoXorUint8Clamped(isolate, buffer, index, value);
769
664 case kExternalFloat32Array: 770 case kExternalFloat32Array:
665 case kExternalFloat64Array: 771 case kExternalFloat64Array:
666 default: 772 default:
667 break; 773 break;
668 } 774 }
669 775
670 UNREACHABLE(); 776 UNREACHABLE();
671 return isolate->heap()->undefined_value(); 777 return isolate->heap()->undefined_value();
672 } 778 }
673 779
(...skipping 10 matching lines...) Expand all
684 void* buffer = sta->GetBuffer()->backing_store(); 790 void* buffer = sta->GetBuffer()->backing_store();
685 791
686 switch (sta->type()) { 792 switch (sta->type()) {
687 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \ 793 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
688 case kExternal##Type##Array: \ 794 case kExternal##Type##Array: \
689 return DoExchange<ctype>(isolate, buffer, index, value); 795 return DoExchange<ctype>(isolate, buffer, index, value);
690 796
691 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE) 797 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
692 #undef TYPED_ARRAY_CASE 798 #undef TYPED_ARRAY_CASE
693 799
800 case kExternalUint8ClampedArray:
801 return DoExchangeUint8Clamped(isolate, buffer, index, value);
802
694 case kExternalFloat32Array: 803 case kExternalFloat32Array:
695 case kExternalFloat64Array: 804 case kExternalFloat64Array:
696 default: 805 default:
697 break; 806 break;
698 } 807 }
699 808
700 UNREACHABLE(); 809 UNREACHABLE();
701 return isolate->heap()->undefined_value(); 810 return isolate->heap()->undefined_value();
702 } 811 }
703 812
704 813
705 RUNTIME_FUNCTION(Runtime_AtomicsIsLockFree) { 814 RUNTIME_FUNCTION(Runtime_AtomicsIsLockFree) {
706 HandleScope scope(isolate); 815 HandleScope scope(isolate);
707 DCHECK(args.length() == 1); 816 DCHECK(args.length() == 1);
708 CONVERT_NUMBER_ARG_HANDLE_CHECKED(size, 0); 817 CONVERT_NUMBER_ARG_HANDLE_CHECKED(size, 0);
709 uint32_t usize = NumberToUint32(*size); 818 uint32_t usize = NumberToUint32(*size);
710 819
711 return Runtime::AtomicIsLockFree(usize) ? isolate->heap()->true_value() 820 return Runtime::AtomicIsLockFree(usize) ? isolate->heap()->true_value()
712 : isolate->heap()->false_value(); 821 : isolate->heap()->false_value();
713 } 822 }
714 } 823 }
715 } // namespace v8::internal 824 } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/harmony/atomics.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698