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

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: Addressed comments 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
« no previous file with comments | « src/elements.h ('k') | src/lookup-inl.h » ('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 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 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
826 return ElementsAccessorSubclass::HasIndexImpl(backing_store, index); 830 uint32_t entry) {
831 return entry;
827 } 832 }
828 833
829 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, 834 static uint32_t GetEntryForIndexImpl(JSObject* holder,
830 uint32_t index) { 835 FixedArrayBase* backing_store,
831 return index; 836 uint32_t index) {
832 } 837 return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
833 838 backing_store) &&
834 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 839 !BackingStore::cast(backing_store)->is_the_hole(index)
835 uint32_t index) final { 840 ? index
836 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
837 }
838
839 static uint32_t GetIndexForKeyImpl(JSObject* holder,
840 FixedArrayBase* backing_store,
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; 841 : kMaxUInt32;
847 } 842 }
848 843
849 virtual uint32_t GetIndexForKey(JSObject* holder, 844 virtual uint32_t GetEntryForIndex(JSObject* holder,
850 FixedArrayBase* backing_store, 845 FixedArrayBase* backing_store,
851 uint32_t key) final { 846 uint32_t index) final {
852 return ElementsAccessorSubclass::GetIndexForKeyImpl(holder, backing_store, 847 return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store,
853 key); 848 index);
854 } 849 }
855 850
856 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 851 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
857 uint32_t index) { 852 uint32_t entry) {
858 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 853 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
859 } 854 }
860 855
861 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, 856 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
862 uint32_t index) final { 857 uint32_t entry) final {
863 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index); 858 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry);
864 } 859 }
865 860
866 private: 861 private:
867 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 862 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
868 }; 863 };
869 864
870 865
871 class DictionaryElementsAccessor 866 class DictionaryElementsAccessor
872 : public ElementsAccessorBase<DictionaryElementsAccessor, 867 : public ElementsAccessorBase<DictionaryElementsAccessor,
873 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 868 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
874 public: 869 public:
875 explicit DictionaryElementsAccessor(const char* name) 870 explicit DictionaryElementsAccessor(const char* name)
876 : ElementsAccessorBase<DictionaryElementsAccessor, 871 : ElementsAccessorBase<DictionaryElementsAccessor,
877 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 872 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
878 873
879 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 874 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
880 Handle<FixedArrayBase> backing_store) { 875 Handle<FixedArrayBase> backing_store) {
881 Handle<SeededNumberDictionary> dict = 876 Handle<SeededNumberDictionary> dict =
882 Handle<SeededNumberDictionary>::cast(backing_store); 877 Handle<SeededNumberDictionary>::cast(backing_store);
883 Isolate* isolate = array->GetIsolate(); 878 Isolate* isolate = array->GetIsolate();
884 int capacity = dict->Capacity(); 879 int capacity = dict->Capacity();
885 uint32_t old_length = 0; 880 uint32_t old_length = 0;
886 CHECK(array->length()->ToArrayLength(&old_length)); 881 CHECK(array->length()->ToArrayLength(&old_length));
887 if (length < old_length) { 882 if (length < old_length) {
888 if (dict->requires_slow_elements()) { 883 if (dict->requires_slow_elements()) {
889 // Find last non-deletable element in range of elements to be 884 // Find last non-deletable element in range of elements to be
890 // deleted and adjust range accordingly. 885 // deleted and adjust range accordingly.
891 for (int i = 0; i < capacity; i++) { 886 for (int entry = 0; entry < capacity; entry++) {
892 DisallowHeapAllocation no_gc; 887 DisallowHeapAllocation no_gc;
893 Object* key = dict->KeyAt(i); 888 Object* index = dict->KeyAt(entry);
894 if (key->IsNumber()) { 889 if (index->IsNumber()) {
895 uint32_t number = static_cast<uint32_t>(key->Number()); 890 uint32_t number = static_cast<uint32_t>(index->Number());
896 if (length <= number && number < old_length) { 891 if (length <= number && number < old_length) {
897 PropertyDetails details = dict->DetailsAt(i); 892 PropertyDetails details = dict->DetailsAt(entry);
898 if (!details.IsConfigurable()) length = number + 1; 893 if (!details.IsConfigurable()) length = number + 1;
899 } 894 }
900 } 895 }
901 } 896 }
902 } 897 }
903 898
904 if (length == 0) { 899 if (length == 0) {
905 // Flush the backing store. 900 // Flush the backing store.
906 JSObject::ResetElements(array); 901 JSObject::ResetElements(array);
907 } else { 902 } else {
908 DisallowHeapAllocation no_gc; 903 DisallowHeapAllocation no_gc;
909 // Remove elements that should be deleted. 904 // Remove elements that should be deleted.
910 int removed_entries = 0; 905 int removed_entries = 0;
911 Handle<Object> the_hole_value = isolate->factory()->the_hole_value(); 906 Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
912 for (int i = 0; i < capacity; i++) { 907 for (int entry = 0; entry < capacity; entry++) {
913 Object* key = dict->KeyAt(i); 908 Object* index = dict->KeyAt(entry);
914 if (key->IsNumber()) { 909 if (index->IsNumber()) {
915 uint32_t number = static_cast<uint32_t>(key->Number()); 910 uint32_t number = static_cast<uint32_t>(index->Number());
916 if (length <= number && number < old_length) { 911 if (length <= number && number < old_length) {
917 dict->SetEntry(i, the_hole_value, the_hole_value); 912 dict->SetEntry(entry, the_hole_value, the_hole_value);
918 removed_entries++; 913 removed_entries++;
919 } 914 }
920 } 915 }
921 } 916 }
922 917
923 // Update the number of elements. 918 // Update the number of elements.
924 dict->ElementsRemoved(removed_entries); 919 dict->ElementsRemoved(removed_entries);
925 } 920 }
926 } 921 }
927 922
928 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); 923 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
929 array->set_length(*length_obj); 924 array->set_length(*length_obj);
930 } 925 }
931 926
932 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 927 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
933 FixedArrayBase* to, ElementsKind from_kind, 928 FixedArrayBase* to, ElementsKind from_kind,
934 uint32_t to_start, int packed_size, 929 uint32_t to_start, int packed_size,
935 int copy_size) { 930 int copy_size) {
936 UNREACHABLE(); 931 UNREACHABLE();
937 } 932 }
938 933
939 934
940 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 935 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
941 // TODO(verwaest): Remove reliance on key in Shrink. 936 // TODO(verwaest): Remove reliance on index in Shrink.
942 Handle<SeededNumberDictionary> dict( 937 Handle<SeededNumberDictionary> dict(
943 SeededNumberDictionary::cast(obj->elements())); 938 SeededNumberDictionary::cast(obj->elements()));
944 uint32_t key = GetKeyForIndexImpl(*dict, index); 939 uint32_t index = GetIndexForEntryImpl(*dict, entry);
945 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); 940 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
946 USE(result); 941 USE(result);
947 DCHECK(result->IsTrue()); 942 DCHECK(result->IsTrue());
948 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); 943 Handle<FixedArray> new_elements =
944 SeededNumberDictionary::Shrink(dict, index);
949 obj->set_elements(*new_elements); 945 obj->set_elements(*new_elements);
950 } 946 }
951 947
952 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 948 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
953 Handle<FixedArrayBase> store) { 949 Handle<FixedArrayBase> store) {
954 Handle<SeededNumberDictionary> backing_store = 950 Handle<SeededNumberDictionary> backing_store =
955 Handle<SeededNumberDictionary>::cast(store); 951 Handle<SeededNumberDictionary>::cast(store);
956 Isolate* isolate = backing_store->GetIsolate(); 952 Isolate* isolate = backing_store->GetIsolate();
957 int entry = backing_store->FindEntry(key); 953 int entry = backing_store->FindEntry(index);
958 if (entry != SeededNumberDictionary::kNotFound) { 954 if (entry != SeededNumberDictionary::kNotFound) {
959 return handle(backing_store->ValueAt(entry), isolate); 955 return handle(backing_store->ValueAt(entry), isolate);
960 } 956 }
961 return isolate->factory()->the_hole_value(); 957 return isolate->factory()->the_hole_value();
962 } 958 }
963 959
964 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 960 static void SetImpl(FixedArrayBase* store, uint32_t index, Object* value) {
965 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 961 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
966 int entry = dictionary->FindEntry(key); 962 int entry = dictionary->FindEntry(index);
967 DCHECK_NE(SeededNumberDictionary::kNotFound, entry); 963 DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
968 dictionary->ValueAtPut(entry, value); 964 dictionary->ValueAtPut(entry, value);
969 } 965 }
970 966
971 static void ReconfigureImpl(Handle<JSObject> object, 967 static void ReconfigureImpl(Handle<JSObject> object,
972 Handle<FixedArrayBase> store, uint32_t index, 968 Handle<FixedArrayBase> store, uint32_t entry,
973 Handle<Object> value, 969 Handle<Object> value,
974 PropertyAttributes attributes) { 970 PropertyAttributes attributes) {
975 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); 971 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
976 if (attributes != NONE) dictionary->set_requires_slow_elements(); 972 if (attributes != NONE) dictionary->set_requires_slow_elements();
977 dictionary->ValueAtPut(index, *value); 973 dictionary->ValueAtPut(entry, *value);
978 PropertyDetails details = dictionary->DetailsAt(index); 974 PropertyDetails details = dictionary->DetailsAt(entry);
979 details = PropertyDetails(attributes, DATA, details.dictionary_index(), 975 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
980 PropertyCellType::kNoCell); 976 PropertyCellType::kNoCell);
981 dictionary->DetailsAtPut(index, details); 977 dictionary->DetailsAtPut(entry, details);
982 } 978 }
983 979
984 static void AddImpl(Handle<JSObject> object, uint32_t index, 980 static void AddImpl(Handle<JSObject> object, uint32_t entry,
985 Handle<Object> value, PropertyAttributes attributes, 981 Handle<Object> value, PropertyAttributes attributes,
986 uint32_t new_capacity) { 982 uint32_t new_capacity) {
987 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 983 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
988 Handle<SeededNumberDictionary> dictionary = 984 Handle<SeededNumberDictionary> dictionary =
989 object->HasFastElements() 985 object->HasFastElements()
990 ? JSObject::NormalizeElements(object) 986 ? JSObject::NormalizeElements(object)
991 : handle(SeededNumberDictionary::cast(object->elements())); 987 : handle(SeededNumberDictionary::cast(object->elements()));
992 Handle<SeededNumberDictionary> new_dictionary = 988 Handle<SeededNumberDictionary> new_dictionary =
993 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 989 SeededNumberDictionary::AddNumberEntry(dictionary, entry, value,
994 details); 990 details);
995 if (attributes != NONE) new_dictionary->set_requires_slow_elements(); 991 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
996 if (dictionary.is_identical_to(new_dictionary)) return; 992 if (dictionary.is_identical_to(new_dictionary)) return;
997 object->set_elements(*new_dictionary); 993 object->set_elements(*new_dictionary);
998 } 994 }
999 995
1000 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) { 996 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) {
1001 DisallowHeapAllocation no_gc; 997 DisallowHeapAllocation no_gc;
1002 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 998 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1003 Object* key = dict->KeyAt(index); 999 Object* index = dict->KeyAt(entry);
1004 return !key->IsTheHole(); 1000 return !index->IsTheHole();
1005 } 1001 }
1006 1002
1007 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { 1003 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) {
1008 DisallowHeapAllocation no_gc; 1004 DisallowHeapAllocation no_gc;
1009 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1005 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1010 uint32_t result = 0; 1006 uint32_t result = 0;
1011 CHECK(dict->KeyAt(index)->ToArrayIndex(&result)); 1007 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result));
1012 return result; 1008 return result;
1013 } 1009 }
1014 1010
1015 static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store, 1011 static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store,
1016 uint32_t key) { 1012 uint32_t index) {
1017 DisallowHeapAllocation no_gc; 1013 DisallowHeapAllocation no_gc;
1018 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1014 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1019 int entry = dict->FindEntry(key); 1015 int entry = dict->FindEntry(index);
1020 return entry == SeededNumberDictionary::kNotFound 1016 return entry == SeededNumberDictionary::kNotFound
1021 ? kMaxUInt32 1017 ? kMaxUInt32
1022 : static_cast<uint32_t>(entry); 1018 : static_cast<uint32_t>(entry);
1023 } 1019 }
1024 1020
1025 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1021 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1026 uint32_t index) { 1022 uint32_t entry) {
1027 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); 1023 return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
1028 } 1024 }
1029 }; 1025 };
1030 1026
1031 1027
1032 // Super class for all fast element arrays. 1028 // Super class for all fast element arrays.
1033 template<typename FastElementsAccessorSubclass, 1029 template<typename FastElementsAccessorSubclass,
1034 typename KindTraits> 1030 typename KindTraits>
1035 class FastElementsAccessor 1031 class FastElementsAccessor
1036 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 1032 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
1037 public: 1033 public:
1038 explicit FastElementsAccessor(const char* name) 1034 explicit FastElementsAccessor(const char* name)
1039 : ElementsAccessorBase<FastElementsAccessorSubclass, 1035 : ElementsAccessorBase<FastElementsAccessorSubclass,
1040 KindTraits>(name) {} 1036 KindTraits>(name) {}
1041 1037
1042 typedef typename KindTraits::BackingStore BackingStore; 1038 typedef typename KindTraits::BackingStore BackingStore;
1043 1039
1044 static void DeleteCommon(Handle<JSObject> obj, uint32_t index, 1040 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry,
1045 Handle<FixedArrayBase> store) { 1041 Handle<FixedArrayBase> store) {
1046 DCHECK(obj->HasFastSmiOrObjectElements() || 1042 DCHECK(obj->HasFastSmiOrObjectElements() ||
1047 obj->HasFastDoubleElements() || 1043 obj->HasFastDoubleElements() ||
1048 obj->HasFastArgumentsElements()); 1044 obj->HasFastArgumentsElements());
1049 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); 1045 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store);
1050 backing_store->set_the_hole(index); 1046 backing_store->set_the_hole(entry);
1051 1047
1052 // TODO(verwaest): Move this out of elements.cc. 1048 // TODO(verwaest): Move this out of elements.cc.
1053 // If an old space backing store is larger than a certain size and 1049 // If an old space backing store is larger than a certain size and
1054 // has too few used values, normalize it. 1050 // has too few used values, normalize it.
1055 // To avoid doing the check on every delete we require at least 1051 // To avoid doing the check on every delete we require at least
1056 // one adjacent hole to the value being deleted. 1052 // one adjacent hole to the value being deleted.
1057 const int kMinLengthForSparsenessCheck = 64; 1053 const int kMinLengthForSparsenessCheck = 64;
1058 if (backing_store->length() < kMinLengthForSparsenessCheck) return; 1054 if (backing_store->length() < kMinLengthForSparsenessCheck) return;
1059 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; 1055 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return;
1060 uint32_t length = 0; 1056 uint32_t length = 0;
1061 if (obj->IsJSArray()) { 1057 if (obj->IsJSArray()) {
1062 JSArray::cast(*obj)->length()->ToArrayLength(&length); 1058 JSArray::cast(*obj)->length()->ToArrayLength(&length);
1063 } else { 1059 } else {
1064 length = static_cast<uint32_t>(store->length()); 1060 length = static_cast<uint32_t>(store->length());
1065 } 1061 }
1066 if ((index > 0 && backing_store->is_the_hole(index - 1)) || 1062 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) ||
1067 (index + 1 < length && backing_store->is_the_hole(index + 1))) { 1063 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) {
1068 int num_used = 0; 1064 int num_used = 0;
1069 for (int i = 0; i < backing_store->length(); ++i) { 1065 for (int i = 0; i < backing_store->length(); ++i) {
1070 if (!backing_store->is_the_hole(i)) ++num_used; 1066 if (!backing_store->is_the_hole(i)) ++num_used;
1071 // Bail out early if more than 1/4 is used. 1067 // Bail out early if more than 1/4 is used.
1072 if (4 * num_used > backing_store->length()) break; 1068 if (4 * num_used > backing_store->length()) break;
1073 } 1069 }
1074 if (4 * num_used <= backing_store->length()) { 1070 if (4 * num_used <= backing_store->length()) {
1075 JSObject::NormalizeElements(obj); 1071 JSObject::NormalizeElements(obj);
1076 } 1072 }
1077 } 1073 }
1078 } 1074 }
1079 1075
1080 static void ReconfigureImpl(Handle<JSObject> object, 1076 static void ReconfigureImpl(Handle<JSObject> object,
1081 Handle<FixedArrayBase> store, uint32_t index, 1077 Handle<FixedArrayBase> store, uint32_t entry,
1082 Handle<Object> value, 1078 Handle<Object> value,
1083 PropertyAttributes attributes) { 1079 PropertyAttributes attributes) {
1084 Handle<SeededNumberDictionary> dictionary = 1080 Handle<SeededNumberDictionary> dictionary =
1085 JSObject::NormalizeElements(object); 1081 JSObject::NormalizeElements(object);
1086 index = dictionary->FindEntry(index); 1082 entry = dictionary->FindEntry(entry);
1087 DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, index, 1083 DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, entry,
1088 value, attributes); 1084 value, attributes);
1089 } 1085 }
1090 1086
1091 static void AddImpl(Handle<JSObject> object, uint32_t index, 1087 static void AddImpl(Handle<JSObject> object, uint32_t entry,
1092 Handle<Object> value, PropertyAttributes attributes, 1088 Handle<Object> value, PropertyAttributes attributes,
1093 uint32_t new_capacity) { 1089 uint32_t new_capacity) {
1094 DCHECK_EQ(NONE, attributes); 1090 DCHECK_EQ(NONE, attributes);
1095 ElementsKind from_kind = object->GetElementsKind(); 1091 ElementsKind from_kind = object->GetElementsKind();
1096 ElementsKind to_kind = FastElementsAccessorSubclass::kind(); 1092 ElementsKind to_kind = FastElementsAccessorSubclass::kind();
1097 if (IsDictionaryElementsKind(from_kind) || 1093 if (IsDictionaryElementsKind(from_kind) ||
1098 IsFastDoubleElementsKind(from_kind) != 1094 IsFastDoubleElementsKind(from_kind) !=
1099 IsFastDoubleElementsKind(to_kind) || 1095 IsFastDoubleElementsKind(to_kind) ||
1100 FastElementsAccessorSubclass::GetCapacityImpl( 1096 FastElementsAccessorSubclass::GetCapacityImpl(
1101 *object, object->elements()) != new_capacity) { 1097 *object, object->elements()) != new_capacity) {
1102 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, 1098 FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object,
1103 new_capacity); 1099 new_capacity);
1104 } else { 1100 } else {
1105 if (from_kind != to_kind) { 1101 if (from_kind != to_kind) {
1106 JSObject::TransitionElementsKind(object, to_kind); 1102 JSObject::TransitionElementsKind(object, to_kind);
1107 } 1103 }
1108 if (IsFastSmiOrObjectElementsKind(from_kind)) { 1104 if (IsFastSmiOrObjectElementsKind(from_kind)) {
1109 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); 1105 DCHECK(IsFastSmiOrObjectElementsKind(to_kind));
1110 JSObject::EnsureWritableFastElements(object); 1106 JSObject::EnsureWritableFastElements(object);
1111 } 1107 }
1112 } 1108 }
1113 FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); 1109 FastElementsAccessorSubclass::SetImpl(object->elements(), entry, *value);
1114 } 1110 }
1115 1111
1116 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1112 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1117 ElementsKind kind = KindTraits::Kind; 1113 ElementsKind kind = KindTraits::Kind;
1118 if (IsFastPackedElementsKind(kind)) { 1114 if (IsFastPackedElementsKind(kind)) {
1119 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 1115 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
1120 } 1116 }
1121 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 1117 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
1122 JSObject::EnsureWritableFastElements(obj); 1118 JSObject::EnsureWritableFastElements(obj);
1123 } 1119 }
1124 DeleteCommon(obj, index, handle(obj->elements())); 1120 DeleteCommon(obj, entry, handle(obj->elements()));
1125 } 1121 }
1126 1122
1127 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { 1123 static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
1128 return !BackingStore::cast(backing_store)->is_the_hole(index); 1124 return !BackingStore::cast(backing_store)->is_the_hole(entry);
1129 } 1125 }
1130 1126
1131 static void ValidateContents(Handle<JSObject> holder, int length) { 1127 static void ValidateContents(Handle<JSObject> holder, int length) {
1132 #if DEBUG 1128 #if DEBUG
1133 Isolate* isolate = holder->GetIsolate(); 1129 Isolate* isolate = holder->GetIsolate();
1134 HandleScope scope(isolate); 1130 HandleScope scope(isolate);
1135 Handle<FixedArrayBase> elements(holder->elements(), isolate); 1131 Handle<FixedArrayBase> elements(holder->elements(), isolate);
1136 Map* map = elements->map(); 1132 Map* map = elements->map();
1137 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 1133 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
1138 (map == isolate->heap()->fixed_array_map() || 1134 (map == isolate->heap()->fixed_array_map() ||
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 1331 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1336 ElementsKindTraits<Kind> > { 1332 ElementsKindTraits<Kind> > {
1337 public: 1333 public:
1338 explicit TypedElementsAccessor(const char* name) 1334 explicit TypedElementsAccessor(const char* name)
1339 : ElementsAccessorBase<AccessorClass, 1335 : ElementsAccessorBase<AccessorClass,
1340 ElementsKindTraits<Kind> >(name) {} 1336 ElementsKindTraits<Kind> >(name) {}
1341 1337
1342 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1338 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1343 typedef TypedElementsAccessor<Kind> AccessorClass; 1339 typedef TypedElementsAccessor<Kind> AccessorClass;
1344 1340
1345 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1341 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
1346 Handle<FixedArrayBase> backing_store) { 1342 Handle<FixedArrayBase> backing_store) {
1347 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1343 if (index < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
1348 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 1344 return BackingStore::get(Handle<BackingStore>::cast(backing_store),
1345 index);
1349 } else { 1346 } else {
1350 return backing_store->GetIsolate()->factory()->undefined_value(); 1347 return backing_store->GetIsolate()->factory()->undefined_value();
1351 } 1348 }
1352 } 1349 }
1353 1350
1354 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1351 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1355 uint32_t index) { 1352 uint32_t entry) {
1356 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 1353 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1357 } 1354 }
1358 1355
1359 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1356 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1360 Handle<FixedArrayBase> backing_store) { 1357 Handle<FixedArrayBase> backing_store) {
1361 // External arrays do not support changing their length. 1358 // External arrays do not support changing their length.
1362 UNREACHABLE(); 1359 UNREACHABLE();
1363 } 1360 }
1364 1361
1365 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1362 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1366 UNREACHABLE(); 1363 UNREACHABLE();
1367 } 1364 }
1368 1365
1369 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1366 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1370 FixedArrayBase* backing_store, 1367 FixedArrayBase* backing_store,
1371 uint32_t key) { 1368 uint32_t index) {
1372 return key < AccessorClass::GetCapacityImpl(holder, backing_store) 1369 return index < AccessorClass::GetCapacityImpl(holder, backing_store)
1373 ? key 1370 ? index
1374 : kMaxUInt32; 1371 : kMaxUInt32;
1375 } 1372 }
1376 1373
1377 static uint32_t GetCapacityImpl(JSObject* holder, 1374 static uint32_t GetCapacityImpl(JSObject* holder,
1378 FixedArrayBase* backing_store) { 1375 FixedArrayBase* backing_store) {
1379 JSArrayBufferView* view = JSArrayBufferView::cast(holder); 1376 JSArrayBufferView* view = JSArrayBufferView::cast(holder);
1380 if (view->WasNeutered()) return 0; 1377 if (view->WasNeutered()) return 0;
1381 return backing_store->length(); 1378 return backing_store->length();
1382 } 1379 }
1383 }; 1380 };
(...skipping 18 matching lines...) Expand all
1402 template <typename SloppyArgumentsElementsAccessorSubclass, 1399 template <typename SloppyArgumentsElementsAccessorSubclass,
1403 typename ArgumentsAccessor, typename KindTraits> 1400 typename ArgumentsAccessor, typename KindTraits>
1404 class SloppyArgumentsElementsAccessor 1401 class SloppyArgumentsElementsAccessor
1405 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1402 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1406 KindTraits> { 1403 KindTraits> {
1407 public: 1404 public:
1408 explicit SloppyArgumentsElementsAccessor(const char* name) 1405 explicit SloppyArgumentsElementsAccessor(const char* name)
1409 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1406 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1410 KindTraits>(name) {} 1407 KindTraits>(name) {}
1411 1408
1412 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1409 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t index,
1413 Handle<FixedArrayBase> parameters) { 1410 Handle<FixedArrayBase> parameters) {
1414 Isolate* isolate = obj->GetIsolate(); 1411 Isolate* isolate = obj->GetIsolate();
1415 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1412 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1416 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1413 Handle<Object> probe(GetParameterMapArg(*parameter_map, index), isolate);
1417 if (!probe->IsTheHole()) { 1414 if (!probe->IsTheHole()) {
1418 DisallowHeapAllocation no_gc; 1415 DisallowHeapAllocation no_gc;
1419 Context* context = Context::cast(parameter_map->get(0)); 1416 Context* context = Context::cast(parameter_map->get(0));
1420 int context_index = Handle<Smi>::cast(probe)->value(); 1417 int context_entry = Handle<Smi>::cast(probe)->value();
1421 DCHECK(!context->get(context_index)->IsTheHole()); 1418 DCHECK(!context->get(context_entry)->IsTheHole());
1422 return handle(context->get(context_index), isolate); 1419 return handle(context->get(context_entry), isolate);
1423 } else { 1420 } else {
1424 // Object is not mapped, defer to the arguments. 1421 // Object is not mapped, defer to the arguments.
1425 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1422 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1426 isolate); 1423 isolate);
1427 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments); 1424 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, index, arguments);
1428 // Elements of the arguments object in slow mode might be slow aliases. 1425 // Elements of the arguments object in slow mode might be slow aliases.
1429 if (result->IsAliasedArgumentsEntry()) { 1426 if (result->IsAliasedArgumentsEntry()) {
1430 DisallowHeapAllocation no_gc; 1427 DisallowHeapAllocation no_gc;
1431 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1428 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1432 Context* context = Context::cast(parameter_map->get(0)); 1429 Context* context = Context::cast(parameter_map->get(0));
1433 int context_index = entry->aliased_context_slot(); 1430 int context_entry = entry->aliased_context_slot();
1434 DCHECK(!context->get(context_index)->IsTheHole()); 1431 DCHECK(!context->get(context_entry)->IsTheHole());
1435 return handle(context->get(context_index), isolate); 1432 return handle(context->get(context_entry), isolate);
1436 } else { 1433 } else {
1437 return result; 1434 return result;
1438 } 1435 }
1439 } 1436 }
1440 } 1437 }
1441 1438
1442 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1439 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1443 uint32_t capacity) { 1440 uint32_t capacity) {
1444 UNREACHABLE(); 1441 UNREACHABLE();
1445 } 1442 }
1446 1443
1447 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 1444 static void SetImpl(FixedArrayBase* store, uint32_t index, Object* value) {
1448 FixedArray* parameter_map = FixedArray::cast(store); 1445 FixedArray* parameter_map = FixedArray::cast(store);
1449 Object* probe = GetParameterMapArg(parameter_map, key); 1446 Object* probe = GetParameterMapArg(parameter_map, index);
1450 if (!probe->IsTheHole()) { 1447 if (!probe->IsTheHole()) {
1451 Context* context = Context::cast(parameter_map->get(0)); 1448 Context* context = Context::cast(parameter_map->get(0));
1452 int context_index = Smi::cast(probe)->value(); 1449 int context_entry = Smi::cast(probe)->value();
1453 DCHECK(!context->get(context_index)->IsTheHole()); 1450 DCHECK(!context->get(context_entry)->IsTheHole());
1454 context->set(context_index, value); 1451 context->set(context_entry, value);
1455 } else { 1452 } else {
1456 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1453 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1457 ArgumentsAccessor::SetImpl(arguments, key, value); 1454 ArgumentsAccessor::SetImpl(arguments, index, value);
1458 } 1455 }
1459 } 1456 }
1460 1457
1461 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1458 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1462 Handle<FixedArrayBase> parameter_map) { 1459 Handle<FixedArrayBase> parameter_map) {
1463 // Sloppy arguments objects are not arrays. 1460 // Sloppy arguments objects are not arrays.
1464 UNREACHABLE(); 1461 UNREACHABLE();
1465 } 1462 }
1466 1463
1467 static uint32_t GetCapacityImpl(JSObject* holder, 1464 static uint32_t GetCapacityImpl(JSObject* holder,
1468 FixedArrayBase* backing_store) { 1465 FixedArrayBase* backing_store) {
1469 FixedArray* parameter_map = FixedArray::cast(backing_store); 1466 FixedArray* parameter_map = FixedArray::cast(backing_store);
1470 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1467 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1471 return parameter_map->length() - 2 + 1468 return parameter_map->length() - 2 +
1472 ArgumentsAccessor::GetCapacityImpl(holder, arguments); 1469 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
1473 } 1470 }
1474 1471
1475 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { 1472 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) {
1476 FixedArray* parameter_map = FixedArray::cast(parameters); 1473 FixedArray* parameter_map = FixedArray::cast(parameters);
1477 uint32_t length = parameter_map->length() - 2; 1474 uint32_t length = parameter_map->length() - 2;
1478 if (index < length) { 1475 if (entry < length) {
1479 return !GetParameterMapArg(parameter_map, index)->IsTheHole(); 1476 return !GetParameterMapArg(parameter_map, entry)->IsTheHole();
1480 } 1477 }
1481 1478
1482 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1479 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1483 return ArgumentsAccessor::HasIndexImpl(arguments, index - length); 1480 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length);
1484 } 1481 }
1485 1482
1486 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, 1483 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters,
1487 uint32_t index) { 1484 uint32_t entry) {
1488 FixedArray* parameter_map = FixedArray::cast(parameters); 1485 FixedArray* parameter_map = FixedArray::cast(parameters);
1489 uint32_t length = parameter_map->length() - 2; 1486 uint32_t length = parameter_map->length() - 2;
1490 if (index < length) return index; 1487 if (entry < length) return entry;
1491 1488
1492 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1489 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1493 return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length); 1490 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length);
1494 } 1491 }
1495 1492
1496 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1493 static uint32_t GetEntryForIndexImpl(JSObject* holder,
1497 FixedArrayBase* parameters, uint32_t key) { 1494 FixedArrayBase* parameters,
1495 uint32_t index) {
1498 FixedArray* parameter_map = FixedArray::cast(parameters); 1496 FixedArray* parameter_map = FixedArray::cast(parameters);
1499 Object* probe = GetParameterMapArg(parameter_map, key); 1497 Object* probe = GetParameterMapArg(parameter_map, index);
1500 if (!probe->IsTheHole()) return key; 1498 if (!probe->IsTheHole()) return index;
1501 1499
1502 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1500 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1503 uint32_t index = 1501 uint32_t entry =
1504 ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key); 1502 ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, index);
1505 if (index == kMaxUInt32) return index; 1503 if (entry == kMaxUInt32) return entry;
1506 return (parameter_map->length() - 2) + index; 1504 return (parameter_map->length() - 2) + entry;
1507 } 1505 }
1508 1506
1509 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 1507 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1510 uint32_t index) { 1508 uint32_t entry) {
1511 FixedArray* parameter_map = FixedArray::cast(parameters); 1509 FixedArray* parameter_map = FixedArray::cast(parameters);
1512 uint32_t length = parameter_map->length() - 2; 1510 uint32_t length = parameter_map->length() - 2;
1513 if (index < length) { 1511 if (entry < length) {
1514 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1512 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1515 } 1513 }
1516 index -= length; 1514 entry -= length;
1517 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1515 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1518 return ArgumentsAccessor::GetDetailsImpl(arguments, index); 1516 return ArgumentsAccessor::GetDetailsImpl(arguments, entry);
1519 } 1517 }
1520 1518
1521 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { 1519 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t index) {
1522 uint32_t length = parameter_map->length() - 2; 1520 uint32_t length = parameter_map->length() - 2;
1523 return key < length 1521 return index < length
1524 ? parameter_map->get(key + 2) 1522 ? parameter_map->get(index + 2)
1525 : Object::cast(parameter_map->GetHeap()->the_hole_value()); 1523 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1526 } 1524 }
1527 1525
1528 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { 1526 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
1529 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1527 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1530 uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2; 1528 uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2;
1531 if (index < length) { 1529 if (entry < length) {
1532 // TODO(kmillikin): We could check if this was the last aliased 1530 // TODO(kmillikin): We could check if this was the last aliased
1533 // parameter, and revert to normal elements in that case. That 1531 // parameter, and revert to normal elements in that case. That
1534 // would enable GC of the context. 1532 // would enable GC of the context.
1535 parameter_map->set_the_hole(index + 2); 1533 parameter_map->set_the_hole(entry + 2);
1536 } else { 1534 } else {
1537 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments( 1535 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments(
1538 obj, index - length); 1536 obj, entry - length);
1539 } 1537 }
1540 } 1538 }
1541 }; 1539 };
1542 1540
1543 1541
1544 class SlowSloppyArgumentsElementsAccessor 1542 class SlowSloppyArgumentsElementsAccessor
1545 : public SloppyArgumentsElementsAccessor< 1543 : public SloppyArgumentsElementsAccessor<
1546 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 1544 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1547 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { 1545 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1548 public: 1546 public:
1549 explicit SlowSloppyArgumentsElementsAccessor(const char* name) 1547 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1550 : SloppyArgumentsElementsAccessor< 1548 : SloppyArgumentsElementsAccessor<
1551 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, 1549 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1552 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1550 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1553 1551
1554 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { 1552 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) {
1555 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1553 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1556 Handle<SeededNumberDictionary> dict( 1554 Handle<SeededNumberDictionary> dict(
1557 SeededNumberDictionary::cast(parameter_map->get(1))); 1555 SeededNumberDictionary::cast(parameter_map->get(1)));
1558 // TODO(verwaest): Remove reliance on key in Shrink. 1556 // TODO(verwaest): Remove reliance on index in Shrink.
1559 uint32_t key = GetKeyForIndexImpl(*dict, index); 1557 uint32_t index = GetIndexForEntryImpl(*dict, entry);
1560 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); 1558 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, entry);
1561 USE(result); 1559 USE(result);
1562 DCHECK(result->IsTrue()); 1560 DCHECK(result->IsTrue());
1563 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); 1561 Handle<FixedArray> new_elements =
1562 SeededNumberDictionary::Shrink(dict, index);
1564 parameter_map->set(1, *new_elements); 1563 parameter_map->set(1, *new_elements);
1565 } 1564 }
1566 1565
1567 static void AddImpl(Handle<JSObject> object, uint32_t key, 1566 static void AddImpl(Handle<JSObject> object, uint32_t index,
1568 Handle<Object> value, PropertyAttributes attributes, 1567 Handle<Object> value, PropertyAttributes attributes,
1569 uint32_t new_capacity) { 1568 uint32_t new_capacity) {
1570 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1569 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1571 Handle<FixedArrayBase> old_elements( 1570 Handle<FixedArrayBase> old_elements(
1572 FixedArrayBase::cast(parameter_map->get(1))); 1571 FixedArrayBase::cast(parameter_map->get(1)));
1573 Handle<SeededNumberDictionary> dictionary = 1572 Handle<SeededNumberDictionary> dictionary =
1574 old_elements->IsSeededNumberDictionary() 1573 old_elements->IsSeededNumberDictionary()
1575 ? Handle<SeededNumberDictionary>::cast(old_elements) 1574 ? Handle<SeededNumberDictionary>::cast(old_elements)
1576 : JSObject::NormalizeElements(object); 1575 : JSObject::NormalizeElements(object);
1577 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 1576 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1578 Handle<SeededNumberDictionary> new_dictionary = 1577 Handle<SeededNumberDictionary> new_dictionary =
1579 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details); 1578 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
1579 details);
1580 if (attributes != NONE) new_dictionary->set_requires_slow_elements(); 1580 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1581 if (*dictionary != *new_dictionary) { 1581 if (*dictionary != *new_dictionary) {
1582 FixedArray::cast(object->elements())->set(1, *new_dictionary); 1582 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1583 } 1583 }
1584 } 1584 }
1585 1585
1586 static void ReconfigureImpl(Handle<JSObject> object, 1586 static void ReconfigureImpl(Handle<JSObject> object,
1587 Handle<FixedArrayBase> store, uint32_t index, 1587 Handle<FixedArrayBase> store, uint32_t entry,
1588 Handle<Object> value, 1588 Handle<Object> value,
1589 PropertyAttributes attributes) { 1589 PropertyAttributes attributes) {
1590 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store); 1590 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1591 uint32_t length = parameter_map->length() - 2; 1591 uint32_t length = parameter_map->length() - 2;
1592 if (index < length) { 1592 if (entry < length) {
1593 Object* probe = parameter_map->get(index + 2); 1593 Object* probe = parameter_map->get(entry + 2);
1594 DCHECK(!probe->IsTheHole()); 1594 DCHECK(!probe->IsTheHole());
1595 Context* context = Context::cast(parameter_map->get(0)); 1595 Context* context = Context::cast(parameter_map->get(0));
1596 int context_index = Smi::cast(probe)->value(); 1596 int context_entry = Smi::cast(probe)->value();
1597 DCHECK(!context->get(context_index)->IsTheHole()); 1597 DCHECK(!context->get(context_entry)->IsTheHole());
1598 context->set(context_index, *value); 1598 context->set(context_entry, *value);
1599 1599
1600 // Redefining attributes of an aliased element destroys fast aliasing. 1600 // Redefining attributes of an aliased element destroys fast aliasing.
1601 parameter_map->set_the_hole(index + 2); 1601 parameter_map->set_the_hole(entry + 2);
1602 // For elements that are still writable we re-establish slow aliasing. 1602 // For elements that are still writable we re-establish slow aliasing.
1603 if ((attributes & READ_ONLY) == 0) { 1603 if ((attributes & READ_ONLY) == 0) {
1604 Isolate* isolate = store->GetIsolate(); 1604 Isolate* isolate = store->GetIsolate();
1605 value = isolate->factory()->NewAliasedArgumentsEntry(context_index); 1605 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry);
1606 } 1606 }
1607 1607
1608 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 1608 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1609 Handle<SeededNumberDictionary> arguments( 1609 Handle<SeededNumberDictionary> arguments(
1610 SeededNumberDictionary::cast(parameter_map->get(1))); 1610 SeededNumberDictionary::cast(parameter_map->get(1)));
1611 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index, 1611 arguments = SeededNumberDictionary::AddNumberEntry(arguments, entry,
1612 value, details); 1612 value, details);
1613 parameter_map->set(1, *arguments); 1613 parameter_map->set(1, *arguments);
1614 } else { 1614 } else {
1615 Handle<FixedArrayBase> arguments( 1615 Handle<FixedArrayBase> arguments(
1616 FixedArrayBase::cast(parameter_map->get(1))); 1616 FixedArrayBase::cast(parameter_map->get(1)));
1617 DictionaryElementsAccessor::ReconfigureImpl( 1617 DictionaryElementsAccessor::ReconfigureImpl(
1618 object, arguments, index - length, value, attributes); 1618 object, arguments, entry - length, value, attributes);
1619 } 1619 }
1620 } 1620 }
1621 }; 1621 };
1622 1622
1623 1623
1624 class FastSloppyArgumentsElementsAccessor 1624 class FastSloppyArgumentsElementsAccessor
1625 : public SloppyArgumentsElementsAccessor< 1625 : public SloppyArgumentsElementsAccessor<
1626 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, 1626 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1627 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { 1627 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
1628 public: 1628 public:
1629 explicit FastSloppyArgumentsElementsAccessor(const char* name) 1629 explicit FastSloppyArgumentsElementsAccessor(const char* name)
1630 : SloppyArgumentsElementsAccessor< 1630 : SloppyArgumentsElementsAccessor<
1631 FastSloppyArgumentsElementsAccessor, 1631 FastSloppyArgumentsElementsAccessor,
1632 FastHoleyObjectElementsAccessor, 1632 FastHoleyObjectElementsAccessor,
1633 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1633 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1634 1634
1635 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { 1635 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) {
1636 FixedArray* parameter_map = FixedArray::cast(obj->elements()); 1636 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1637 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1637 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1638 FastHoleyObjectElementsAccessor::DeleteCommon(obj, index, arguments); 1638 FastHoleyObjectElementsAccessor::DeleteCommon(obj, entry, arguments);
1639 } 1639 }
1640 1640
1641 static void AddImpl(Handle<JSObject> object, uint32_t key, 1641 static void AddImpl(Handle<JSObject> object, uint32_t index,
1642 Handle<Object> value, PropertyAttributes attributes, 1642 Handle<Object> value, PropertyAttributes attributes,
1643 uint32_t new_capacity) { 1643 uint32_t new_capacity) {
1644 DCHECK_EQ(NONE, attributes); 1644 DCHECK_EQ(NONE, attributes);
1645 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1645 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1646 Handle<FixedArrayBase> old_elements( 1646 Handle<FixedArrayBase> old_elements(
1647 FixedArrayBase::cast(parameter_map->get(1))); 1647 FixedArrayBase::cast(parameter_map->get(1)));
1648 if (old_elements->IsSeededNumberDictionary() || 1648 if (old_elements->IsSeededNumberDictionary() ||
1649 static_cast<uint32_t>(old_elements->length()) < new_capacity) { 1649 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1650 GrowCapacityAndConvertImpl(object, new_capacity); 1650 GrowCapacityAndConvertImpl(object, new_capacity);
1651 } 1651 }
1652 SetImpl(object->elements(), key, *value); 1652 SetImpl(object->elements(), index, *value);
1653 } 1653 }
1654 1654
1655 static void ReconfigureImpl(Handle<JSObject> object, 1655 static void ReconfigureImpl(Handle<JSObject> object,
1656 Handle<FixedArrayBase> store, uint32_t index, 1656 Handle<FixedArrayBase> store, uint32_t entry,
1657 Handle<Object> value, 1657 Handle<Object> value,
1658 PropertyAttributes attributes) { 1658 PropertyAttributes attributes) {
1659 Handle<SeededNumberDictionary> dictionary = 1659 Handle<SeededNumberDictionary> dictionary =
1660 JSObject::NormalizeElements(object); 1660 JSObject::NormalizeElements(object);
1661 FixedArray::cast(*store)->set(1, *dictionary); 1661 FixedArray::cast(*store)->set(1, *dictionary);
1662 uint32_t length = static_cast<uint32_t>(store->length()) - 2; 1662 uint32_t length = static_cast<uint32_t>(store->length()) - 2;
1663 if (index >= length) { 1663 if (entry >= length) {
1664 index = dictionary->FindEntry(index - length) + length; 1664 entry = dictionary->FindEntry(entry - length) + length;
1665 } 1665 }
1666 SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, index, 1666 SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, entry,
1667 value, attributes); 1667 value, attributes);
1668 } 1668 }
1669 1669
1670 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1670 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1671 FixedArrayBase* to, ElementsKind from_kind, 1671 FixedArrayBase* to, ElementsKind from_kind,
1672 uint32_t to_start, int packed_size, 1672 uint32_t to_start, int packed_size,
1673 int copy_size) { 1673 int copy_size) {
1674 DCHECK(!to->IsDictionary()); 1674 DCHECK(!to->IsDictionary());
1675 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { 1675 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
1676 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, 1676 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)); 1742 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
1743 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); 1743 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
1744 } 1744 }
1745 1745
1746 array->set_length(Smi::FromInt(length)); 1746 array->set_length(Smi::FromInt(length));
1747 JSObject::ValidateElements(array); 1747 JSObject::ValidateElements(array);
1748 } 1748 }
1749 } // namespace 1749 } // namespace
1750 1750
1751 1751
1752 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key, 1752 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t index,
1753 bool allow_appending) { 1753 bool allow_appending) {
1754 DisallowHeapAllocation no_allocation; 1754 DisallowHeapAllocation no_allocation;
1755 Object* raw_length = NULL; 1755 Object* raw_length = NULL;
1756 const char* elements_type = "array"; 1756 const char* elements_type = "array";
1757 if (obj->IsJSArray()) { 1757 if (obj->IsJSArray()) {
1758 JSArray* array = JSArray::cast(*obj); 1758 JSArray* array = JSArray::cast(*obj);
1759 raw_length = array->length(); 1759 raw_length = array->length();
1760 } else { 1760 } else {
1761 raw_length = Smi::FromInt(obj->elements()->length()); 1761 raw_length = Smi::FromInt(obj->elements()->length());
1762 elements_type = "object"; 1762 elements_type = "object";
1763 } 1763 }
1764 1764
1765 if (raw_length->IsNumber()) { 1765 if (raw_length->IsNumber()) {
1766 double n = raw_length->Number(); 1766 double n = raw_length->Number();
1767 if (FastI2D(FastD2UI(n)) == n) { 1767 if (FastI2D(FastD2UI(n)) == n) {
1768 int32_t int32_length = DoubleToInt32(n); 1768 int32_t int32_length = DoubleToInt32(n);
1769 uint32_t compare_length = static_cast<uint32_t>(int32_length); 1769 uint32_t compare_length = static_cast<uint32_t>(int32_length);
1770 if (allow_appending) compare_length++; 1770 if (allow_appending) compare_length++;
1771 if (key >= compare_length) { 1771 if (index >= compare_length) {
1772 PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ", 1772 PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ",
1773 elements_type, op, elements_type, static_cast<int>(int32_length), 1773 elements_type, op, elements_type, static_cast<int>(int32_length),
1774 static_cast<int>(key)); 1774 static_cast<int>(index));
1775 TraceTopFrame(obj->GetIsolate()); 1775 TraceTopFrame(obj->GetIsolate());
1776 PrintF("]\n"); 1776 PrintF("]\n");
1777 } 1777 }
1778 } else { 1778 } else {
1779 PrintF("[%s elements length not integer value in ", elements_type); 1779 PrintF("[%s elements length not integer value in ", elements_type);
1780 TraceTopFrame(obj->GetIsolate()); 1780 TraceTopFrame(obj->GetIsolate());
1781 PrintF("]\n"); 1781 PrintF("]\n");
1782 } 1782 }
1783 } else { 1783 } else {
1784 PrintF("[%s elements length not a number in ", elements_type); 1784 PrintF("[%s elements length not a number in ", elements_type);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 } else { 1837 } else {
1838 elms = Handle<FixedArrayBase>::cast( 1838 elms = Handle<FixedArrayBase>::cast(
1839 factory->NewFixedArrayWithHoles(number_of_elements)); 1839 factory->NewFixedArrayWithHoles(number_of_elements));
1840 } 1840 }
1841 1841
1842 // Fill in the content 1842 // Fill in the content
1843 switch (array->GetElementsKind()) { 1843 switch (array->GetElementsKind()) {
1844 case FAST_HOLEY_SMI_ELEMENTS: 1844 case FAST_HOLEY_SMI_ELEMENTS:
1845 case FAST_SMI_ELEMENTS: { 1845 case FAST_SMI_ELEMENTS: {
1846 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); 1846 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms);
1847 for (int index = 0; index < number_of_elements; index++) { 1847 for (int entry = 0; entry < number_of_elements; entry++) {
1848 smi_elms->set(index, (*args)[index], SKIP_WRITE_BARRIER); 1848 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER);
1849 } 1849 }
1850 break; 1850 break;
1851 } 1851 }
1852 case FAST_HOLEY_ELEMENTS: 1852 case FAST_HOLEY_ELEMENTS:
1853 case FAST_ELEMENTS: { 1853 case FAST_ELEMENTS: {
1854 DisallowHeapAllocation no_gc; 1854 DisallowHeapAllocation no_gc;
1855 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); 1855 WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
1856 Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms); 1856 Handle<FixedArray> object_elms = Handle<FixedArray>::cast(elms);
1857 for (int index = 0; index < number_of_elements; index++) { 1857 for (int entry = 0; entry < number_of_elements; entry++) {
1858 object_elms->set(index, (*args)[index], mode); 1858 object_elms->set(entry, (*args)[entry], mode);
1859 } 1859 }
1860 break; 1860 break;
1861 } 1861 }
1862 case FAST_HOLEY_DOUBLE_ELEMENTS: 1862 case FAST_HOLEY_DOUBLE_ELEMENTS:
1863 case FAST_DOUBLE_ELEMENTS: { 1863 case FAST_DOUBLE_ELEMENTS: {
1864 Handle<FixedDoubleArray> double_elms = 1864 Handle<FixedDoubleArray> double_elms =
1865 Handle<FixedDoubleArray>::cast(elms); 1865 Handle<FixedDoubleArray>::cast(elms);
1866 for (int index = 0; index < number_of_elements; index++) { 1866 for (int entry = 0; entry < number_of_elements; entry++) {
1867 double_elms->set(index, (*args)[index]->Number()); 1867 double_elms->set(entry, (*args)[entry]->Number());
1868 } 1868 }
1869 break; 1869 break;
1870 } 1870 }
1871 default: 1871 default:
1872 UNREACHABLE(); 1872 UNREACHABLE();
1873 break; 1873 break;
1874 } 1874 }
1875 1875
1876 array->set_elements(*elms); 1876 array->set_elements(*elms);
1877 array->set_length(Smi::FromInt(number_of_elements)); 1877 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]; 1898 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1899 ELEMENTS_LIST(ACCESSOR_DELETE) 1899 ELEMENTS_LIST(ACCESSOR_DELETE)
1900 #undef ACCESSOR_DELETE 1900 #undef ACCESSOR_DELETE
1901 elements_accessors_ = NULL; 1901 elements_accessors_ = NULL;
1902 } 1902 }
1903 1903
1904 1904
1905 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 1905 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
1906 } // namespace internal 1906 } // namespace internal
1907 } // namespace v8 1907 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/lookup-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698