OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |