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

Side by Side Diff: src/elements.cc

Issue 1807173002: [elements] Fix sorting dictionary element keys (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: specializing GetIterationLength for DICTIONARY_ELEMENTS Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | 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/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 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity); 715 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(array, capacity);
716 } 716 }
717 717
718 array->set_length(Smi::FromInt(length)); 718 array->set_length(Smi::FromInt(length));
719 JSObject::ValidateElements(array); 719 JSObject::ValidateElements(array);
720 } 720 }
721 721
722 static uint32_t GetIterationLength(JSObject* receiver, 722 static uint32_t GetIterationLength(JSObject* receiver,
723 FixedArrayBase* elements) { 723 FixedArrayBase* elements) {
724 if (receiver->IsJSArray()) { 724 if (receiver->IsJSArray()) {
725 DCHECK(JSArray::cast(receiver)->length()->IsSmi());
725 return static_cast<uint32_t>( 726 return static_cast<uint32_t>(
726 Smi::cast(JSArray::cast(receiver)->length())->value()); 727 Smi::cast(JSArray::cast(receiver)->length())->value());
727 } else {
728 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
729 } 728 }
729 return ElementsAccessorSubclass::GetCapacityImpl(receiver, elements);
730 } 730 }
731 731
732 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 732 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
733 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 733 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
734 ElementsKind from_kind, uint32_t capacity) { 734 ElementsKind from_kind, uint32_t capacity) {
735 return ConvertElementsWithCapacity( 735 return ConvertElementsWithCapacity(
736 object, old_elements, from_kind, capacity, 0, 0, 736 object, old_elements, from_kind, capacity, 0, 0,
737 ElementsAccessor::kCopyToEndAndInitializeToHole); 737 ElementsAccessor::kCopyToEndAndInitializeToHole);
738 } 738 }
739 739
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 if (!a->IsUndefined()) { 939 if (!a->IsUndefined()) {
940 if (b->IsUndefined()) return true; 940 if (b->IsUndefined()) return true;
941 return a->Number() < b->Number(); 941 return a->Number() < b->Number();
942 } 942 }
943 return !b->IsUndefined(); 943 return !b->IsUndefined();
944 } 944 }
945 } cmp; 945 } cmp;
946 Object** start = 946 Object** start =
947 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress()); 947 reinterpret_cast<Object**>(combined_keys->GetFirstElementAddress());
948 std::sort(start, start + nof_indices, cmp); 948 std::sort(start, start + nof_indices, cmp);
949 uint32_t array_length = 0;
949 // Indices from dictionary elements should only be converted after 950 // Indices from dictionary elements should only be converted after
950 // sorting. 951 // sorting.
951 if (convert == CONVERT_TO_STRING) { 952 if (convert == CONVERT_TO_STRING) {
952 for (uint32_t i = 0; i < nof_indices; i++) { 953 for (uint32_t i = 0; i < nof_indices; i++) {
953 Handle<Object> index_string = isolate->factory()->Uint32ToString( 954 Handle<Object> index_string = isolate->factory()->Uint32ToString(
954 combined_keys->get(i)->Number()); 955 combined_keys->get(i)->Number());
955 combined_keys->set(i, *index_string); 956 combined_keys->set(i, *index_string);
956 } 957 }
958 } else if (!(object->IsJSArray() &&
959 JSArray::cast(*object)->length()->ToArrayLength(
960 &array_length) &&
961 array_length <= Smi::kMaxValue)) {
962 // Since we use std::sort above, the GC will no longer know where the
963 // HeapNumbers are, hence we have to write them again.
964 // For Arrays with valid Smi length, we are sure to have no HeapNumber
965 // indices and thus we can skip this step.
966 for (uint32_t i = 0; i < nof_indices; i++) {
967 Object* index = combined_keys->get(i);
968 combined_keys->set(i, index);
969 }
957 } 970 }
958 } 971 }
959 972
960 // Copy over the passed-in property keys. 973 // Copy over the passed-in property keys.
961 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, 974 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys,
962 FAST_ELEMENTS, nof_indices, nof_property_keys); 975 FAST_ELEMENTS, nof_indices, nof_property_keys);
963 976
964 if (IsHoleyElementsKind(kind())) { 977 if (IsHoleyElementsKind(kind())) {
965 // Shrink combined_keys to the final size. 978 // Shrink combined_keys to the final size.
966 int final_size = nof_indices + nof_property_keys; 979 int final_size = nof_indices + nof_property_keys;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 1045
1033 1046
1034 class DictionaryElementsAccessor 1047 class DictionaryElementsAccessor
1035 : public ElementsAccessorBase<DictionaryElementsAccessor, 1048 : public ElementsAccessorBase<DictionaryElementsAccessor,
1036 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1049 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1037 public: 1050 public:
1038 explicit DictionaryElementsAccessor(const char* name) 1051 explicit DictionaryElementsAccessor(const char* name)
1039 : ElementsAccessorBase<DictionaryElementsAccessor, 1052 : ElementsAccessorBase<DictionaryElementsAccessor,
1040 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1053 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1041 1054
1055 static uint32_t GetIterationLength(JSObject* receiver,
1056 FixedArrayBase* elements) {
1057 uint32_t length;
1058 if (receiver->IsJSArray()) {
1059 // Special-case GetIterationLength for dictionary elements since the
1060 // length of the array might be a HeapNumber.
1061 JSArray::cast(receiver)->length()->ToArrayLength(&length);
1062 } else {
1063 length = GetCapacityImpl(receiver, elements);
1064 }
1065 return length;
1066 }
1067
1042 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, 1068 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
1043 uint32_t length, 1069 uint32_t length,
1044 Handle<FixedArrayBase> backing_store) { 1070 Handle<FixedArrayBase> backing_store) {
1045 Handle<SeededNumberDictionary> dict = 1071 Handle<SeededNumberDictionary> dict =
1046 Handle<SeededNumberDictionary>::cast(backing_store); 1072 Handle<SeededNumberDictionary>::cast(backing_store);
1047 int capacity = dict->Capacity(); 1073 int capacity = dict->Capacity();
1048 uint32_t old_length = 0; 1074 uint32_t old_length = 0;
1049 CHECK(array->length()->ToArrayLength(&old_length)); 1075 CHECK(array->length()->ToArrayLength(&old_length));
1050 if (length < old_length) { 1076 if (length < old_length) {
1051 if (dict->requires_slow_elements()) { 1077 if (dict->requires_slow_elements()) {
(...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 } 2935 }
2910 } 2936 }
2911 2937
2912 DCHECK(j == result_len); 2938 DCHECK(j == result_len);
2913 return result_array; 2939 return result_array;
2914 } 2940 }
2915 2941
2916 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2942 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2917 } // namespace internal 2943 } // namespace internal
2918 } // namespace v8 2944 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698