| 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 |