| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index ba5aa7765aa7463e0071f842afd0b1a8555ca641..e1318bcc3f1a452b00addc58aa3a7c87d8df9c5b 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -10679,19 +10679,19 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
|
|
|
| set_map(new_map);
|
| set_elements(fast_elements);
|
| - } else {
|
| + } else if (!HasFastDoubleElements()) {
|
| Object* obj;
|
| { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| }
|
| }
|
| - ASSERT(HasFastElements());
|
| + ASSERT(HasFastElements() || HasFastDoubleElements());
|
|
|
| // Collect holes at the end, undefined before that and the rest at the
|
| // start, and return the number of non-hole, non-undefined values.
|
|
|
| - FixedArray* elements = FixedArray::cast(this->elements());
|
| - uint32_t elements_length = static_cast<uint32_t>(elements->length());
|
| + FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
|
| + uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
|
| if (limit > elements_length) {
|
| limit = elements_length ;
|
| }
|
| @@ -10710,47 +10710,78 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
|
| result_double = HeapNumber::cast(new_double);
|
| }
|
|
|
| - AssertNoAllocation no_alloc;
|
| -
|
| - // Split elements into defined, undefined and the_hole, in that order.
|
| - // Only count locations for undefined and the hole, and fill them afterwards.
|
| - WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
|
| - unsigned int undefs = limit;
|
| - unsigned int holes = limit;
|
| - // Assume most arrays contain no holes and undefined values, so minimize the
|
| - // number of stores of non-undefined, non-the-hole values.
|
| - for (unsigned int i = 0; i < undefs; i++) {
|
| - Object* current = elements->get(i);
|
| - if (current->IsTheHole()) {
|
| - holes--;
|
| - undefs--;
|
| - } else if (current->IsUndefined()) {
|
| - undefs--;
|
| - } else {
|
| - continue;
|
| + uint32_t result = 0;
|
| + if (elements_base->map() == heap->fixed_double_array_map()) {
|
| + FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base);
|
| + // Split elements into defined and the_hole, in that order.
|
| + unsigned int holes = limit;
|
| + // Assume most arrays contain no holes and undefined values, so minimize the
|
| + // number of stores of non-undefined, non-the-hole values.
|
| + for (unsigned int i = 0; i < holes; i++) {
|
| + if (elements->is_the_hole(i)) {
|
| + holes--;
|
| + } else {
|
| + continue;
|
| + }
|
| + // Position i needs to be filled.
|
| + while (holes > i) {
|
| + if (elements->is_the_hole(holes)) {
|
| + holes--;
|
| + } else {
|
| + elements->set(i, elements->get(holes));
|
| + break;
|
| + }
|
| + }
|
| }
|
| - // Position i needs to be filled.
|
| - while (undefs > i) {
|
| - current = elements->get(undefs);
|
| + result = holes;
|
| + while (holes < limit) {
|
| + elements->set_the_hole(holes);
|
| + holes++;
|
| + }
|
| + } else {
|
| + FixedArray* elements = FixedArray::cast(elements_base);
|
| + AssertNoAllocation no_alloc;
|
| +
|
| + // Split elements into defined, undefined and the_hole, in that order. Only
|
| + // count locations for undefined and the hole, and fill them afterwards.
|
| + WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
|
| + unsigned int undefs = limit;
|
| + unsigned int holes = limit;
|
| + // Assume most arrays contain no holes and undefined values, so minimize the
|
| + // number of stores of non-undefined, non-the-hole values.
|
| + for (unsigned int i = 0; i < undefs; i++) {
|
| + Object* current = elements->get(i);
|
| if (current->IsTheHole()) {
|
| holes--;
|
| undefs--;
|
| } else if (current->IsUndefined()) {
|
| undefs--;
|
| } else {
|
| - elements->set(i, current, write_barrier);
|
| - break;
|
| + continue;
|
| + }
|
| + // Position i needs to be filled.
|
| + while (undefs > i) {
|
| + current = elements->get(undefs);
|
| + if (current->IsTheHole()) {
|
| + holes--;
|
| + undefs--;
|
| + } else if (current->IsUndefined()) {
|
| + undefs--;
|
| + } else {
|
| + elements->set(i, current, write_barrier);
|
| + break;
|
| + }
|
| }
|
| }
|
| - }
|
| - uint32_t result = undefs;
|
| - while (undefs < holes) {
|
| - elements->set_undefined(undefs);
|
| - undefs++;
|
| - }
|
| - while (holes < limit) {
|
| - elements->set_the_hole(holes);
|
| - holes++;
|
| + result = undefs;
|
| + while (undefs < holes) {
|
| + elements->set_undefined(undefs);
|
| + undefs++;
|
| + }
|
| + while (holes < limit) {
|
| + elements->set_the_hole(holes);
|
| + holes++;
|
| + }
|
| }
|
|
|
| if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
|
|
|