| 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);
|
| + }
|
| }
|
|
|
|
|
|
|