Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 940120541e4ca51be3861fa72dca83c97b44fa80..d65e63d57dda5e58a3f616ebdcb59406dd2181e7 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -8448,43 +8448,6 @@ void Code::Disassemble(const char* name, FILE* out) { |
#endif // ENABLE_DISASSEMBLER |
-static void CopyFastElementsToFast(FixedArray* source, |
- FixedArray* destination, |
- WriteBarrierMode mode) { |
- int count = source->length(); |
- int copy_size = Min(count, destination->length()); |
- if (mode == SKIP_WRITE_BARRIER || |
- !Page::FromAddress(destination->address())->IsFlagSet( |
- MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) { |
- Address to = destination->address() + FixedArray::kHeaderSize; |
- Address from = source->address() + FixedArray::kHeaderSize; |
- memcpy(reinterpret_cast<void*>(to), |
- reinterpret_cast<void*>(from), |
- kPointerSize * copy_size); |
- } else { |
- for (int i = 0; i < copy_size; ++i) { |
- destination->set(i, source->get(i), mode); |
- } |
- } |
-} |
- |
- |
-static void CopySlowElementsToFast(SeededNumberDictionary* source, |
- FixedArray* destination, |
- WriteBarrierMode mode) { |
- int destination_length = destination->length(); |
- for (int i = 0; i < source->Capacity(); ++i) { |
- Object* key = source->KeyAt(i); |
- if (key->IsNumber()) { |
- uint32_t entry = static_cast<uint32_t>(key->Number()); |
- if (entry < static_cast<uint32_t>(destination_length)) { |
- destination->set(entry, source->ValueAt(i), mode); |
- } |
- } |
- } |
-} |
- |
- |
MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
int capacity, |
int length, |
@@ -8518,79 +8481,17 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
FixedArrayBase* old_elements_raw = elements(); |
ElementsKind elements_kind = GetElementsKind(); |
- switch (elements_kind) { |
- case FAST_SMI_ONLY_ELEMENTS: |
- case FAST_ELEMENTS: { |
- AssertNoAllocation no_gc; |
- WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
- CopyFastElementsToFast(FixedArray::cast(old_elements_raw), |
- new_elements, mode); |
- set_map_and_elements(new_map, new_elements); |
- break; |
- } |
- case DICTIONARY_ELEMENTS: { |
- AssertNoAllocation no_gc; |
- WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
- CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw), |
- new_elements, |
- mode); |
- set_map_and_elements(new_map, new_elements); |
- break; |
- } |
- case NON_STRICT_ARGUMENTS_ELEMENTS: { |
- AssertNoAllocation no_gc; |
- WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
- // The object's map and the parameter map are unchanged, the unaliased |
- // arguments are copied to the new backing store. |
- FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
- FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
- if (arguments->IsDictionary()) { |
- CopySlowElementsToFast(SeededNumberDictionary::cast(arguments), |
- new_elements, |
- mode); |
- } else { |
- CopyFastElementsToFast(arguments, new_elements, mode); |
- } |
- parameter_map->set(1, new_elements); |
- break; |
- } |
- case FAST_DOUBLE_ELEMENTS: { |
- FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); |
- uint32_t old_length = static_cast<uint32_t>(old_elements->length()); |
- // Fill out the new array with this content and array holes. |
- for (uint32_t i = 0; i < old_length; i++) { |
- if (!old_elements->is_the_hole(i)) { |
- Object* obj; |
- // Objects must be allocated in the old object space, since the |
- // overall number of HeapNumbers needed for the conversion might |
- // exceed the capacity of new space, and we would fail repeatedly |
- // trying to convert the FixedDoubleArray. |
- MaybeObject* maybe_value_object = |
- GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i), |
- TENURED); |
- if (!maybe_value_object->To(&obj)) return maybe_value_object; |
- // Force write barrier. It's not worth trying to exploit |
- // elems->GetWriteBarrierMode(), since it requires an |
- // AssertNoAllocation stack object that would have to be positioned |
- // after the HeapNumber allocation anyway. |
- new_elements->set(i, obj, UPDATE_WRITE_BARRIER); |
- } |
- } |
- set_map(new_map); |
- set_elements(new_elements); |
- break; |
- } |
- 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: |
- case EXTERNAL_PIXEL_ELEMENTS: |
- UNREACHABLE(); |
- break; |
+ ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); |
+ ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS) |
+ ? FAST_SMI_ONLY_ELEMENTS |
+ : FAST_ELEMENTS; |
+ // int copy_size = Min(old_elements_raw->length(), new_elements->length()); |
+ accessor->CopyElements(this, new_elements, to_kind); |
+ if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { |
+ set_map_and_elements(new_map, new_elements); |
+ } else { |
+ FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
+ parameter_map->set(1, new_elements); |
} |
if (FLAG_trace_elements_transitions) { |