Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 7495d6e7099fcb7e6c8c02a36fc7249fd7e707d8..8479402e4a850a9db55bdb07e054332ad31d0ff3 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -2896,9 +2896,12 @@ MaybeObject* JSObject::NormalizeElements() { |
| int length = IsJSArray() |
| ? Smi::cast(JSArray::cast(this)->length())->value() |
| : array->length(); |
| + int old_capacity = 0; |
| + int used_elements = 0; |
| + GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| NumberDictionary* dictionary = NULL; |
| { Object* object; |
| - MaybeObject* maybe = NumberDictionary::Allocate(length); |
| + MaybeObject* maybe = NumberDictionary::Allocate(used_elements); |
| if (!maybe->ToObject(&object)) return maybe; |
| dictionary = NumberDictionary::cast(object); |
| } |
| @@ -9083,62 +9086,69 @@ MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
| bool JSObject::HasDenseElements() { |
| int capacity = 0; |
| - int number_of_elements = 0; |
| + int used = 0; |
| + GetElementsCapacityAndUsage(&capacity, &used); |
| + return (capacity == 0) || (used > (capacity / 2)); |
| +} |
| + |
| + |
| +void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { |
| + *capacity = 0; |
| + *used = 0; |
| FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
| FixedArray* backing_store = NULL; |
| - switch (GetElementsKind()) { |
| + ElementsKind kind = GetElementsKind(); |
| + switch (kind) { |
| case NON_STRICT_ARGUMENTS_ELEMENTS: |
| backing_store_base = |
| FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
| backing_store = FixedArray::cast(backing_store_base); |
| if (backing_store->IsDictionary()) { |
| NumberDictionary* dictionary = NumberDictionary::cast(backing_store); |
| - capacity = dictionary->Capacity(); |
| - number_of_elements = dictionary->NumberOfElements(); |
| + *capacity = dictionary->Capacity(); |
| + *used = dictionary->NumberOfElements(); |
| break; |
| } |
| // Fall through. |
| case FAST_ELEMENTS: |
| backing_store = FixedArray::cast(backing_store_base); |
| - capacity = backing_store->length(); |
| - for (int i = 0; i < capacity; ++i) { |
| - if (!backing_store->get(i)->IsTheHole()) ++number_of_elements; |
| + *capacity = backing_store->length(); |
| + for (int i = 0; i < *capacity; ++i) { |
| + if (!backing_store->get(i)->IsTheHole()) ++(*used); |
| } |
| break; |
| case DICTIONARY_ELEMENTS: { |
| NumberDictionary* dictionary = |
| NumberDictionary::cast(FixedArray::cast(elements())); |
| - capacity = dictionary->Capacity(); |
| - number_of_elements = dictionary->NumberOfElements(); |
| + *capacity = dictionary->Capacity(); |
| + *used = dictionary->NumberOfElements(); |
| break; |
| } |
| case FAST_DOUBLE_ELEMENTS: { |
| FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| - capacity = elms->length(); |
| - for (int i = 0; i < capacity; i++) { |
| - if (!elms->is_the_hole(i)) number_of_elements++; |
| + *capacity = elms->length(); |
| + for (int i = 0; i < *capacity; i++) { |
| + if (!elms->is_the_hole(i)) ++(*used); |
| } |
| break; |
| } |
| - case EXTERNAL_PIXEL_ELEMENTS: |
| - case EXTERNAL_BYTE_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| - case EXTERNAL_SHORT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| - case EXTERNAL_INT_ELEMENTS: |
| - case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| - case EXTERNAL_FLOAT_ELEMENTS: |
| - case EXTERNAL_DOUBLE_ELEMENTS: { |
| - return true; |
| - } |
| + default: |
| + ASSERT(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND <= kind && |
| + kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
|
danno
2011/07/22 09:21:25
Please leave this explicitly enumerated and remove
Vitaly Repeshko
2011/07/25 15:50:55
Agreed. I added the external array cases back. The
|
| + break; |
| } |
| - return (capacity == 0) || (number_of_elements > (capacity / 2)); |
| } |
| bool JSObject::ShouldConvertToSlowElements(int new_capacity) { |
| - if (new_capacity <= kMaxFastElementsLength) return false; |
| + STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <= |
| + kMaxUncheckedFastElementsLength); |
| + if (new_capacity <= kMaxUncheckedOldFastElementsLength || |
| + (new_capacity <= kMaxUncheckedFastElementsLength && |
| + GetHeap()->InNewSpace(this))) { |
| + return false; |
| + } |
| // Keep the array in fast case if the current backing storage is |
| // almost filled and if the new capacity is no more than twice the |
| // old capacity. |