Chromium Code Reviews| Index: src/objects-inl.h |
| diff --git a/src/objects-inl.h b/src/objects-inl.h |
| index 1eaae3cd4e31b0bb7470fe62067665bf93c71393..91402180bfdfaf1ca5ac2e89ffc62c69216bcc8c 100644 |
| --- a/src/objects-inl.h |
| +++ b/src/objects-inl.h |
| @@ -1183,6 +1183,22 @@ int HeapNumber::get_sign() { |
| ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) |
| +Object** FixedArray::GetFirstElementAddress() { |
| + return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0))); |
| +} |
| + |
| + |
| +bool FixedArray::ContainsOnlySmisOrHoles() { |
| + Object* the_hole = GetHeap()->the_hole_value(); |
| + Object** current = GetFirstElementAddress(); |
| + for (int i = 0; i < length(); ++i) { |
| + Object* candidate = *current++; |
| + if (!candidate->IsSmi() && candidate != the_hole) return false; |
| + } |
| + return true; |
| +} |
| + |
| + |
| FixedArrayBase* JSObject::elements() { |
| Object* array = READ_FIELD(this, kElementsOffset); |
| return static_cast<FixedArrayBase*>(array); |
| @@ -1211,38 +1227,67 @@ void JSObject::ValidateSmiOnlyElements() { |
| } |
| -MaybeObject* JSObject::EnsureCanContainNonSmiElements() { |
| +MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { |
| #if DEBUG |
| ValidateSmiOnlyElements(); |
| #endif |
| - if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) { |
| - Object* obj; |
| - MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); |
| - if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| - set_map(Map::cast(obj)); |
| + if ((map()->elements_kind() != FAST_ELEMENTS)) { |
| + return TransitionElementsKind(FAST_ELEMENTS); |
| } |
| return this; |
| } |
| MaybeObject* JSObject::EnsureCanContainElements(Object** objects, |
| - uint32_t count) { |
| - if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { |
| - for (uint32_t i = 0; i < count; ++i) { |
| - Object* current = *objects++; |
| - if (!current->IsSmi() && current != GetHeap()->the_hole_value()) { |
| - return EnsureCanContainNonSmiElements(); |
| + uint32_t count, |
| + EnsureElementsMode mode) { |
| + ElementsKind current_kind = map()->elements_kind(); |
| + ElementsKind target_kind = current_kind; |
| + ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); |
| + if (current_kind == FAST_ELEMENTS) return this; |
| + |
| + Heap* heap = GetHeap(); |
| + Object* the_hole = heap->the_hole_value(); |
| + Object* heap_number_map = heap->heap_number_map(); |
| + for (uint32_t i = 0; i < count; ++i) { |
| + Object* current = *objects++; |
| + if (!current->IsSmi() && current != the_hole) { |
| + if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && |
| + HeapObject::cast(current)->map() == heap_number_map) { |
| + target_kind = FAST_DOUBLE_ELEMENTS; |
| + } else { |
| + target_kind = FAST_ELEMENTS; |
| + break; |
| } |
| } |
| } |
| + |
| + if (target_kind != current_kind) { |
| + return TransitionElementsKind(target_kind); |
| + } |
| return this; |
| } |
| -MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) { |
| - Object** objects = reinterpret_cast<Object**>( |
| - FIELD_ADDR(elements, elements->OffsetOfElementAt(0))); |
| - return EnsureCanContainElements(objects, elements->length()); |
| +MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, |
| + EnsureElementsMode mode) { |
| + if (elements->map() != GetHeap()->fixed_double_array_map()) { |
| + ASSERT(elements->map() == GetHeap()->fixed_array_map() || |
| + elements->map() == GetHeap()->fixed_cow_array_map()); |
| + if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { |
| + mode = DONT_ALLOW_DOUBLE_ELEMENTS; |
| + } |
| + Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); |
| + return EnsureCanContainElements(objects, elements->length(), |
| + mode); |
|
Jakob Kummerow
2011/12/07 17:02:47
nit: no need for line break
danno
2011/12/08 15:09:09
Done.
|
| + } |
| + |
| + ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); |
| + if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { |
| + return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); |
| + } |
| + |
| + return this; |
| } |
| @@ -4120,7 +4165,8 @@ ElementsKind JSObject::GetElementsKind() { |
| (map == GetHeap()->fixed_array_map() || |
| map == GetHeap()->fixed_cow_array_map())) || |
| (kind == FAST_DOUBLE_ELEMENTS && |
| - fixed_array->IsFixedDoubleArray()) || |
| + (fixed_array->IsFixedDoubleArray() || |
| + fixed_array == GetHeap()->empty_fixed_array())) || |
| (kind == DICTIONARY_ELEMENTS && |
| fixed_array->IsFixedArray() && |
| fixed_array->IsDictionary()) || |
| @@ -4579,11 +4625,18 @@ void JSArray::set_length(Smi* length) { |
| } |
| -MaybeObject* JSArray::SetContent(FixedArray* storage) { |
| - MaybeObject* maybe_object = EnsureCanContainElements(storage); |
| - if (maybe_object->IsFailure()) return maybe_object; |
| - set_length(Smi::FromInt(storage->length())); |
| +MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { |
| + MaybeObject* maybe_result = EnsureCanContainElements( |
| + storage, ALLOW_COPIED_DOUBLE_ELEMENTS); |
| + if (maybe_result->IsFailure()) return maybe_result; |
| + ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && |
| + GetElementsKind() == FAST_DOUBLE_ELEMENTS) || |
| + ((storage->map() != GetHeap()->fixed_double_array_map()) && |
| + ((GetElementsKind() == FAST_ELEMENTS) || |
| + (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && |
| + FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); |
| set_elements(storage); |
| + set_length(Smi::FromInt(storage->length())); |
| return this; |
| } |