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

Side by Side Diff: src/elements.cc

Issue 1224643004: Index -> Entry and Key -> Index in elements.[cc|h] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/conversions.h" 8 #include "src/conversions.h"
9 #include "src/elements.h" 9 #include "src/elements.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 #define ELEMENTS_TRAITS(Class, KindParam, Store) \ 116 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
117 template<> class ElementsKindTraits<KindParam> { \ 117 template<> class ElementsKindTraits<KindParam> { \
118 public: /* NOLINT */ \ 118 public: /* NOLINT */ \
119 static const ElementsKind Kind = KindParam; \ 119 static const ElementsKind Kind = KindParam; \
120 typedef Store BackingStore; \ 120 typedef Store BackingStore; \
121 }; 121 };
122 ELEMENTS_LIST(ELEMENTS_TRAITS) 122 ELEMENTS_LIST(ELEMENTS_TRAITS)
123 #undef ELEMENTS_TRAITS 123 #undef ELEMENTS_TRAITS
124 124
125 125
126 static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) { 126 static bool HasIndex(Handle<FixedArray> array, Handle<Object> index_handle) {
127 DisallowHeapAllocation no_gc; 127 DisallowHeapAllocation no_gc;
128 Object* key = *key_handle; 128 Object* index = *index_handle;
129 int len0 = array->length(); 129 int len0 = array->length();
130 for (int i = 0; i < len0; i++) { 130 for (int i = 0; i < len0; i++) {
131 Object* element = array->get(i); 131 Object* element = array->get(i);
132 if (key->KeyEquals(element)) return true; 132 if (index->KeyEquals(element)) return true;
133 } 133 }
134 return false; 134 return false;
135 } 135 }
136 136
137 137
138 MUST_USE_RESULT 138 MUST_USE_RESULT
139 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { 139 static MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
140 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength), 140 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength),
141 Object); 141 Object);
142 } 142 }
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 length = fixed_array_base->length(); 535 length = fixed_array_base->length();
536 } 536 }
537 ElementsAccessorSubclass::ValidateContents(holder, length); 537 ElementsAccessorSubclass::ValidateContents(holder, length);
538 } 538 }
539 539
540 void Validate(Handle<JSObject> holder) final { 540 void Validate(Handle<JSObject> holder) final {
541 DisallowHeapAllocation no_gc; 541 DisallowHeapAllocation no_gc;
542 ElementsAccessorSubclass::ValidateImpl(holder); 542 ElementsAccessorSubclass::ValidateImpl(holder);
543 } 543 }
544 544
545 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, 545 virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
546 Handle<FixedArrayBase> backing_store) final { 546 Handle<FixedArrayBase> backing_store) final {
547 return ElementsAccessorSubclass::GetIndexForKeyImpl(*holder, *backing_store, 547 return ElementsAccessorSubclass::GetEntryForIndexImpl(
548 key) != kMaxUInt32; 548 *holder, *backing_store, index) != kMaxUInt32;
549 } 549 }
550 550
551 virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key, 551 virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t index,
552 Handle<FixedArrayBase> backing_store) final { 552 Handle<FixedArrayBase> backing_store) final {
553 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && 553 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
554 FLAG_trace_js_array_abuse) { 554 FLAG_trace_js_array_abuse) {
555 CheckArrayAbuse(holder, "elements read", key); 555 CheckArrayAbuse(holder, "elements read", index);
556 } 556 }
557 557
558 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && 558 if (IsExternalArrayElementsKind(ElementsTraits::Kind) &&
559 FLAG_trace_external_array_abuse) { 559 FLAG_trace_external_array_abuse) {
560 CheckArrayAbuse(holder, "external elements read", key); 560 CheckArrayAbuse(holder, "external elements read", index);
561 } 561 }
562 562
563 return ElementsAccessorSubclass::GetImpl(holder, key, backing_store); 563 return ElementsAccessorSubclass::GetImpl(holder, index, backing_store);
564 } 564 }
565 565
566 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 566 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
567 Handle<FixedArrayBase> backing_store) { 567 Handle<FixedArrayBase> backing_store) {
568 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { 568 if (index <
569 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 569 ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
570 return BackingStore::get(Handle<BackingStore>::cast(backing_store),
571 index);
570 } else { 572 } else {
571 return backing_store->GetIsolate()->factory()->the_hole_value(); 573 return backing_store->GetIsolate()->factory()->the_hole_value();
572 } 574 }
573 } 575 }
574 576
575 virtual void Set(FixedArrayBase* backing_store, uint32_t key, 577 virtual void Set(FixedArrayBase* backing_store, uint32_t index,
576 Object* value) final { 578 Object* value) final {
577 ElementsAccessorSubclass::SetImpl(backing_store, key, value); 579 ElementsAccessorSubclass::SetImpl(backing_store, index, value);
578 } 580 }
579 581
580 static void SetImpl(FixedArrayBase* backing_store, uint32_t key, 582 static void SetImpl(FixedArrayBase* backing_store, uint32_t index,
581 Object* value) { 583 Object* value) {
582 BackingStore::cast(backing_store)->SetValue(key, value); 584 BackingStore::cast(backing_store)->SetValue(index, value);
583 } 585 }
584 586
585 virtual void Reconfigure(Handle<JSObject> object, 587 virtual void Reconfigure(Handle<JSObject> object,
586 Handle<FixedArrayBase> store, uint32_t index, 588 Handle<FixedArrayBase> store, uint32_t entry,
587 Handle<Object> value, 589 Handle<Object> value,
588 PropertyAttributes attributes) final { 590 PropertyAttributes attributes) final {
589 ElementsAccessorSubclass::ReconfigureImpl(object, store, index, value, 591 ElementsAccessorSubclass::ReconfigureImpl(object, store, entry, value,
590 attributes); 592 attributes);
591 } 593 }
592 594
593 static void ReconfigureImpl(Handle<JSObject> object, 595 static void ReconfigureImpl(Handle<JSObject> object,
594 Handle<FixedArrayBase> store, uint32_t index, 596 Handle<FixedArrayBase> store, uint32_t entry,
595 Handle<Object> value, 597 Handle<Object> value,
596 PropertyAttributes attributes) { 598 PropertyAttributes attributes) {
597 UNREACHABLE(); 599 UNREACHABLE();
598 } 600 }
599 601
600 virtual void Add(Handle<JSObject> object, uint32_t index, 602 virtual void Add(Handle<JSObject> object, uint32_t entry,
601 Handle<Object> value, PropertyAttributes attributes, 603 Handle<Object> value, PropertyAttributes attributes,
602 uint32_t new_capacity) final { 604 uint32_t new_capacity) final {
603 ElementsAccessorSubclass::AddImpl(object, index, value, attributes, 605 ElementsAccessorSubclass::AddImpl(object, entry, value, attributes,
604 new_capacity); 606 new_capacity);
605 } 607 }
606 608
607 static void AddImpl(Handle<JSObject> object, uint32_t index, 609 static void AddImpl(Handle<JSObject> object, uint32_t entry,
608 Handle<Object> value, PropertyAttributes attributes, 610 Handle<Object> value, PropertyAttributes attributes,
609 uint32_t new_capacity) { 611 uint32_t new_capacity) {
610 UNREACHABLE(); 612 UNREACHABLE();
611 } 613 }
612 614
613 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { 615 virtual void SetLength(Handle<JSArray> array, uint32_t length) final {
614 ElementsAccessorSubclass::SetLengthImpl(array, length, 616 ElementsAccessorSubclass::SetLengthImpl(array, length,
615 handle(array->elements())); 617 handle(array->elements()));
616 } 618 }
617 619
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements, 673 JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements,
672 to_kind, elements); 674 to_kind, elements);
673 } 675 }
674 } 676 }
675 677
676 virtual void GrowCapacityAndConvert(Handle<JSObject> object, 678 virtual void GrowCapacityAndConvert(Handle<JSObject> object,
677 uint32_t capacity) final { 679 uint32_t capacity) final {
678 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, capacity); 680 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, capacity);
679 } 681 }
680 682
681 virtual void Delete(Handle<JSObject> obj, uint32_t index) final { 683 virtual void Delete(Handle<JSObject> obj, uint32_t entry) final {
682 ElementsAccessorSubclass::DeleteImpl(obj, index); 684 ElementsAccessorSubclass::DeleteImpl(obj, entry);
683 } 685 }
684 686
685 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 687 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
686 FixedArrayBase* to, ElementsKind from_kind, 688 FixedArrayBase* to, ElementsKind from_kind,
687 uint32_t to_start, int packed_size, 689 uint32_t to_start, int packed_size,
688 int copy_size) { 690 int copy_size) {
689 UNREACHABLE(); 691 UNREACHABLE();
690 } 692 }
691 693
692 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, 694 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 // Optimize if 'other' is empty. 750 // Optimize if 'other' is empty.
749 // We cannot optimize if 'this' is empty, as other may have holes. 751 // We cannot optimize if 'this' is empty, as other may have holes.
750 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); 752 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
751 if (len1 == 0) return to; 753 if (len1 == 0) return to;
752 754
753 Isolate* isolate = from->GetIsolate(); 755 Isolate* isolate = from->GetIsolate();
754 756
755 // Compute how many elements are not in other. 757 // Compute how many elements are not in other.
756 uint32_t extra = 0; 758 uint32_t extra = 0;
757 for (uint32_t y = 0; y < len1; y++) { 759 for (uint32_t y = 0; y < len1; y++) {
758 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { 760 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
759 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 761 uint32_t index =
762 ElementsAccessorSubclass::GetIndexForEntryImpl(*from, y);
760 Handle<Object> value = 763 Handle<Object> value =
761 ElementsAccessorSubclass::GetImpl(receiver, key, from); 764 ElementsAccessorSubclass::GetImpl(receiver, index, from);
762 765
763 DCHECK(!value->IsTheHole()); 766 DCHECK(!value->IsTheHole());
764 DCHECK(!value->IsAccessorPair()); 767 DCHECK(!value->IsAccessorPair());
765 DCHECK(!value->IsExecutableAccessorInfo()); 768 DCHECK(!value->IsExecutableAccessorInfo());
766 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 769 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
767 continue; 770 continue;
768 } 771 }
769 if (!HasKey(to, value)) { 772 if (!HasIndex(to, value)) {
770 extra++; 773 extra++;
771 } 774 }
772 } 775 }
773 } 776 }
774 777
775 if (extra == 0) return to; 778 if (extra == 0) return to;
776 779
777 // Allocate the result 780 // Allocate the result
778 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); 781 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra);
779 782
780 // Fill in the content 783 // Fill in the content
781 { 784 {
782 DisallowHeapAllocation no_gc; 785 DisallowHeapAllocation no_gc;
783 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 786 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
784 for (int i = 0; i < len0; i++) { 787 for (int i = 0; i < len0; i++) {
785 Object* e = to->get(i); 788 Object* e = to->get(i);
786 DCHECK(e->IsString() || e->IsNumber()); 789 DCHECK(e->IsString() || e->IsNumber());
787 result->set(i, e, mode); 790 result->set(i, e, mode);
788 } 791 }
789 } 792 }
790 // Fill in the extra values. 793 // Fill in the extra values.
791 uint32_t index = 0; 794 uint32_t entry = 0;
792 for (uint32_t y = 0; y < len1; y++) { 795 for (uint32_t y = 0; y < len1; y++) {
793 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) { 796 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
794 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 797 uint32_t index =
798 ElementsAccessorSubclass::GetIndexForEntryImpl(*from, y);
795 Handle<Object> value = 799 Handle<Object> value =
796 ElementsAccessorSubclass::GetImpl(receiver, key, from); 800 ElementsAccessorSubclass::GetImpl(receiver, index, from);
797 DCHECK(!value->IsAccessorPair()); 801 DCHECK(!value->IsAccessorPair());
798 DCHECK(!value->IsExecutableAccessorInfo()); 802 DCHECK(!value->IsExecutableAccessorInfo());
799 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 803 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
800 continue; 804 continue;
801 } 805 }
802 if (!value->IsTheHole() && !HasKey(to, value)) { 806 if (!value->IsTheHole() && !HasIndex(to, value)) {
803 result->set(len0 + index, *value); 807 result->set(len0 + entry, *value);
804 index++; 808 entry++;
805 } 809 }
806 } 810 }
807 } 811 }
808 DCHECK(extra == index); 812 DCHECK(extra == entry);
809 return result; 813 return result;
810 } 814 }
811 815
812 static uint32_t GetCapacityImpl(JSObject* holder, 816 static uint32_t GetCapacityImpl(JSObject* holder,
813 FixedArrayBase* backing_store) { 817 FixedArrayBase* backing_store) {
814 return backing_store->length(); 818 return backing_store->length();
815 } 819 }
816 820
817 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 821 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
818 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 822 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
819 } 823 }
820 824
821 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { 825 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
822 return true; 826 return true;
823 } 827 }
824 828
825 virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t index) final { 829 virtual bool HasEntry(FixedArrayBase* backing_store, uint32_t entry) final {
826 return ElementsAccessorSubclass::HasIndexImpl(backing_store, index); 830 return ElementsAccessorSubclass::HasEntryImpl(backing_store, entry);
827 } 831 }
828 832
829 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, 833 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
830 uint32_t index) { 834 uint32_t entry) {
831 return index; 835 return entry;
832 } 836 }
833 837
834 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 838 static uint32_t GetEntryForIndexImpl(JSObject* holder,
835 uint32_t index) final { 839 FixedArrayBase* backing_store,
836 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); 840 uint32_t index) {
837 } 841 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
838 842 backing_store) &&
839 static uint32_t GetIndexForKeyImpl(JSObject* holder, 843 !BackingStore::cast(backing_store)->is_the_hole(index)
840 FixedArrayBase* backing_store, 844 ? index
841 uint32_t key) {
842 return key < ElementsAccessorSubclass::GetCapacityImpl(holder,
843 backing_store) &&
844 !BackingStore::cast(backing_store)->is_the_hole(key)
845 ? key
846 : kMaxUInt32; 845 : kMaxUInt32;
847 } 846 }
848 847
849 virtual uint32_t GetIndexForKey(JSObject* holder, 848 virtual uint32_t GetEntryForIndex(JSObject* holder,
850 FixedArrayBase* backing_store, 849 FixedArrayBase* backing_store,
851 uint32_t key) final { 850 uint32_t index) final {
852 return ElementsAccessorSubclass::GetIndexForKeyImpl(holder, backing_store, 851 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store,
853 key); 852 index);
854 } 853 }
855 854
856 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 855 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
857 uint32_t index) { 856 uint32_t entry) {
858 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 857 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
859 } 858 }
860 859
861 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, 860 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
862 uint32_t index) final { 861 uint32_t entry) final {
863 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index); 862 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry);
864 } 863 }
865 864
866 private: 865 private:
867 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 866 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
868 }; 867 };
869 868
870 869
871 class DictionaryElementsAccessor 870 class DictionaryElementsAccessor
872 : public ElementsAccessorBase<DictionaryElementsAccessor, 871 : public ElementsAccessorBase<DictionaryElementsAccessor,
873 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 872 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
874 public: 873 public:
875 explicit DictionaryElementsAccessor(const char* name) 874 explicit DictionaryElementsAccessor(const char* name)
876 : ElementsAccessorBase<DictionaryElementsAccessor, 875 : ElementsAccessorBase<DictionaryElementsAccessor,
877 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 876 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
878 877
879 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 878 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
880 Handle<FixedArrayBase> backing_store) { 879 Handle<FixedArrayBase> backing_store) {
881 Handle<SeededNumberDictionary> dict = 880 Handle<SeededNumberDictionary> dict =
882 Handle<SeededNumberDictionary>::cast(backing_store); 881 Handle<SeededNumberDictionary>::cast(backing_store);
883 Isolate* isolate = array->GetIsolate(); 882 Isolate* isolate = array->GetIsolate();
884 int capacity = dict->Capacity(); 883 int capacity = dict->Capacity();
885 uint32_t old_length = 0; 884 uint32_t old_length = 0;
886 CHECK(array->length()->ToArrayLength(&old_length)); 885 CHECK(array->length()->ToArrayLength(&old_length));
887 if (length < old_length) { 886 if (length < old_length) {
888 if (dict->requires_slow_elements()) { 887 if (dict->requires_slow_elements()) {
889 // Find last non-deletable element in range of elements to be 888 // Find last non-deletable element in range of elements to be
890 // deleted and adjust range accordingly. 889 // deleted and adjust range accordingly.
891 for (int i = 0; i < capacity; i++) { 890 for (int i = 0; i < capacity; i++) {
Igor Sheludko 2015/07/07 11:01:42 i -> entry?
892 DisallowHeapAllocation no_gc; 891 DisallowHeapAllocation no_gc;
893 Object* key = dict->KeyAt(i); 892 Object* index = dict->KeyAt(i);
894 if (key->IsNumber()) { 893 if (index->IsNumber()) {
895 uint32_t number = static_cast<uint32_t>(key->Number()); 894 uint32_t number = static_cast<uint32_t>(index->Number());
896 if (length <= number && number < old_length) { 895 if (length <= number && number < old_length) {
897 PropertyDetails details = dict->DetailsAt(i); 896 PropertyDetails details = dict->DetailsAt(i);
898 if (!details.IsConfigurable()) length = number + 1; 897 if (!details.IsConfigurable()) length = number + 1;
899 } 898 }
900 } 899 }
901 } 900 }
902 } 901 }
903 902
904 if (length == 0) { 903 if (length == 0) {
905 // Flush the backing store. 904 // Flush the backing store.
906 JSObject::ResetElements(array); 905 JSObject::ResetElements(array);
907 } else { 906 } else {
908 DisallowHeapAllocation no_gc; 907 DisallowHeapAllocation no_gc;
909 // Remove elements that should be deleted. 908 // Remove elements that should be deleted.
910 int removed_entries = 0; 909 int removed_entries = 0;
911 Handle<Object> the_hole_value = isolate->factory()->the_hole_value(); 910 Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
912 for (int i = 0; i < capacity; i++) { 911 for (int i = 0; i < capacity; i++) {
Igor Sheludko 2015/07/07 11:01:42 i -> entry?
913 Object* key = dict->KeyAt(i); 912 Object* index = dict->KeyAt(i);
914 if (key->IsNumber()) { 913 if (index->IsNumber()) {
915 uint32_t number = static_cast<uint32_t>(key->Number()); 914 uint32_t number = static_cast<uint32_t>(index->Number());
916 if (length <= number && number < old_length) { 915 if (length <= number && number < old_length) {
917 dict->SetEntry(i, the_hole_value, the_hole_value); 916 dict->SetEntry(i, the_hole_value, the_hole_value);
918 removed_entries++; 917 removed_entries++;
919 } 918 }
920 } 919 }
921 } 920 }
922 921
923 // Update the number of elements. 922 // Update the number of elements.
924 dict->ElementsRemoved(removed_entries); 923 dict->ElementsRemoved(removed_entries);
925 } 924 }
926 } 925 }
927 926
928 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); 927 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
929 array->set_length(*length_obj); 928 array->set_length(*length_obj);
930 } 929 }
931 930
932 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 931 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
933 FixedArrayBase* to, ElementsKind from_kind, 932 FixedArrayBase* to, ElementsKind from_kind,
934 uint32_t to_start, int packed_size, 933 uint32_t to_start, int packed_size,
935 int copy_size) { 934 int copy_size) {
936 UNREACHABLE(); 935 UNREACHABLE();
937 } 936 }
938 937
939 938
940 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 939 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
941 // TODO(verwaest): Remove reliance on key in Shrink. 940 // TODO(verwaest): Remove reliance on index in Shrink.
942 Handle<SeededNumberDictionary> dict( 941 Handle<SeededNumberDictionary> dict(
943 SeededNumberDictionary::cast(obj->elements())); 942 SeededNumberDictionary::cast(obj->elements()));
944 uint32_t key = GetKeyForIndexImpl(*dict, index); 943 uint32_t index = GetIndexForEntryImpl(*dict, entry);
945 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); 944 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
946 USE(result); 945 USE(result);
947 DCHECK(result->IsTrue()); 946 DCHECK(result->IsTrue());
948 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); 947 Handle<FixedArray> new_elements =
948 SeededNumberDictionary::Shrink(dict, index);
949 obj->set_elements(*new_elements); 949 obj->set_elements(*new_elements);
950 } 950 }
951 951
952 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 952 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
953 Handle<FixedArrayBase> store) { 953 Handle<FixedArrayBase> store) {
954 Handle<SeededNumberDictionary> backing_store = 954 Handle<SeededNumberDictionary> backing_store =
955 Handle<SeededNumberDictionary>::cast(store); 955 Handle<SeededNumberDictionary>::cast(store);
956 Isolate* isolate = backing_store->GetIsolate(); 956 Isolate* isolate = backing_store->GetIsolate();
957 int entry = backing_store->FindEntry(key); 957 int entry = backing_store->FindEntry(index);
958 if (entry != SeededNumberDictionary::kNotFound) { 958 if (entry != SeededNumberDictionary::kNotFound) {
959 return handle(backing_store->ValueAt(entry), isolate); 959 return handle(backing_store->ValueAt(entry), isolate);
960 } 960 }
961 return isolate->factory()->the_hole_value(); 961 return isolate->factory()->the_hole_value();
962 } 962 }
963 963
964 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 964 static void SetImpl(FixedArrayBase* store, uint32_t index, Object* value) {
965 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 965 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
966 int entry = dictionary->FindEntry(key); 966 int entry = dictionary->FindEntry(index);
967 DCHECK_NE(SeededNumberDictionary::kNotFound, entry); 967 DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
968 dictionary->ValueAtPut(entry, value); 968 dictionary->ValueAtPut(entry, value);
969 } 969 }
970 970
971 static void ReconfigureImpl(Handle<JSObject> object, 971 static void ReconfigureImpl(Handle<JSObject> object,
972 Handle<FixedArrayBase> store, uint32_t index, 972 Handle<FixedArrayBase> store, uint32_t entry,
973 Handle<Object> value, 973 Handle<Object> value,
974 PropertyAttributes attributes) { 974 PropertyAttributes attributes) {
975 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); 975 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
976 if (attributes != NONE) dictionary->set_requires_slow_elements(); 976 if (attributes != NONE) dictionary->set_requires_slow_elements();
977 dictionary->ValueAtPut(index, *value); 977 dictionary->ValueAtPut(entry, *value);
978 PropertyDetails details = dictionary->DetailsAt(index); 978 PropertyDetails details = dictionary->DetailsAt(entry);
979 details = PropertyDetails(attributes, DATA, details.dictionary_index(), 979 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
980 PropertyCellType::kNoCell); 980 PropertyCellType::kNoCell);
981 dictionary->DetailsAtPut(index, details); 981 dictionary->DetailsAtPut(entry, details);
982 } 982 }
983 983
984 static void AddImpl(Handle<JSObject> object, uint32_t index, 984 static void AddImpl(Handle<JSObject> object, uint32_t entry,
985 Handle<Object> value, PropertyAttributes attributes, 985 Handle<Object> value, PropertyAttributes attributes,
986 uint32_t new_capacity) { 986 uint32_t new_capacity) {
987 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 987 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
988 Handle<SeededNumberDictionary> dictionary = 988 Handle<SeededNumberDictionary> dictionary =
989 object->HasFastElements() 989 object->HasFastElements()
990 ? JSObject::NormalizeElements(object) 990 ? JSObject::NormalizeElements(object)
991 : handle(SeededNumberDictionary::cast(object->elements())); 991 : handle(SeededNumberDictionary::cast(object->elements()));
992 Handle<SeededNumberDictionary> new_dictionary = 992 Handle<SeededNumberDictionary> new_dictionary =
993 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 993 SeededNumberDictionary::AddNumberEntry(dictionary, entry, value,
994 details); 994 details);
995 if (attributes != NONE) new_dictionary->set_requires_slow_elements(); 995 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
996 if (dictionary.is_identical_to(new_dictionary)) return; 996 if (dictionary.is_identical_to(new_dictionary)) return;
997 object->set_elements(*new_dictionary); 997 object->set_elements(*new_dictionary);
998 } 998 }
999 999
1000 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { 1000 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) {
1001 DisallowHeapAllocation no_gc; 1001 DisallowHeapAllocation no_gc;
1002 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1002 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1003 Object* key = dict->KeyAt(index); 1003 Object* index = dict->KeyAt(entry);
1004 return !key->IsTheHole(); 1004 return !index->IsTheHole();
1005 } 1005 }
1006 1006
1007 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { 1007 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) {
1008 DisallowHeapAllocation no_gc; 1008 DisallowHeapAllocation no_gc;
1009 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1009 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1010 uint32_t result = 0; 1010 uint32_t result = 0;
1011 CHECK(dict->KeyAt(index)->ToArrayIndex(&result)); 1011 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result));
1012 return result; 1012 return result;
1013 } 1013 }
1014 1014
1015 static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store, 1015 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store,
1016 uint32_t key) { 1016 uint32_t index) {
1017 DisallowHeapAllocation no_gc; 1017 DisallowHeapAllocation no_gc;
1018 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1018 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1019 int entry = dict->FindEntry(key); 1019 int entry = dict->FindEntry(index);
1020 return entry == SeededNumberDictionary::kNotFound 1020 return entry == SeededNumberDictionary::kNotFound
1021 ? kMaxUInt32 1021 ? kMaxUInt32
1022 : static_cast<uint32_t>(entry); 1022 : static_cast<uint32_t>(entry);
1023 } 1023 }
1024 1024
1025 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1025 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1026 uint32_t index) { 1026 uint32_t entry) {
1027 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); 1027 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1028 } 1028 }
1029 }; 1029 };
1030 1030
1031 1031
1032 // Super class for all fast element arrays. 1032 // Super class for all fast element arrays.
1033 template<typename FastElementsAccessorSubclass, 1033 template<typename FastElementsAccessorSubclass,
1034 typename KindTraits> 1034 typename KindTraits>
1035 class FastElementsAccessor 1035 class FastElementsAccessor
1036 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 1036 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
1037 public: 1037 public:
1038 explicit FastElementsAccessor(const char* name) 1038 explicit FastElementsAccessor(const char* name)
1039 : ElementsAccessorBase<FastElementsAccessorSubclass, 1039 : ElementsAccessorBase<FastElementsAccessorSubclass,
1040 KindTraits>(name) {} 1040 KindTraits>(name) {}
1041 1041
1042 typedef typename KindTraits::BackingStore BackingStore; 1042 typedef typename KindTraits::BackingStore BackingStore;
1043 1043
1044 static void DeleteCommon(Handle<JSObject> obj, uint32_t index, 1044 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry,
1045 Handle<FixedArrayBase> store) { 1045 Handle<FixedArrayBase> store) {
1046 DCHECK(obj->HasFastSmiOrObjectElements() || 1046 DCHECK(obj->HasFastSmiOrObjectElements() ||
1047 obj->HasFastDoubleElements() || 1047 obj->HasFastDoubleElements() ||
1048 obj->HasFastArgumentsElements()); 1048 obj->HasFastArgumentsElements());
1049 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); 1049 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store);
1050 backing_store->set_the_hole(index); 1050 backing_store->set_the_hole(entry);
1051 1051
1052 // TODO(verwaest): Move this out of elements.cc. 1052 // TODO(verwaest): Move this out of elements.cc.
1053 // If an old space backing store is larger than a certain size and 1053 // If an old space backing store is larger than a certain size and
1054 // has too few used values, normalize it. 1054 // has too few used values, normalize it.
1055 // To avoid doing the check on every delete we require at least 1055 // To avoid doing the check on every delete we require at least
1056 // one adjacent hole to the value being deleted. 1056 // one adjacent hole to the value being deleted.
1057 const int kMinLengthForSparsenessCheck = 64; 1057 const int kMinLengthForSparsenessCheck = 64;
1058 if (backing_store->length() < kMinLengthForSparsenessCheck) return; 1058 if (backing_store->length() < kMinLengthForSparsenessCheck) return;
1059 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; 1059 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return;
1060 uint32_t length = 0; 1060 uint32_t length = 0;
1061 if (obj->IsJSArray()) { 1061 if (obj->IsJSArray()) {
1062 JSArray::cast(*obj)->length()->ToArrayLength(&length); 1062 JSArray::cast(*obj)->length()->ToArrayLength(&length);
1063 } else { 1063 } else {
1064 length = static_cast<uint32_t>(store->length()); 1064 length = static_cast<uint32_t>(store->length());
1065 } 1065 }
1066 if ((index > 0 && backing_store->is_the_hole(index - 1)) || 1066 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) ||
1067 (index + 1 < length && backing_store->is_the_hole(index + 1))) { 1067 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) {
1068 int num_used = 0; 1068 int num_used = 0;
1069 for (int i = 0; i < backing_store->length(); ++i) { 1069 for (int i = 0; i < backing_store->length(); ++i) {
1070 if (!backing_store->is_the_hole(i)) ++num_used; 1070 if (!backing_store->is_the_hole(i)) ++num_used;
1071 // Bail out early if more than 1/4 is used. 1071 // Bail out early if more than 1/4 is used.
1072 if (4 * num_used > backing_store->length()) break; 1072 if (4 * num_used > backing_store->length()) break;
1073 } 1073 }
1074 if (4 * num_used <= backing_store->length()) { 1074 if (4 * num_used <= backing_store->length()) {
1075 JSObject::NormalizeElements(obj); 1075 JSObject::NormalizeElements(obj);
1076 } 1076 }
1077 } 1077 }
1078 } 1078 }
1079 1079
1080 static void ReconfigureImpl(Handle<JSObject> object, 1080 static void ReconfigureImpl(Handle<JSObject> object,
1081 Handle<FixedArrayBase> store, uint32_t index, 1081 Handle<FixedArrayBase> store, uint32_t entry,
1082 Handle<Object> value, 1082 Handle<Object> value,
1083 PropertyAttributes attributes) { 1083 PropertyAttributes attributes) {
1084 Handle<SeededNumberDictionary> dictionary = 1084 Handle<SeededNumberDictionary> dictionary =
1085 JSObject::NormalizeElements(object); 1085 JSObject::NormalizeElements(object);
1086 index = dictionary->FindEntry(index); 1086 entry = dictionary->FindEntry(entry);
1087 DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, index, 1087 DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, entry,
1088 value, attributes); 1088 value, attributes);
1089 } 1089 }
1090 1090
1091 static void AddImpl(Handle<JSObject> object, uint32_t index, 1091 static void AddImpl(Handle<JSObject> object, uint32_t entry,
1092 Handle<Object> value, PropertyAttributes attributes, 1092 Handle<Object> value, PropertyAttributes attributes,
1093 uint32_t new_capacity) { 1093 uint32_t new_capacity) {
1094 DCHECK_EQ(NONE, attributes); 1094 DCHECK_EQ(NONE, attributes);
1095 ElementsKind from_kind = object->GetElementsKind(); 1095 ElementsKind from_kind = object->GetElementsKind();
1096 ElementsKind to_kind = FastElementsAccessorSubclass::kind(); 1096 ElementsKind to_kind = FastElementsAccessorSubclass::kind();
1097 if (IsDictionaryElementsKind(from_kind) || 1097 if (IsDictionaryElementsKind(from_kind) ||
1098 IsFastDoubleElementsKind(from_kind) != 1098 IsFastDoubleElementsKind(from_kind) !=
1099 IsFastDoubleElementsKind(to_kind) || 1099 IsFastDoubleElementsKind(to_kind) ||
1100 FastElementsAccessorSubclass::GetCapacityImpl( 1100 FastElementsAccessorSubclass::GetCapacityImpl(
1101 *object, object->elements()) != new_capacity) { 1101 *object, object->elements()) != new_capacity) {
1102 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, 1102 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object,
1103 new_capacity); 1103 new_capacity);
1104 } else { 1104 } else {
1105 if (from_kind != to_kind) { 1105 if (from_kind != to_kind) {
1106 JSObject::TransitionElementsKind(object, to_kind); 1106 JSObject::TransitionElementsKind(object, to_kind);
1107 } 1107 }
1108 if (IsFastSmiOrObjectElementsKind(from_kind)) { 1108 if (IsFastSmiOrObjectElementsKind(from_kind)) {
1109 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 1109 DCHECK(IsFastSmiOrObjectElementsKind(to_kind));
1110 JSObject::EnsureWritableFastElements(object); 1110 JSObject::EnsureWritableFastElements(object);
1111 } 1111 }
1112 } 1112 }
1113 FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); 1113 FastElementsAccessorSubclass::SetImpl(object->elements(), entry, *value);
1114 } 1114 }
1115 1115
1116 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1116 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1117 ElementsKind kind = KindTraits::Kind; 1117 ElementsKind kind = KindTraits::Kind;
1118 if (IsFastPackedElementsKind(kind)) { 1118 if (IsFastPackedElementsKind(kind)) {
1119 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 1119 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
1120 } 1120 }
1121 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1121 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1122 JSObject::EnsureWritableFastElements(obj); 1122 JSObject::EnsureWritableFastElements(obj);
1123 } 1123 }
1124 DeleteCommon(obj, index, handle(obj->elements())); 1124 DeleteCommon(obj, entry, handle(obj->elements()));
1125 } 1125 }
1126 1126
1127 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { 1127 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
1128 return !BackingStore::cast(backing_store)->is_the_hole(index); 1128 return !BackingStore::cast(backing_store)->is_the_hole(entry);
1129 } 1129 }
1130 1130
1131 static void ValidateContents(Handle<JSObject> holder, int length) { 1131 static void ValidateContents(Handle<JSObject> holder, int length) {
1132 #if DEBUG 1132 #if DEBUG
1133 Isolate* isolate = holder->GetIsolate(); 1133 Isolate* isolate = holder->GetIsolate();
1134 HandleScope scope(isolate); 1134 HandleScope scope(isolate);
1135 Handle<FixedArrayBase> elements(holder->elements(), isolate); 1135 Handle<FixedArrayBase> elements(holder->elements(), isolate);
1136 Map* map = elements->map(); 1136 Map* map = elements->map();
1137 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 1137 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
1138 (map == isolate->heap()->fixed_array_map() || 1138 (map == isolate->heap()->fixed_array_map() ||
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 1335 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1336 ElementsKindTraits<Kind> > { 1336 ElementsKindTraits<Kind> > {
1337 public: 1337 public:
1338 explicit TypedElementsAccessor(const char* name) 1338 explicit TypedElementsAccessor(const char* name)
1339 : ElementsAccessorBase<AccessorClass, 1339 : ElementsAccessorBase<AccessorClass,
1340 ElementsKindTraits<Kind> >(name) {} 1340 ElementsKindTraits<Kind> >(name) {}
1341 1341
1342 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1342 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1343 typedef TypedElementsAccessor<Kind> AccessorClass; 1343 typedef TypedElementsAccessor<Kind> AccessorClass;
1344 1344
1345 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1345 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
1346 Handle<FixedArrayBase> backing_store) { 1346 Handle<FixedArrayBase> backing_store) {
1347 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1347 if (index < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
1348 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 1348 return BackingStore::get(Handle<BackingStore>::cast(backing_store),
1349 index);
1349 } else { 1350 } else {
1350 return backing_store->GetIsolate()->factory()->undefined_value(); 1351 return backing_store->GetIsolate()->factory()->undefined_value();
1351 } 1352 }
1352 } 1353 }
1353 1354
1354 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1355 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1355 uint32_t index) { 1356 uint32_t entry) {
1356 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 1357 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1357 } 1358 }
1358 1359
1359 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1360 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1360 Handle<FixedArrayBase> backing_store) { 1361 Handle<FixedArrayBase> backing_store) {
1361 // External arrays do not support changing their length. 1362 // External arrays do not support changing their length.
1362 UNREACHABLE(); 1363 UNREACHABLE();
1363 } 1364 }
1364 1365
1365 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1366 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1366 UNREACHABLE(); 1367 UNREACHABLE();
1367 } 1368 }
1368 1369
1369 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1370 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1370 FixedArrayBase* backing_store, 1371 FixedArrayBase* backing_store,
1371 uint32_t key) { 1372 uint32_t index) {
1372 return key < AccessorClass::GetCapacityImpl(holder, backing_store) 1373 return index < AccessorClass::GetCapacityImpl(holder, backing_store)
1373 ? key 1374 ? index
1374 : kMaxUInt32; 1375 : kMaxUInt32;
1375 } 1376 }
1376 1377
1377 static uint32_t GetCapacityImpl(JSObject* holder, 1378 static uint32_t GetCapacityImpl(JSObject* holder,
1378 FixedArrayBase* backing_store) { 1379 FixedArrayBase* backing_store) {
1379 JSArrayBufferView* view = JSArrayBufferView::cast(holder); 1380 JSArrayBufferView* view = JSArrayBufferView::cast(holder);
1380 if (view->WasNeutered()) return 0; 1381 if (view->WasNeutered()) return 0;
1381 return backing_store->length(); 1382 return backing_store->length();
1382 } 1383 }
1383 }; 1384 };
(...skipping 18 matching lines...) Expand all
1402 template <typename SloppyArgumentsElementsAccessorSubclass, 1403 template <typename SloppyArgumentsElementsAccessorSubclass,
1403 typename ArgumentsAccessor, typename KindTraits> 1404 typename ArgumentsAccessor, typename KindTraits>
1404 class SloppyArgumentsElementsAccessor 1405 class SloppyArgumentsElementsAccessor
1405 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1406 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1406 KindTraits> { 1407 KindTraits> {
1407 public: 1408 public:
1408 explicit SloppyArgumentsElementsAccessor(const char* name) 1409 explicit SloppyArgumentsElementsAccessor(const char* name)
1409 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1410 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1410 KindTraits>(name) {} 1411 KindTraits>(name) {}
1411 1412
1412 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1413 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
1413 Handle<FixedArrayBase> parameters) { 1414 Handle<FixedArrayBase> parameters) {
1414 Isolate* isolate = obj->GetIsolate(); 1415 Isolate* isolate = obj->GetIsolate();
1415 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1416 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1416 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1417 Handle<Object> probe(GetParameterMapArg(*parameter_map, index), isolate);
1417 if (!probe->IsTheHole()) { 1418 if (!probe->IsTheHole()) {
1418 DisallowHeapAllocation no_gc; 1419 DisallowHeapAllocation no_gc;
1419 Context* context = Context::cast(parameter_map->get(0)); 1420 Context* context = Context::cast(parameter_map->get(0));
1420 int context_index = Handle<Smi>::cast(probe)->value(); 1421 int context_entry = Handle<Smi>::cast(probe)->value();
1421 DCHECK(!context->get(context_index)->IsTheHole()); 1422 DCHECK(!context->get(context_entry)->IsTheHole());
1422 return handle(context->get(context_index), isolate); 1423 return handle(context->get(context_entry), isolate);
1423 } else { 1424 } else {
1424 // Object is not mapped, defer to the arguments. 1425 // Object is not mapped, defer to the arguments.
1425 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1426 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1426 isolate); 1427 isolate);
1427 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments); 1428 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, index, arguments);
1428 // Elements of the arguments object in slow mode might be slow aliases. 1429 // Elements of the arguments object in slow mode might be slow aliases.
1429 if (result->IsAliasedArgumentsEntry()) { 1430 if (result->IsAliasedArgumentsEntry()) {
1430 DisallowHeapAllocation no_gc; 1431 DisallowHeapAllocation no_gc;
1431 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1432 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1432 Context* context = Context::cast(parameter_map->get(0)); 1433 Context* context = Context::cast(parameter_map->get(0));
1433 int context_index = entry->aliased_context_slot(); 1434 int context_entry = entry->aliased_context_slot();
1434 DCHECK(!context->get(context_index)->IsTheHole()); 1435 DCHECK(!context->get(context_entry)->IsTheHole());
1435 return handle(context->get(context_index), isolate); 1436 return handle(context->get(context_entry), isolate);
1436 } else { 1437 } else {
1437 return result; 1438 return result;
1438 } 1439 }
1439 } 1440 }
1440 } 1441 }
1441 1442
1442 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1443 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1443 uint32_t capacity) { 1444 uint32_t capacity) {
1444 UNREACHABLE(); 1445 UNREACHABLE();
1445 } 1446 }
1446 1447
1447 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 1448 static void SetImpl(FixedArrayBase* store, uint32_t index, Object* value) {
1448 FixedArray* parameter_map = FixedArray::cast(store); 1449 FixedArray* parameter_map = FixedArray::cast(store);
1449 Object* probe = GetParameterMapArg(parameter_map, key); 1450 Object* probe = GetParameterMapArg(parameter_map, index);
1450 if (!probe->IsTheHole()) { 1451 if (!probe->IsTheHole()) {
1451 Context* context = Context::cast(parameter_map->get(0)); 1452 Context* context = Context::cast(parameter_map->get(0));
1452 int context_index = Smi::cast(probe)->value(); 1453 int context_entry = Smi::cast(probe)->value();
1453 DCHECK(!context->get(context_index)->IsTheHole()); 1454 DCHECK(!context->get(context_entry)->IsTheHole());
1454 context->set(context_index, value); 1455 context->set(context_entry, value);
1455 } else { 1456 } else {
1456 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1457 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1457 ArgumentsAccessor::SetImpl(arguments, key, value); 1458 ArgumentsAccessor::SetImpl(arguments, index, value);
1458 } 1459 }
1459 } 1460 }
1460 1461
1461 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1462 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1462 Handle<FixedArrayBase> parameter_map) { 1463 Handle<FixedArrayBase> parameter_map) {
1463 // Sloppy arguments objects are not arrays. 1464 // Sloppy arguments objects are not arrays.
1464 UNREACHABLE(); 1465 UNREACHABLE();
1465 } 1466 }
1466 1467
1467 static uint32_t GetCapacityImpl(JSObject* holder, 1468 static uint32_t GetCapacityImpl(JSObject* holder,
1468 FixedArrayBase* backing_store) { 1469 FixedArrayBase* backing_store) {
1469 FixedArray* parameter_map = FixedArray::cast(backing_store); 1470 FixedArray* parameter_map = FixedArray::cast(backing_store);
1470 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1471 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1471 return parameter_map->length() - 2 + 1472 return parameter_map->length() - 2 +
1472 ArgumentsAccessor::GetCapacityImpl(holder, arguments); 1473 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
1473 } 1474 }
1474 1475
1475 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { 1476 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) {
1476 FixedArray* parameter_map = FixedArray::cast(parameters); 1477 FixedArray* parameter_map = FixedArray::cast(parameters);
1477 uint32_t length = parameter_map->length() - 2; 1478 uint32_t length = parameter_map->length() - 2;
1478 if (index < length) { 1479 if (entry < length) {
1479 return !GetParameterMapArg(parameter_map, index)->IsTheHole(); 1480 return !GetParameterMapArg(parameter_map, entry)->IsTheHole();
1480 } 1481 }
1481 1482
1482 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1483 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1483 return ArgumentsAccessor::HasIndexImpl(arguments, index - length); 1484 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length);
1484 } 1485 }
1485 1486
1486 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, 1487 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters,
1487 uint32_t index) { 1488 uint32_t entry) {
1488 FixedArray* parameter_map = FixedArray::cast(parameters); 1489 FixedArray* parameter_map = FixedArray::cast(parameters);
1489 uint32_t length = parameter_map->length() - 2; 1490 uint32_t length = parameter_map->length() - 2;
1490 if (index < length) return index; 1491 if (entry < length) return entry;
1491 1492
1492 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1493 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1493 return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length); 1494 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length);
1494 } 1495 }
1495 1496
1496 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1497 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1497 FixedArrayBase* parameters, uint32_t key) { 1498 FixedArrayBase* parameters,
1499 uint32_t index) {
1498 FixedArray* parameter_map = FixedArray::cast(parameters); 1500 FixedArray* parameter_map = FixedArray::cast(parameters);
1499 Object* probe = GetParameterMapArg(parameter_map, key); 1501 Object* probe = GetParameterMapArg(parameter_map, index);
1500 if (!probe->IsTheHole()) return key; 1502 if (!probe->IsTheHole()) return index;
1501 1503
1502 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1504 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1503 uint32_t index = 1505 uint32_t entry =
1504 ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key); 1506 ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, index);
1505 if (index == kMaxUInt32) return index; 1507 if (entry == kMaxUInt32) return entry;
1506 return (parameter_map->length() - 2) + index; 1508 return (parameter_map->length() - 2) + entry;
1507 } 1509 }
1508 1510
1509 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 1511 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1510 uint32_t index) { 1512 uint32_t entry) {
1511 FixedArray* parameter_map = FixedArray::cast(parameters); 1513 FixedArray* parameter_map = FixedArray::cast(parameters);
1512 uint32_t length = parameter_map->length() - 2; 1514 uint32_t length = parameter_map->length() - 2;
1513 if (index < length) { 1515 if (entry < length) {
1514 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1516 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1515 } 1517 }
1516 index -= length; 1518 entry -= length;
1517 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1519 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1518 return ArgumentsAccessor::GetDetailsImpl(arguments, index); 1520 return ArgumentsAccessor::GetDetailsImpl(arguments, entry);
1519 } 1521 }
1520 1522
1521 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { 1523 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t index) {
1522 uint32_t length = parameter_map->length() - 2; 1524 uint32_t length = parameter_map->length() - 2;
1523 return key < length 1525 return index < length
1524 ? parameter_map->get(key + 2) 1526 ? parameter_map->get(index + 2)
1525 : Object::cast(parameter_map->GetHeap()->the_hole_value()); 1527 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1526 } 1528 }
1527 1529
1528 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1530 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1529 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1531 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1530 uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2; 1532 uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2;
1531 if (index < length) { 1533 if (entry < length) {
1532 // TODO(kmillikin): We could check if this was the last aliased 1534 // TODO(kmillikin): We could check if this was the last aliased
1533 // parameter, and revert to normal elements in that case. That 1535 // parameter, and revert to normal elements in that case. That
1534 // would enable GC of the context. 1536 // would enable GC of the context.
1535 parameter_map->set_the_hole(index + 2); 1537 parameter_map->set_the_hole(entry + 2);
1536 } else { 1538 } else {
1537 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments( 1539 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments(
1538 obj, index - length); 1540 obj, entry - length);
1539 } 1541 }
1540 } 1542 }
1541 }; 1543 };
1542 1544
1543 1545
1544 class SlowSloppyArgumentsElementsAccessor 1546 class SlowSloppyArgumentsElementsAccessor
1545 : public SloppyArgumentsElementsAccessor< 1547 : public SloppyArgumentsElementsAccessor<
1546 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 1548 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1547 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { 1549 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1548 public: 1550 public:
1549 explicit SlowSloppyArgumentsElementsAccessor(const char* name) 1551 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1550 : SloppyArgumentsElementsAccessor< 1552 : SloppyArgumentsElementsAccessor<
1551 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 1553 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1552 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1554 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1553 1555
1554 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { 1556 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) {
1555 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1557 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1556 Handle<SeededNumberDictionary> dict( 1558 Handle<SeededNumberDictionary> dict(
1557 SeededNumberDictionary::cast(parameter_map->get(1))); 1559 SeededNumberDictionary::cast(parameter_map->get(1)));
1558 // TODO(verwaest): Remove reliance on key in Shrink. 1560 // TODO(verwaest): Remove reliance on index in Shrink.
1559 uint32_t key = GetKeyForIndexImpl(*dict, index); 1561 uint32_t index = GetIndexForEntryImpl(*dict, entry);
1560 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); 1562 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
1561 USE(result); 1563 USE(result);
1562 DCHECK(result->IsTrue()); 1564 DCHECK(result->IsTrue());
1563 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); 1565 Handle<FixedArray> new_elements =
1566 SeededNumberDictionary::Shrink(dict, index);
1564 parameter_map->set(1, *new_elements); 1567 parameter_map->set(1, *new_elements);
1565 } 1568 }
1566 1569
1567 static void AddImpl(Handle<JSObject> object, uint32_t key, 1570 static void AddImpl(Handle<JSObject> object, uint32_t index,
1568 Handle<Object> value, PropertyAttributes attributes, 1571 Handle<Object> value, PropertyAttributes attributes,
1569 uint32_t new_capacity) { 1572 uint32_t new_capacity) {
1570 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1573 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1571 Handle<FixedArrayBase> old_elements( 1574 Handle<FixedArrayBase> old_elements(
1572 FixedArrayBase::cast(parameter_map->get(1))); 1575 FixedArrayBase::cast(parameter_map->get(1)));
1573 Handle<SeededNumberDictionary> dictionary = 1576 Handle<SeededNumberDictionary> dictionary =
1574 old_elements->IsSeededNumberDictionary() 1577 old_elements->IsSeededNumberDictionary()
1575 ? Handle<SeededNumberDictionary>::cast(old_elements) 1578 ? Handle<SeededNumberDictionary>::cast(old_elements)
1576 : JSObject::NormalizeElements(object); 1579 : JSObject::NormalizeElements(object);
1577 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 1580 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1578 Handle<SeededNumberDictionary> new_dictionary = 1581 Handle<SeededNumberDictionary> new_dictionary =
1579 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details); 1582 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
1583 details);
1580 if (attributes != NONE) new_dictionary->set_requires_slow_elements(); 1584 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1581 if (*dictionary != *new_dictionary) { 1585 if (*dictionary != *new_dictionary) {
1582 FixedArray::cast(object->elements())->set(1, *new_dictionary); 1586 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1583 } 1587 }
1584 } 1588 }
1585 1589
1586 static void ReconfigureImpl(Handle<JSObject> object, 1590 static void ReconfigureImpl(Handle<JSObject> object,
1587 Handle<FixedArrayBase> store, uint32_t index, 1591 Handle<FixedArrayBase> store, uint32_t entry,
1588 Handle<Object> value, 1592 Handle<Object> value,
1589 PropertyAttributes attributes) { 1593 PropertyAttributes attributes) {
1590 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store); 1594 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1591 uint32_t length = parameter_map->length() - 2; 1595 uint32_t length = parameter_map->length() - 2;
1592 if (index < length) { 1596 if (entry < length) {
1593 Object* probe = parameter_map->get(index + 2); 1597 Object* probe = parameter_map->get(entry + 2);
1594 DCHECK(!probe->IsTheHole()); 1598 DCHECK(!probe->IsTheHole());
1595 Context* context = Context::cast(parameter_map->get(0)); 1599 Context* context = Context::cast(parameter_map->get(0));
1596 int context_index = Smi::cast(probe)->value(); 1600 int context_entry = Smi::cast(probe)->value();
1597 DCHECK(!context->get(context_index)->IsTheHole()); 1601 DCHECK(!context->get(context_entry)->IsTheHole());
1598 context->set(context_index, *value); 1602 context->set(context_entry, *value);
1599 1603
1600 // Redefining attributes of an aliased element destroys fast aliasing. 1604 // Redefining attributes of an aliased element destroys fast aliasing.
1601 parameter_map->set_the_hole(index + 2); 1605 parameter_map->set_the_hole(entry + 2);
1602 // For elements that are still writable we re-establish slow aliasing. 1606 // For elements that are still writable we re-establish slow aliasing.
1603 if ((attributes & READ_ONLY) == 0) { 1607 if ((attributes & READ_ONLY) == 0) {
1604 Isolate* isolate = store->GetIsolate(); 1608 Isolate* isolate = store->GetIsolate();
1605 value = isolate->factory()->NewAliasedArgumentsEntry(context_index); 1609 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry);
1606 } 1610 }
1607 1611
1608 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 1612 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1609 Handle<SeededNumberDictionary> arguments( 1613 Handle<SeededNumberDictionary> arguments(
1610 SeededNumberDictionary::cast(parameter_map->get(1))); 1614 SeededNumberDictionary::cast(parameter_map->get(1)));
1611 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index, 1615 arguments = SeededNumberDictionary::AddNumberEntry(arguments, entry,
1612 value, details); 1616 value, details);
1613 parameter_map->set(1, *arguments); 1617 parameter_map->set(1, *arguments);
1614 } else { 1618 } else {
1615 Handle<FixedArrayBase> arguments( 1619 Handle<FixedArrayBase> arguments(
1616 FixedArrayBase::cast(parameter_map->get(1))); 1620 FixedArrayBase::cast(parameter_map->get(1)));
1617 DictionaryElementsAccessor::ReconfigureImpl( 1621 DictionaryElementsAccessor::ReconfigureImpl(
1618 object, arguments, index - length, value, attributes); 1622 object, arguments, entry - length, value, attributes);
1619 } 1623 }
1620 } 1624 }
1621 }; 1625 };
1622 1626
1623 1627
1624 class FastSloppyArgumentsElementsAccessor 1628 class FastSloppyArgumentsElementsAccessor
1625 : public SloppyArgumentsElementsAccessor< 1629 : public SloppyArgumentsElementsAccessor<
1626 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, 1630 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1627 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { 1631 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
1628 public: 1632 public:
1629 explicit FastSloppyArgumentsElementsAccessor(const char* name) 1633 explicit FastSloppyArgumentsElementsAccessor(const char* name)
1630 : SloppyArgumentsElementsAccessor< 1634 : SloppyArgumentsElementsAccessor<
1631 FastSloppyArgumentsElementsAccessor, 1635 FastSloppyArgumentsElementsAccessor,
1632 FastHoleyObjectElementsAccessor, 1636 FastHoleyObjectElementsAccessor,
1633 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1637 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1634 1638
1635 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { 1639 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) {
1636 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1640 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1637 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1641 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1638 FastHoleyObjectElementsAccessor::DeleteCommon(obj, index, arguments); 1642 FastHoleyObjectElementsAccessor::DeleteCommon(obj, entry, arguments);
1639 } 1643 }
1640 1644
1641 static void AddImpl(Handle<JSObject> object, uint32_t key, 1645 static void AddImpl(Handle<JSObject> object, uint32_t index,
1642 Handle<Object> value, PropertyAttributes attributes, 1646 Handle<Object> value, PropertyAttributes attributes,
1643 uint32_t new_capacity) { 1647 uint32_t new_capacity) {
1644 DCHECK_EQ(NONE, attributes); 1648 DCHECK_EQ(NONE, attributes);
1645 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1649 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1646 Handle<FixedArrayBase> old_elements( 1650 Handle<FixedArrayBase> old_elements(
1647 FixedArrayBase::cast(parameter_map->get(1))); 1651 FixedArrayBase::cast(parameter_map->get(1)));
1648 if (old_elements->IsSeededNumberDictionary() || 1652 if (old_elements->IsSeededNumberDictionary() ||
1649 static_cast<uint32_t>(old_elements->length()) < new_capacity) { 1653 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1650 GrowCapacityAndConvertImpl(object, new_capacity); 1654 GrowCapacityAndConvertImpl(object, new_capacity);
1651 } 1655 }
1652 SetImpl(object->elements(), key, *value); 1656 SetImpl(object->elements(), index, *value);
1653 } 1657 }
1654 1658
1655 static void ReconfigureImpl(Handle<JSObject> object, 1659 static void ReconfigureImpl(Handle<JSObject> object,
1656 Handle<FixedArrayBase> store, uint32_t index, 1660 Handle<FixedArrayBase> store, uint32_t entry,
1657 Handle<Object> value, 1661 Handle<Object> value,
1658 PropertyAttributes attributes) { 1662 PropertyAttributes attributes) {
1659 Handle<SeededNumberDictionary> dictionary = 1663 Handle<SeededNumberDictionary> dictionary =
1660 JSObject::NormalizeElements(object); 1664 JSObject::NormalizeElements(object);
1661 FixedArray::cast(*store)->set(1, *dictionary); 1665 FixedArray::cast(*store)->set(1, *dictionary);
1662 uint32_t length = static_cast<uint32_t>(store->length()) - 2; 1666 uint32_t length = static_cast<uint32_t>(store->length()) - 2;
1663 if (index >= length) { 1667 if (entry >= length) {
1664 index = dictionary->FindEntry(index - length) + length; 1668 entry = dictionary->FindEntry(entry - length) + length;
1665 } 1669 }
1666 SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, index, 1670 SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, entry,
1667 value, attributes); 1671 value, attributes);
1668 } 1672 }
1669 1673
1670 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1674 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1671 FixedArrayBase* to, ElementsKind from_kind, 1675 FixedArrayBase* to, ElementsKind from_kind,
1672 uint32_t to_start, int packed_size, 1676 uint32_t to_start, int packed_size,
1673 int copy_size) { 1677 int copy_size) {
1674 DCHECK(!to->IsDictionary()); 1678 DCHECK(!to->IsDictionary());
1675 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { 1679 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
1676 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, 1680 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); 1746 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
1743 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); 1747 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
1744 } 1748 }
1745 1749
1746 array->set_length(Smi::FromInt(length)); 1750 array->set_length(Smi::FromInt(length));
1747 JSObject::ValidateElements(array); 1751 JSObject::ValidateElements(array);
1748 } 1752 }
1749 } // namespace 1753 } // namespace
1750 1754
1751 1755
1752 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key, 1756 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index,
1753 bool allow_appending) { 1757 bool allow_appending) {
1754 DisallowHeapAllocation no_allocation; 1758 DisallowHeapAllocation no_allocation;
1755 Object* raw_length = NULL; 1759 Object* raw_length = NULL;
1756 const char* elements_type = "array"; 1760 const char* elements_type = "array";
1757 if (obj->IsJSArray()) { 1761 if (obj->IsJSArray()) {
1758 JSArray* array = JSArray::cast(*obj); 1762 JSArray* array = JSArray::cast(*obj);
1759 raw_length = array->length(); 1763 raw_length = array->length();
1760 } else { 1764 } else {
1761 raw_length = Smi::FromInt(obj->elements()->length()); 1765 raw_length = Smi::FromInt(obj->elements()->length());
1762 elements_type = "object"; 1766 elements_type = "object";
1763 } 1767 }
1764 1768
1765 if (raw_length->IsNumber()) { 1769 if (raw_length->IsNumber()) {
1766 double n = raw_length->Number(); 1770 double n = raw_length->Number();
1767 if (FastI2D(FastD2UI(n)) == n) { 1771 if (FastI2D(FastD2UI(n)) == n) {
1768 int32_t int32_length = DoubleToInt32(n); 1772 int32_t int32_length = DoubleToInt32(n);
1769 uint32_t compare_length = static_cast<uint32_t>(int32_length); 1773 uint32_t compare_length = static_cast<uint32_t>(int32_length);
1770 if (allow_appending) compare_length++; 1774 if (allow_appending) compare_length++;
1771 if (key >= compare_length) { 1775 if (index >= compare_length) {
1772 PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ", 1776 PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ",
1773 elements_type, op, elements_type, static_cast<int>(int32_length), 1777 elements_type, op, elements_type, static_cast<int>(int32_length),
1774 static_cast<int>(key)); 1778 static_cast<int>(index));
1775 TraceTopFrame(obj->GetIsolate()); 1779 TraceTopFrame(obj->GetIsolate());
1776 PrintF("]\n"); 1780 PrintF("]\n");
1777 } 1781 }
1778 } else { 1782 } else {
1779 PrintF("[%s elements length not integer value in ", elements_type); 1783 PrintF("[%s elements length not integer value in ", elements_type);
1780 TraceTopFrame(obj->GetIsolate()); 1784 TraceTopFrame(obj->GetIsolate());
1781 PrintF("]\n"); 1785 PrintF("]\n");
1782 } 1786 }
1783 } else { 1787 } else {
1784 PrintF("[%s elements length not a number in ", elements_type); 1788 PrintF("[%s elements length not a number in ", elements_type);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 } else { 1841 } else {
1838 elms = Handle<FixedArrayBase>::cast( 1842 elms = Handle<FixedArrayBase>::cast(
1839 factory->NewFixedArrayWithHoles(number_of_elements)); 1843 factory->NewFixedArrayWithHoles(number_of_elements));
1840 } 1844 }
1841 1845
1842 // Fill in the content 1846 // Fill in the content
1843 switch (array->GetElementsKind()) { 1847 switch (array->GetElementsKind()) {
1844 case FAST_HOLEY_SMI_ELEMENTS: 1848 case FAST_HOLEY_SMI_ELEMENTS:
1845 case FAST_SMI_ELEMENTS: { 1849 case FAST_SMI_ELEMENTS: {
1846 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); 1850 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms);
1847 for (int index = 0; index < number_of_elements; index++) { 1851 for (int entry = 0; entry < number_of_elements; entry++) {
1848 smi_elms->set(index, (*args)[index], SKIP_WRITE_BARRIER); 1852 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER);
1849 } 1853 }
1850 break; 1854 break;
1851 } 1855 }
1852 case FAST_HOLEY_ELEMENTS: 1856 case FAST_HOLEY_ELEMENTS:
1853 case FAST_ELEMENTS: { 1857 case FAST_ELEMENTS: {
1854 DisallowHeapAllocation no_gc; 1858 DisallowHeapAllocation no_gc;
1855 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 1859 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
1856 Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms); 1860 Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms);
1857 for (int index = 0; index < number_of_elements; index++) { 1861 for (int entry = 0; entry < number_of_elements; entry++) {
1858 object_elms->set(index, (*args)[index], mode); 1862 object_elms->set(entry, (*args)[entry], mode);
1859 } 1863 }
1860 break; 1864 break;
1861 } 1865 }
1862 case FAST_HOLEY_DOUBLE_ELEMENTS: 1866 case FAST_HOLEY_DOUBLE_ELEMENTS:
1863 case FAST_DOUBLE_ELEMENTS: { 1867 case FAST_DOUBLE_ELEMENTS: {
1864 Handle<FixedDoubleArray> double_elms = 1868 Handle<FixedDoubleArray> double_elms =
1865 Handle<FixedDoubleArray>::cast(elms); 1869 Handle<FixedDoubleArray>::cast(elms);
1866 for (int index = 0; index < number_of_elements; index++) { 1870 for (int entry = 0; entry < number_of_elements; entry++) {
1867 double_elms->set(index, (*args)[index]->Number()); 1871 double_elms->set(entry, (*args)[entry]->Number());
1868 } 1872 }
1869 break; 1873 break;
1870 } 1874 }
1871 default: 1875 default:
1872 UNREACHABLE(); 1876 UNREACHABLE();
1873 break; 1877 break;
1874 } 1878 }
1875 1879
1876 array->set_elements(*elms); 1880 array->set_elements(*elms);
1877 array->set_length(Smi::FromInt(number_of_elements)); 1881 array->set_length(Smi::FromInt(number_of_elements));
(...skipping 20 matching lines...) Expand all
1898 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 1902 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1899 ELEMENTS_LIST(ACCESSOR_DELETE) 1903 ELEMENTS_LIST(ACCESSOR_DELETE)
1900 #undef ACCESSOR_DELETE 1904 #undef ACCESSOR_DELETE
1901 elements_accessors_ = NULL; 1905 elements_accessors_ = NULL;
1902 } 1906 }
1903 1907
1904 1908
1905 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 1909 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
1906 } // namespace internal 1910 } // namespace internal
1907 } // namespace v8 1911 } // namespace v8
OLDNEW
« src/elements.h ('K') | « src/elements.h ('k') | src/lookup-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698