Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: src/objects.cc

Issue 9638014: Implement efficient element copying in ElementsAccessors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/elements.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 8430 matching lines...) Expand 10 before | Expand all | Expand 10 after
8441 } 8441 }
8442 } 8442 }
8443 8443
8444 PrintF("RelocInfo (size = %d)\n", relocation_size()); 8444 PrintF("RelocInfo (size = %d)\n", relocation_size());
8445 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); 8445 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out);
8446 PrintF(out, "\n"); 8446 PrintF(out, "\n");
8447 } 8447 }
8448 #endif // ENABLE_DISASSEMBLER 8448 #endif // ENABLE_DISASSEMBLER
8449 8449
8450 8450
8451 static void CopyFastElementsToFast(FixedArray* source,
8452 FixedArray* destination,
8453 WriteBarrierMode mode) {
8454 int count = source->length();
8455 int copy_size = Min(count, destination->length());
8456 if (mode == SKIP_WRITE_BARRIER ||
8457 !Page::FromAddress(destination->address())->IsFlagSet(
8458 MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) {
8459 Address to = destination->address() + FixedArray::kHeaderSize;
8460 Address from = source->address() + FixedArray::kHeaderSize;
8461 memcpy(reinterpret_cast<void*>(to),
8462 reinterpret_cast<void*>(from),
8463 kPointerSize * copy_size);
8464 } else {
8465 for (int i = 0; i < copy_size; ++i) {
8466 destination->set(i, source->get(i), mode);
8467 }
8468 }
8469 }
8470
8471
8472 static void CopySlowElementsToFast(SeededNumberDictionary* source,
8473 FixedArray* destination,
8474 WriteBarrierMode mode) {
8475 int destination_length = destination->length();
8476 for (int i = 0; i < source->Capacity(); ++i) {
8477 Object* key = source->KeyAt(i);
8478 if (key->IsNumber()) {
8479 uint32_t entry = static_cast<uint32_t>(key->Number());
8480 if (entry < static_cast<uint32_t>(destination_length)) {
8481 destination->set(entry, source->ValueAt(i), mode);
8482 }
8483 }
8484 }
8485 }
8486
8487
8488 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 8451 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
8489 int capacity, 8452 int capacity,
8490 int length, 8453 int length,
8491 SetFastElementsCapacityMode set_capacity_mode) { 8454 SetFastElementsCapacityMode set_capacity_mode) {
8492 Heap* heap = GetHeap(); 8455 Heap* heap = GetHeap();
8493 // We should never end in here with a pixel or external array. 8456 // We should never end in here with a pixel or external array.
8494 ASSERT(!HasExternalArrayElements()); 8457 ASSERT(!HasExternalArrayElements());
8495 8458
8496 // Allocate a new fast elements backing store. 8459 // Allocate a new fast elements backing store.
8497 FixedArray* new_elements; 8460 FixedArray* new_elements;
(...skipping 13 matching lines...) Expand all
8511 elements() == heap->empty_fixed_array())); 8474 elements() == heap->empty_fixed_array()));
8512 ElementsKind elements_kind = has_fast_smi_only_elements 8475 ElementsKind elements_kind = has_fast_smi_only_elements
8513 ? FAST_SMI_ONLY_ELEMENTS 8476 ? FAST_SMI_ONLY_ELEMENTS
8514 : FAST_ELEMENTS; 8477 : FAST_ELEMENTS;
8515 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); 8478 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
8516 if (!maybe->To(&new_map)) return maybe; 8479 if (!maybe->To(&new_map)) return maybe;
8517 } 8480 }
8518 8481
8519 FixedArrayBase* old_elements_raw = elements(); 8482 FixedArrayBase* old_elements_raw = elements();
8520 ElementsKind elements_kind = GetElementsKind(); 8483 ElementsKind elements_kind = GetElementsKind();
8521 switch (elements_kind) { 8484 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
8522 case FAST_SMI_ONLY_ELEMENTS: 8485 ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS)
8523 case FAST_ELEMENTS: { 8486 ? FAST_SMI_ONLY_ELEMENTS
8524 AssertNoAllocation no_gc; 8487 : FAST_ELEMENTS;
8525 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); 8488 // int copy_size = Min(old_elements_raw->length(), new_elements->length());
8526 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), 8489 accessor->CopyElements(this, new_elements, to_kind);
8527 new_elements, mode); 8490 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
8528 set_map_and_elements(new_map, new_elements); 8491 set_map_and_elements(new_map, new_elements);
8529 break; 8492 } else {
8530 } 8493 FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
8531 case DICTIONARY_ELEMENTS: { 8494 parameter_map->set(1, new_elements);
8532 AssertNoAllocation no_gc;
8533 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
8534 CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw),
8535 new_elements,
8536 mode);
8537 set_map_and_elements(new_map, new_elements);
8538 break;
8539 }
8540 case NON_STRICT_ARGUMENTS_ELEMENTS: {
8541 AssertNoAllocation no_gc;
8542 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
8543 // The object's map and the parameter map are unchanged, the unaliased
8544 // arguments are copied to the new backing store.
8545 FixedArray* parameter_map = FixedArray::cast(old_elements_raw);
8546 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
8547 if (arguments->IsDictionary()) {
8548 CopySlowElementsToFast(SeededNumberDictionary::cast(arguments),
8549 new_elements,
8550 mode);
8551 } else {
8552 CopyFastElementsToFast(arguments, new_elements, mode);
8553 }
8554 parameter_map->set(1, new_elements);
8555 break;
8556 }
8557 case FAST_DOUBLE_ELEMENTS: {
8558 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw);
8559 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
8560 // Fill out the new array with this content and array holes.
8561 for (uint32_t i = 0; i < old_length; i++) {
8562 if (!old_elements->is_the_hole(i)) {
8563 Object* obj;
8564 // Objects must be allocated in the old object space, since the
8565 // overall number of HeapNumbers needed for the conversion might
8566 // exceed the capacity of new space, and we would fail repeatedly
8567 // trying to convert the FixedDoubleArray.
8568 MaybeObject* maybe_value_object =
8569 GetHeap()->AllocateHeapNumber(old_elements->get_scalar(i),
8570 TENURED);
8571 if (!maybe_value_object->To(&obj)) return maybe_value_object;
8572 // Force write barrier. It's not worth trying to exploit
8573 // elems->GetWriteBarrierMode(), since it requires an
8574 // AssertNoAllocation stack object that would have to be positioned
8575 // after the HeapNumber allocation anyway.
8576 new_elements->set(i, obj, UPDATE_WRITE_BARRIER);
8577 }
8578 }
8579 set_map(new_map);
8580 set_elements(new_elements);
8581 break;
8582 }
8583 case EXTERNAL_BYTE_ELEMENTS:
8584 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
8585 case EXTERNAL_SHORT_ELEMENTS:
8586 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
8587 case EXTERNAL_INT_ELEMENTS:
8588 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
8589 case EXTERNAL_FLOAT_ELEMENTS:
8590 case EXTERNAL_DOUBLE_ELEMENTS:
8591 case EXTERNAL_PIXEL_ELEMENTS:
8592 UNREACHABLE();
8593 break;
8594 } 8495 }
8595 8496
8596 if (FLAG_trace_elements_transitions) { 8497 if (FLAG_trace_elements_transitions) {
8597 PrintElementsTransition(stdout, elements_kind, old_elements_raw, 8498 PrintElementsTransition(stdout, elements_kind, old_elements_raw,
8598 GetElementsKind(), new_elements); 8499 GetElementsKind(), new_elements);
8599 } 8500 }
8600 8501
8601 // Update the length if necessary. 8502 // Update the length if necessary.
8602 if (IsJSArray()) { 8503 if (IsJSArray()) {
8603 JSArray::cast(this)->set_length(Smi::FromInt(length)); 8504 JSArray::cast(this)->set_length(Smi::FromInt(length));
(...skipping 4353 matching lines...) Expand 10 before | Expand all | Expand 10 after
12957 if (break_point_objects()->IsUndefined()) return 0; 12858 if (break_point_objects()->IsUndefined()) return 0;
12958 // Single break point. 12859 // Single break point.
12959 if (!break_point_objects()->IsFixedArray()) return 1; 12860 if (!break_point_objects()->IsFixedArray()) return 1;
12960 // Multiple break points. 12861 // Multiple break points.
12961 return FixedArray::cast(break_point_objects())->length(); 12862 return FixedArray::cast(break_point_objects())->length();
12962 } 12863 }
12963 #endif // ENABLE_DEBUGGER_SUPPORT 12864 #endif // ENABLE_DEBUGGER_SUPPORT
12964 12865
12965 12866
12966 } } // namespace v8::internal 12867 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/elements.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698