Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 97d67b121957f2ea9ad01d9fa6a3b8452a861876..5261b6a5ff931381d463e3fda522e23e24ad8389 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -12150,6 +12150,12 @@ MaybeObject* Dictionary<Shape, Key>::Allocate(int at_least_space_for) { |
} |
+void StringDictionary::DoGenerateNewEnumerationIndices( |
+ Handle<StringDictionary> dictionary) { |
+ CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
+ dictionary->GenerateNewEnumerationIndices()); |
+} |
+ |
template<typename Shape, typename Key> |
MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
@@ -12468,23 +12474,43 @@ void Dictionary<Shape, Key>::CopyKeysTo( |
} |
-void StringDictionary::CopyEnumKeysTo(FixedArray* storage, |
- FixedArray* sort_array) { |
- ASSERT(storage->length() >= NumberOfEnumElements()); |
+void StringDictionary::CopyEnumKeysTo(FixedArray* storage) { |
+ int length = storage->length(); |
+ ASSERT(length >= NumberOfEnumElements()); |
+ Heap* heap = GetHeap(); |
+ Object* undefined_value = heap->undefined_value(); |
int capacity = Capacity(); |
- int index = 0; |
+ int properties = 0; |
+ |
+ // Fill in the enumeration array by assigning enumerable keys at their |
+ // enumeration index. This will leave holes in the array if there are keys |
+ // that are deleted or not enumerable. |
for (int i = 0; i < capacity; i++) { |
Object* k = KeyAt(i); |
if (IsKey(k)) { |
PropertyDetails details = DetailsAt(i); |
if (details.IsDeleted() || details.IsDontEnum()) continue; |
- storage->set(index, k); |
- sort_array->set(index, Smi::FromInt(details.dictionary_index())); |
- index++; |
+ properties++; |
+ storage->set(details.dictionary_index() - 1, k); |
+ if (properties == length) break; |
} |
} |
- storage->SortPairs(sort_array, sort_array->length()); |
- ASSERT(storage->length() >= index); |
+ |
+ // There are holes in the enumeration array if less properties were assigned |
+ // than the length of the array. If so, crunch all the existing properties |
+ // together by shifting them to the left (maintaining the enumeration order), |
+ // and trimming of the right side of the array. |
+ if (properties < length) { |
+ properties = 0; |
+ for (int i = 0; i < length; ++i) { |
+ Object* value = storage->get(i); |
+ if (value != undefined_value) { |
+ storage->set(properties, value); |
+ ++properties; |
+ } |
+ } |
+ RightTrimFixedArray<FROM_MUTATOR>(heap, storage, length - properties); |
+ } |
} |