Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 5c8a8987054a7d0c2096599337e5ff8c26fddf7d..9572366c69ac45104a4a1c89413cd9b2fe0cf3cc 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -8369,13 +8369,25 @@ MaybeObject* JSArray::Initialize(int capacity) { |
| void JSArray::Expand(int required_size) { |
|
Jakob Kummerow
2011/12/07 17:02:47
Instead of all this code here, we should be able t
danno
2011/12/08 15:09:09
Done.
|
| Handle<JSArray> self(this); |
| - Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
| - int old_size = old_backing->length(); |
| + Handle<FixedArrayBase> old_backing_raw(FixedArrayBase::cast(elements())); |
| + int old_size = old_backing_raw->length(); |
| int new_size = required_size > old_size ? required_size : old_size; |
| - Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); |
| - // Can't use this any more now because we may have had a GC! |
| - for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
| - GetIsolate()->factory()->SetContent(self, new_backing); |
| + if (old_backing_raw->map() == GetHeap()->fixed_double_array_map()) { |
| + Handle<FixedDoubleArray> new_backing = |
| + FACTORY->NewFixedDoubleArray(new_size); |
| + // Can't use this any more now because we may have had a GC! |
| + FixedDoubleArray* old_backing(FixedDoubleArray::cast(*old_backing_raw)); |
| + for (int i = 0; i < old_size; i++) { |
| + new_backing->set(i, old_backing->get_scalar(i)); |
| + } |
| + GetIsolate()->factory()->SetContent(self, new_backing); |
| + } else { |
| + Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); |
| + // Can't use this any more now because we may have had a GC! |
| + FixedArray* old_backing(FixedArray::cast(*old_backing_raw)); |
| + for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
| + GetIsolate()->factory()->SetContent(self, new_backing); |
| + } |
| } |
| @@ -8529,13 +8541,14 @@ MaybeObject* JSReceiver::SetPrototype(Object* value, |
| MaybeObject* JSObject::EnsureCanContainElements(Arguments* args, |
| uint32_t first_arg, |
| - uint32_t arg_count) { |
| + uint32_t arg_count, |
| + EnsureElementsMode mode) { |
| // Elements in |Arguments| are ordered backwards (because they're on the |
| // stack), but the method that's called here iterates over them in forward |
| // direction. |
| return EnsureCanContainElements( |
| args->arguments() - first_arg - (arg_count - 1), |
| - arg_count); |
| + arg_count, mode); |
| } |
| @@ -9487,31 +9500,45 @@ MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind( |
| FixedArrayBase* elms = FixedArrayBase::cast(elements()); |
| uint32_t capacity = static_cast<uint32_t>(elms->length()); |
| uint32_t length = capacity; |
| + |
| if (IsJSArray()) { |
| - CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
| + Object* raw_length = JSArray::cast(this)->length(); |
| + if (raw_length->IsUndefined()) { |
| + // If length is undefined, then JSArray is being initialized and has no |
| + // elements, assume a length of zero. |
| + length = 0; |
| + } else { |
| + CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); |
| + } |
| } |
| - if (from_kind == FAST_SMI_ONLY_ELEMENTS) { |
| - if (to_kind == FAST_DOUBLE_ELEMENTS) { |
| - MaybeObject* maybe_result = |
| - SetFastDoubleElementsCapacityAndLength(capacity, length); |
| - if (maybe_result->IsFailure()) return maybe_result; |
| - return this; |
| - } else if (to_kind == FAST_ELEMENTS) { |
| - MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); |
| - Map* new_map; |
| - if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| - if (FLAG_trace_elements_transitions) { |
| - PrintElementsTransition(stdout, from_kind, elms, FAST_ELEMENTS, elms); |
| - } |
| - set_map(new_map); |
| - return this; |
| + |
| + if ((from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) || |
| + (length == 0)) { |
| + MaybeObject* maybe_new_map = GetElementsTransitionMap(to_kind); |
| + Map* new_map; |
| + if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| + if (FLAG_trace_elements_transitions) { |
| + PrintElementsTransition(stdout, from_kind, elms, to_kind, elms); |
| } |
| - } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { |
| + set_map(new_map); |
| + return this; |
| + } |
| + |
| + if (from_kind == FAST_SMI_ONLY_ELEMENTS && |
| + to_kind == FAST_DOUBLE_ELEMENTS) { |
| + MaybeObject* maybe_result = |
| + SetFastDoubleElementsCapacityAndLength(capacity, length); |
| + if (maybe_result->IsFailure()) return maybe_result; |
| + return this; |
| + } |
| + |
| + if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { |
| MaybeObject* maybe_result = SetFastElementsCapacityAndLength( |
| capacity, length, kDontAllowSmiOnlyElements); |
| if (maybe_result->IsFailure()) return maybe_result; |
| return this; |
| } |
| + |
| // This method should never be called for any other case than the ones |
| // handled above. |
| UNREACHABLE(); |