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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 859 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
860 filter)) { | 860 filter)) { |
861 keys->AddKey(i); | 861 keys->AddKey(i); |
862 } | 862 } |
863 } | 863 } |
864 } | 864 } |
865 | 865 |
866 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 866 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
867 Isolate* isolate, Handle<JSObject> object, | 867 Isolate* isolate, Handle<JSObject> object, |
868 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 868 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
869 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { | 869 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 870 uint32_t insertion_index = 0) { |
870 uint32_t length = | 871 uint32_t length = |
871 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); | 872 ElementsAccessorSubclass::GetIterationLength(*object, *backing_store); |
872 uint32_t insertion_index = 0; | |
873 for (uint32_t i = 0; i < length; i++) { | 873 for (uint32_t i = 0; i < length; i++) { |
874 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, | 874 if (ElementsAccessorSubclass::HasElementImpl(object, i, backing_store, |
875 filter)) { | 875 filter)) { |
876 if (convert == CONVERT_TO_STRING) { | 876 if (convert == CONVERT_TO_STRING) { |
877 Handle<String> index_string = isolate->factory()->Uint32ToString(i); | 877 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
878 list->set(insertion_index, *index_string); | 878 list->set(insertion_index, *index_string); |
879 } else { | 879 } else { |
880 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); | 880 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
881 } | 881 } |
882 insertion_index++; | 882 insertion_index++; |
(...skipping 24 matching lines...) Expand all Loading... |
907 | 907 |
908 // Collect the element indices into a new list. | 908 // Collect the element indices into a new list. |
909 uint32_t nof_indices = 0; | 909 uint32_t nof_indices = 0; |
910 Handle<FixedArray> combined_keys = | 910 Handle<FixedArray> combined_keys = |
911 isolate->factory()->NewFixedArray(initial_list_length); | 911 isolate->factory()->NewFixedArray(initial_list_length); |
912 combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl( | 912 combined_keys = ElementsAccessorSubclass::DirectCollectElementIndicesImpl( |
913 isolate, object, backing_store, convert, filter, combined_keys, | 913 isolate, object, backing_store, convert, filter, combined_keys, |
914 &nof_indices); | 914 &nof_indices); |
915 | 915 |
916 // Sort the indices list if necessary. | 916 // Sort the indices list if necessary. |
917 if (IsDictionaryElementsKind(kind())) { | 917 if (IsDictionaryElementsKind(kind()) || IsSloppyArgumentsElements(kind())) { |
918 struct { | 918 struct { |
919 bool operator()(Object* a, Object* b) { | 919 bool operator()(Object* a, Object* b) { |
920 if (!a->IsUndefined()) { | 920 if (!a->IsUndefined()) { |
921 if (b->IsUndefined()) return true; | 921 if (b->IsUndefined()) return true; |
922 return a->Number() < b->Number(); | 922 return a->Number() < b->Number(); |
923 } | 923 } |
924 return !b->IsUndefined(); | 924 return !b->IsUndefined(); |
925 } | 925 } |
926 } cmp; | 926 } cmp; |
927 Object** start = | 927 Object** start = |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 if (key == kMaxUInt32) continue; | 1220 if (key == kMaxUInt32) continue; |
1221 keys->AddKey(key); | 1221 keys->AddKey(key); |
1222 } | 1222 } |
1223 | 1223 |
1224 keys->SortCurrentElementsList(); | 1224 keys->SortCurrentElementsList(); |
1225 } | 1225 } |
1226 | 1226 |
1227 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 1227 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
1228 Isolate* isolate, Handle<JSObject> object, | 1228 Isolate* isolate, Handle<JSObject> object, |
1229 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 1229 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
1230 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices) { | 1230 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 1231 uint32_t insertion_index = 0) { |
1231 Handle<SeededNumberDictionary> dictionary = | 1232 Handle<SeededNumberDictionary> dictionary = |
1232 Handle<SeededNumberDictionary>::cast(backing_store); | 1233 Handle<SeededNumberDictionary>::cast(backing_store); |
1233 uint32_t capacity = dictionary->Capacity(); | 1234 uint32_t capacity = dictionary->Capacity(); |
1234 uint32_t insertion_index = 0; | |
1235 for (uint32_t i = 0; i < capacity; i++) { | 1235 for (uint32_t i = 0; i < capacity; i++) { |
1236 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); | 1236 uint32_t key = GetKeyForEntryImpl(dictionary, i, filter); |
1237 if (key == kMaxUInt32) continue; | 1237 if (key == kMaxUInt32) continue; |
1238 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); | 1238 Handle<Object> index = isolate->factory()->NewNumberFromUint(key); |
1239 list->set(insertion_index, *index); | 1239 list->set(insertion_index, *index); |
1240 insertion_index++; | 1240 insertion_index++; |
1241 } | 1241 } |
1242 *nof_indices = insertion_index; | 1242 *nof_indices = insertion_index; |
1243 return list; | 1243 return list; |
1244 } | 1244 } |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 if (entry < length) { | 2216 if (entry < length) { |
2217 // TODO(kmillikin): We could check if this was the last aliased | 2217 // TODO(kmillikin): We could check if this was the last aliased |
2218 // parameter, and revert to normal elements in that case. That | 2218 // parameter, and revert to normal elements in that case. That |
2219 // would enable GC of the context. | 2219 // would enable GC of the context. |
2220 parameter_map->set_the_hole(entry + 2); | 2220 parameter_map->set_the_hole(entry + 2); |
2221 } else { | 2221 } else { |
2222 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments( | 2222 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments( |
2223 obj, entry - length); | 2223 obj, entry - length); |
2224 } | 2224 } |
2225 } | 2225 } |
| 2226 |
| 2227 static void CollectElementIndicesImpl(Handle<JSObject> object, |
| 2228 Handle<FixedArrayBase> backing_store, |
| 2229 KeyAccumulator* keys, uint32_t range, |
| 2230 PropertyFilter filter, |
| 2231 uint32_t offset) { |
| 2232 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
| 2233 uint32_t length = parameter_map->length() - 2; |
| 2234 if (range < length) length = range; |
| 2235 |
| 2236 for (uint32_t i = offset; i < length; ++i) { |
| 2237 if (!parameter_map->get(i + 2)->IsTheHole()) { |
| 2238 keys->AddKey(i); |
| 2239 } |
| 2240 } |
| 2241 |
| 2242 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
| 2243 ArgumentsAccessor::CollectElementIndicesImpl(object, store, keys, range, |
| 2244 filter, offset); |
| 2245 if (SloppyArgumentsElementsAccessorSubclass::kind() == |
| 2246 FAST_SLOPPY_ARGUMENTS_ELEMENTS) { |
| 2247 keys->SortCurrentElementsList(); |
| 2248 } |
| 2249 } |
| 2250 |
| 2251 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
| 2252 Isolate* isolate, Handle<JSObject> object, |
| 2253 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
| 2254 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
| 2255 uint32_t insertion_index = 0) { |
| 2256 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
| 2257 uint32_t length = parameter_map->length() - 2; |
| 2258 |
| 2259 for (uint32_t i = 0; i < length; ++i) { |
| 2260 if (parameter_map->get(i + 2)->IsTheHole()) continue; |
| 2261 if (convert == CONVERT_TO_STRING) { |
| 2262 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
| 2263 list->set(insertion_index, *index_string); |
| 2264 } else { |
| 2265 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
| 2266 } |
| 2267 insertion_index++; |
| 2268 } |
| 2269 |
| 2270 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
| 2271 return ArgumentsAccessor::DirectCollectElementIndicesImpl( |
| 2272 isolate, object, store, convert, filter, list, nof_indices, |
| 2273 insertion_index); |
| 2274 } |
2226 }; | 2275 }; |
2227 | 2276 |
2228 | 2277 |
2229 class SlowSloppyArgumentsElementsAccessor | 2278 class SlowSloppyArgumentsElementsAccessor |
2230 : public SloppyArgumentsElementsAccessor< | 2279 : public SloppyArgumentsElementsAccessor< |
2231 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, | 2280 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, |
2232 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { | 2281 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { |
2233 public: | 2282 public: |
2234 explicit SlowSloppyArgumentsElementsAccessor(const char* name) | 2283 explicit SlowSloppyArgumentsElementsAccessor(const char* name) |
2235 : SloppyArgumentsElementsAccessor< | 2284 : SloppyArgumentsElementsAccessor< |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2774 } | 2823 } |
2775 } | 2824 } |
2776 | 2825 |
2777 DCHECK(j == result_len); | 2826 DCHECK(j == result_len); |
2778 return result_array; | 2827 return result_array; |
2779 } | 2828 } |
2780 | 2829 |
2781 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2830 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2782 } // namespace internal | 2831 } // namespace internal |
2783 } // namespace v8 | 2832 } // namespace v8 |
OLD | NEW |