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

Side by Side Diff: src/elements.cc

Issue 1316213008: Speedup JSReceiver::GetKeys (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Removing UnionOfKey Created 5 years, 3 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/objects.h » ('j') | src/objects.h » ('J')
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/elements.h" 5 #include "src/elements.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/factory.h" 9 #include "src/factory.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 #define ELEMENTS_TRAITS(Class, KindParam, Store) \ 90 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
91 template<> class ElementsKindTraits<KindParam> { \ 91 template<> class ElementsKindTraits<KindParam> { \
92 public: /* NOLINT */ \ 92 public: /* NOLINT */ \
93 static const ElementsKind Kind = KindParam; \ 93 static const ElementsKind Kind = KindParam; \
94 typedef Store BackingStore; \ 94 typedef Store BackingStore; \
95 }; 95 };
96 ELEMENTS_LIST(ELEMENTS_TRAITS) 96 ELEMENTS_LIST(ELEMENTS_TRAITS)
97 #undef ELEMENTS_TRAITS 97 #undef ELEMENTS_TRAITS
98 98
99 99
100 static bool HasIndex(Handle<FixedArray> array, Handle<Object> index_handle) {
101 DisallowHeapAllocation no_gc;
102 Object* index = *index_handle;
103 int len0 = array->length();
104 for (int i = 0; i < len0; i++) {
105 Object* element = array->get(i);
106 if (index->KeyEquals(element)) return true;
107 }
108 return false;
109 }
110
111
112 MUST_USE_RESULT 100 MUST_USE_RESULT
113 MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) { 101 MaybeHandle<Object> ThrowArrayLengthRangeError(Isolate* isolate) {
114 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength), 102 THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kInvalidArrayLength),
115 Object); 103 Object);
116 } 104 }
117 105
118 106
119 void CopyObjectToObjectElements(FixedArrayBase* from_base, 107 void CopyObjectToObjectElements(FixedArrayBase* from_base,
120 ElementsKind from_kind, uint32_t from_start, 108 ElementsKind from_kind, uint32_t from_start,
121 FixedArrayBase* to_base, ElementsKind to_kind, 109 FixedArrayBase* to_base, ElementsKind to_kind,
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 // intentionally to avoid ArrayConcat() builtin performance degradation. 840 // intentionally to avoid ArrayConcat() builtin performance degradation.
853 // 841 //
854 // Details: The idea is that allocations actually happen only in case of 842 // Details: The idea is that allocations actually happen only in case of
855 // copying from object with fast double elements to object with object 843 // copying from object with fast double elements to object with object
856 // elements. In all the other cases there are no allocations performed and 844 // elements. In all the other cases there are no allocations performed and
857 // handle creation causes noticeable performance degradation of the builtin. 845 // handle creation causes noticeable performance degradation of the builtin.
858 ElementsAccessorSubclass::CopyElementsImpl( 846 ElementsAccessorSubclass::CopyElementsImpl(
859 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 847 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
860 } 848 }
861 849
862 virtual Handle<FixedArray> AddElementsToFixedArray( 850 virtual void AddElementsToFixedArrayWithAccumulator(
863 Handle<JSObject> receiver, Handle<FixedArray> to, 851 Handle<JSObject> receiver, KeyAccumulator* accumulator,
864 FixedArray::KeyFilter filter) final { 852 FixedArray::KeyFilter filter) final {
865 Handle<FixedArrayBase> from(receiver->elements()); 853 Handle<FixedArrayBase> from(receiver->elements());
866 854 uint32_t add_length =
867 int len0 = to->length(); 855 ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
868 #ifdef ENABLE_SLOW_DCHECKS 856 if (add_length == 0) return;
869 if (FLAG_enable_slow_asserts) { 857 accumulator->PrepareForComparisons(add_length);
870 for (int i = 0; i < len0; i++) { 858 int prev_key_count = accumulator->GetLength();
871 DCHECK(!to->get(i)->IsTheHole()); 859 for (uint32_t i = 0; i < add_length; i++) {
860 if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue;
861 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i);
862 DCHECK(!value->IsAccessorPair());
863 DCHECK(!value->IsExecutableAccessorInfo());
864 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
865 continue;
866 }
867 if (!value->IsTheHole() && !accumulator->HasKey(value, prev_key_count)) {
868 accumulator->AddKey(value);
872 } 869 }
873 } 870 }
874 #endif
875
876 // Optimize if 'other' is empty.
877 // We cannot optimize if 'this' is empty, as other may have holes.
878 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
879 if (len1 == 0) return to;
880
881 Isolate* isolate = from->GetIsolate();
882
883 // Compute how many elements are not in other.
884 uint32_t extra = 0;
885 for (uint32_t y = 0; y < len1; y++) {
886 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
887 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, y);
888
889 DCHECK(!value->IsTheHole());
890 DCHECK(!value->IsAccessorPair());
891 DCHECK(!value->IsExecutableAccessorInfo());
892 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
893 continue;
894 }
895 if (!HasIndex(to, value)) {
896 extra++;
897 }
898 }
899 }
900
901 if (extra == 0) return to;
902
903 // Allocate the result
904 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra);
905
906 // Fill in the content
907 {
908 DisallowHeapAllocation no_gc;
909 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
910 for (int i = 0; i < len0; i++) {
911 Object* e = to->get(i);
912 DCHECK(e->IsString() || e->IsNumber());
913 result->set(i, e, mode);
914 }
915 }
916 // Fill in the extra values.
917 uint32_t entry = 0;
918 for (uint32_t y = 0; y < len1; y++) {
919 if (ElementsAccessorSubclass::HasEntryImpl(*from, y)) {
920 Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, y);
921 DCHECK(!value->IsAccessorPair());
922 DCHECK(!value->IsExecutableAccessorInfo());
923 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
924 continue;
925 }
926 if (!value->IsTheHole() && !HasIndex(to, value)) {
927 result->set(len0 + entry, *value);
928 entry++;
929 }
930 }
931 }
932 DCHECK(extra == entry);
933 return result;
934 } 871 }
935 872
936 static uint32_t GetCapacityImpl(JSObject* holder, 873 static uint32_t GetCapacityImpl(JSObject* holder,
937 FixedArrayBase* backing_store) { 874 FixedArrayBase* backing_store) {
938 return backing_store->length(); 875 return backing_store->length();
939 } 876 }
940 877
941 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 878 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
942 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 879 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
943 } 880 }
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 } 2346 }
2410 } 2347 }
2411 2348
2412 DCHECK(j == result_len); 2349 DCHECK(j == result_len);
2413 return result_array; 2350 return result_array;
2414 } 2351 }
2415 2352
2416 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2353 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2417 } // namespace internal 2354 } // namespace internal
2418 } // namespace v8 2355 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698