| 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/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 convert, filter); | 975 convert, filter); |
| 976 } | 976 } |
| 977 | 977 |
| 978 static Handle<FixedArray> PrependElementIndicesImpl( | 978 static Handle<FixedArray> PrependElementIndicesImpl( |
| 979 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, | 979 Handle<JSObject> object, Handle<FixedArrayBase> backing_store, |
| 980 Handle<FixedArray> keys, GetKeysConversion convert, | 980 Handle<FixedArray> keys, GetKeysConversion convert, |
| 981 PropertyFilter filter) { | 981 PropertyFilter filter) { |
| 982 Isolate* isolate = object->GetIsolate(); | 982 Isolate* isolate = object->GetIsolate(); |
| 983 uint32_t nof_property_keys = keys->length(); | 983 uint32_t nof_property_keys = keys->length(); |
| 984 uint32_t initial_list_length = | 984 uint32_t initial_list_length = |
| 985 Subclass::GetCapacityImpl(*object, *backing_store); | 985 Subclass::GetMaxNumberOfEntries(*object, *backing_store); |
| 986 initial_list_length += nof_property_keys; | 986 initial_list_length += nof_property_keys; |
| 987 | 987 |
| 988 bool needs_sorting = |
| 989 IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind()); |
| 990 |
| 988 // Collect the element indices into a new list. | 991 // Collect the element indices into a new list. |
| 989 uint32_t nof_indices = 0; | 992 uint32_t nof_indices = 0; |
| 990 Handle<FixedArray> combined_keys = | 993 Handle<FixedArray> combined_keys = |
| 991 isolate->factory()->NewFixedArray(initial_list_length); | 994 isolate->factory()->NewFixedArray(initial_list_length); |
| 992 combined_keys = Subclass::DirectCollectElementIndicesImpl( | 995 combined_keys = Subclass::DirectCollectElementIndicesImpl( |
| 993 isolate, object, backing_store, convert, filter, combined_keys, | 996 isolate, object, backing_store, |
| 994 &nof_indices); | 997 needs_sorting ? GetKeysConversion::kKeepNumbers : convert, filter, |
| 998 combined_keys, &nof_indices); |
| 995 | 999 |
| 996 // Sort the indices list if necessary. | 1000 if (needs_sorting) { |
| 997 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { | |
| 998 SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER); | 1001 SortIndices(combined_keys, nof_indices, SKIP_WRITE_BARRIER); |
| 999 uint32_t array_length = 0; | 1002 uint32_t array_length = 0; |
| 1000 // Indices from dictionary elements should only be converted after | 1003 // Indices from dictionary elements should only be converted after |
| 1001 // sorting. | 1004 // sorting. |
| 1002 if (convert == GetKeysConversion::kConvertToString) { | 1005 if (convert == GetKeysConversion::kConvertToString) { |
| 1003 for (uint32_t i = 0; i < nof_indices; i++) { | 1006 for (uint32_t i = 0; i < nof_indices; i++) { |
| 1004 Handle<Object> index_string = isolate->factory()->Uint32ToString( | 1007 Handle<Object> index_string = isolate->factory()->Uint32ToString( |
| 1005 combined_keys->get(i)->Number()); | 1008 combined_keys->get(i)->Number()); |
| 1006 combined_keys->set(i, *index_string); | 1009 combined_keys->set(i, *index_string); |
| 1007 } | 1010 } |
| 1008 } else if (!(object->IsJSArray() && | 1011 } else if (!(object->IsJSArray() && |
| 1009 JSArray::cast(*object)->length()->ToArrayLength( | 1012 JSArray::cast(*object)->length()->ToArrayLength( |
| 1010 &array_length) && | 1013 &array_length) && |
| 1011 array_length <= Smi::kMaxValue)) { | 1014 array_length <= Smi::kMaxValue)) { |
| 1012 // Since we use std::sort above, the GC will no longer know where the | 1015 // Since we use std::sort above, the GC will no longer know where the |
| 1013 // HeapNumbers are. For Arrays with valid Smi length, we are sure to | 1016 // HeapNumbers are. For Arrays with valid Smi length, we are sure to |
| 1014 // have no HeapNumber indices and thus we can skip this step. | 1017 // have no HeapNumber indices and thus we can skip this step. |
| 1015 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(isolate->heap(), *combined_keys, 0, | 1018 FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(isolate->heap(), *combined_keys, 0, |
| 1016 nof_indices); | 1019 nof_indices); |
| 1017 } | 1020 } |
| 1018 } | 1021 } |
| 1019 | 1022 |
| 1020 // Copy over the passed-in property keys. | 1023 // Copy over the passed-in property keys. |
| 1021 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, | 1024 CopyObjectToObjectElements(*keys, FAST_ELEMENTS, 0, *combined_keys, |
| 1022 FAST_ELEMENTS, nof_indices, nof_property_keys); | 1025 FAST_ELEMENTS, nof_indices, nof_property_keys); |
| 1023 | 1026 |
| 1024 if (IsHoleyElementsKind(kind())) { | 1027 // For holey elements and arguments we might have to shrink the collected |
| 1028 // keys since the estimates might be off. |
| 1029 if (IsHoleyElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
| 1025 // Shrink combined_keys to the final size. | 1030 // Shrink combined_keys to the final size. |
| 1026 int final_size = nof_indices + nof_property_keys; | 1031 int final_size = nof_indices + nof_property_keys; |
| 1027 DCHECK_LE(final_size, combined_keys->length()); | 1032 DCHECK_LE(final_size, combined_keys->length()); |
| 1028 combined_keys->Shrink(final_size); | 1033 combined_keys->Shrink(final_size); |
| 1029 } | 1034 } |
| 1030 | 1035 |
| 1031 return combined_keys; | 1036 return combined_keys; |
| 1032 } | 1037 } |
| 1033 | 1038 |
| 1034 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, | 1039 void AddElementsToKeyAccumulator(Handle<JSObject> receiver, |
| (...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2298 } | 2303 } |
| 2299 | 2304 |
| 2300 static uint32_t GetCapacityImpl(JSObject* holder, | 2305 static uint32_t GetCapacityImpl(JSObject* holder, |
| 2301 FixedArrayBase* backing_store) { | 2306 FixedArrayBase* backing_store) { |
| 2302 FixedArray* parameter_map = FixedArray::cast(backing_store); | 2307 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 2303 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 2308 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 2304 return parameter_map->length() - 2 + | 2309 return parameter_map->length() - 2 + |
| 2305 ArgumentsAccessor::GetCapacityImpl(holder, arguments); | 2310 ArgumentsAccessor::GetCapacityImpl(holder, arguments); |
| 2306 } | 2311 } |
| 2307 | 2312 |
| 2313 static uint32_t GetMaxNumberOfEntries(JSObject* holder, |
| 2314 FixedArrayBase* backing_store) { |
| 2315 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 2316 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 2317 return parameter_map->length() - 2 + |
| 2318 ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments); |
| 2319 } |
| 2320 |
| 2308 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, | 2321 static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver, |
| 2309 KeyAccumulator* accumulator, | 2322 KeyAccumulator* accumulator, |
| 2310 AddKeyConversion convert) { | 2323 AddKeyConversion convert) { |
| 2311 FixedArrayBase* elements = receiver->elements(); | 2324 FixedArrayBase* elements = receiver->elements(); |
| 2312 uint32_t length = GetCapacityImpl(*receiver, elements); | 2325 uint32_t length = GetCapacityImpl(*receiver, elements); |
| 2313 for (uint32_t entry = 0; entry < length; entry++) { | 2326 for (uint32_t entry = 0; entry < length; entry++) { |
| 2314 if (!HasEntryImpl(elements, entry)) continue; | 2327 if (!HasEntryImpl(elements, entry)) continue; |
| 2315 Handle<Object> value = GetImpl(elements, entry); | 2328 Handle<Object> value = GetImpl(elements, entry); |
| 2316 accumulator->AddKey(value, convert); | 2329 accumulator->AddKey(value, convert); |
| 2317 } | 2330 } |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3030 insertion_index += len; | 3043 insertion_index += len; |
| 3031 } | 3044 } |
| 3032 | 3045 |
| 3033 DCHECK_EQ(insertion_index, result_len); | 3046 DCHECK_EQ(insertion_index, result_len); |
| 3034 return result_array; | 3047 return result_array; |
| 3035 } | 3048 } |
| 3036 | 3049 |
| 3037 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3050 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 3038 } // namespace internal | 3051 } // namespace internal |
| 3039 } // namespace v8 | 3052 } // namespace v8 |
| OLD | NEW |