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

Unified Diff: src/elements.cc

Issue 9663002: Use CopyElements for SetFastDoubleElementsCapacityAndLength (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 331f6bc4b49162864f52c863497bfa020b453e52..f6a1697829eb52ea99a36df53eca5befe61bd0ad 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -131,95 +131,135 @@ static Failure* ThrowArrayLengthRangeError(Heap* heap) {
}
-void CopyObjectToObjectElements(AssertNoAllocation* no_gc,
- FixedArray* from_obj,
+void CopyObjectToObjectElements(FixedArray* from,
ElementsKind from_kind,
uint32_t from_start,
- FixedArray* to_obj,
+ FixedArray* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
- ASSERT(to_obj->map() != HEAP->fixed_cow_array_map());
+ int raw_copy_size,
+ WriteBarrierMode mode) {
+ ASSERT(to->map() != HEAP->fixed_cow_array_map());
ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
- if (copy_size == -1) {
- copy_size = Min(from_obj->length() - from_start,
- to_obj->length() - to_start);
+ int copy_size = raw_copy_size;
+ if (raw_copy_size < 0) {
+ ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+ raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = Min(from->length() - from_start,
+ to->length() - to_start);
+#ifdef DEBUG
+ // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+ // marked with the hole.
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ ASSERT(to->get(i)->IsTheHole());
+ }
+ }
+#endif
}
- ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
- (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+ (copy_size + static_cast<int>(from_start)) <= from->length());
if (copy_size == 0) return;
- Address to = to_obj->address() + FixedArray::kHeaderSize;
- Address from = from_obj->address() + FixedArray::kHeaderSize;
- CopyWords(reinterpret_cast<Object**>(to) + to_start,
- reinterpret_cast<Object**>(from) + from_start,
+ Address to_address = to->address() + FixedArray::kHeaderSize;
+ Address from_address = from->address() + FixedArray::kHeaderSize;
+ CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
+ reinterpret_cast<Object**>(from_address) + from_start,
copy_size);
- if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
- Heap* heap = from_obj->GetHeap();
- WriteBarrierMode mode = to_obj->GetWriteBarrierMode(*no_gc);
- if (mode == UPDATE_WRITE_BARRIER) {
- heap->RecordWrites(to_obj->address(),
- to_obj->OffsetOfElementAt(to_start),
+ if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS &&
+ mode == UPDATE_WRITE_BARRIER) {
+ Heap* heap = from->GetHeap();
+ if (!heap->InNewSpace(to)) {
+ heap->RecordWrites(to->address(),
+ to->OffsetOfElementAt(to_start),
copy_size);
}
- heap->incremental_marking()->RecordWrites(to_obj);
+ heap->incremental_marking()->RecordWrites(to);
}
}
-
-
static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
uint32_t from_start,
FixedArray* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int raw_copy_size,
+ WriteBarrierMode mode) {
+ int copy_size = raw_copy_size;
+ Heap* heap = from->GetHeap();
+ if (raw_copy_size < 0) {
+ ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+ raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = from->max_number_key() + 1 - from_start;
+#ifdef DEBUG
+ // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+ // marked with the hole.
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ ASSERT(to->get(i)->IsTheHole());
+ }
+ }
+#endif
+ }
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to->length());
ASSERT(to != from);
ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
- ASSERT(copy_size == -1 ||
- (copy_size + static_cast<int>(to_start)) <= to->length());
- WriteBarrierMode mode = to_kind == FAST_ELEMENTS
- ? UPDATE_WRITE_BARRIER
- : SKIP_WRITE_BARRIER;
- uint32_t copy_limit = (copy_size == -1)
- ? to->length()
- : Min(to_start + copy_size, static_cast<uint32_t>(to->length()));
- for (int i = 0; i < from->Capacity(); ++i) {
- Object* key = from->KeyAt(i);
- if (key->IsNumber()) {
- uint32_t entry = static_cast<uint32_t>(key->Number());
- if (entry >= to_start && entry < copy_limit) {
- Object* value = from->ValueAt(i);
- ASSERT(to_kind == FAST_ELEMENTS || value->IsSmi());
- to->set(entry, value, mode);
- }
+ if (copy_size == 0) return;
+ for (int i = 0; i < copy_size; i++) {
+ int entry = from->FindEntry(i + from_start);
+ if (entry != SeededNumberDictionary::kNotFound) {
+ Object* value = from->ValueAt(entry);
+ ASSERT(!value->IsTheHole());
+ to->set(i + to_start, value, SKIP_WRITE_BARRIER);
+ } else {
+ to->set_the_hole(i + to_start);
+ }
+ }
+ if (to_kind == FAST_ELEMENTS) {
+ if (!heap->InNewSpace(to)) {
+ heap->RecordWrites(to->address(),
+ to->OffsetOfElementAt(to_start),
+ copy_size);
}
+ heap->incremental_marking()->RecordWrites(to);
}
}
MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
- FixedDoubleArray* from_obj,
+ FixedDoubleArray* from,
uint32_t from_start,
- FixedArray* to_obj,
+ FixedArray* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int raw_copy_size) {
ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
- if (copy_size == -1) {
- copy_size = Min(from_obj->length() - from_start,
- to_obj->length() - to_start);
+ int copy_size = raw_copy_size;
+ if (raw_copy_size < 0) {
+ ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+ raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = Min(from->length() - from_start,
+ to->length() - to_start);
+#ifdef DEBUG
+ // FAST_ELEMENT arrays cannot be uninitialized. Ensure they are already
+ // marked with the hole.
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ ASSERT(to->get(i)->IsTheHole());
+ }
+ }
+#endif
}
- ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
- (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
- if (copy_size == 0) return from_obj;
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+ (copy_size + static_cast<int>(from_start)) <= from->length());
+ if (copy_size == 0) return from;
for (int i = 0; i < copy_size; ++i) {
if (to_kind == FAST_SMI_ONLY_ELEMENTS) {
UNIMPLEMENTED();
return Failure::Exception();
} else {
- MaybeObject* maybe_value = from_obj->get(i + from_start);
+ MaybeObject* maybe_value = from->get(i + from_start);
Object* value;
ASSERT(to_kind == FAST_ELEMENTS);
// Because FAST_DOUBLE_ELEMENTS -> FAST_ELEMENT allocate HeapObjects
@@ -229,42 +269,109 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements(
// can't be taken from new space.
if (!maybe_value->ToObject(&value)) {
ASSERT(maybe_value->IsRetryAfterGC() || maybe_value->IsOutOfMemory());
- Heap* heap = from_obj->GetHeap();
+ Heap* heap = from->GetHeap();
MaybeObject* maybe_value_object =
- heap->AllocateHeapNumber(from_obj->get_scalar(i + from_start),
+ heap->AllocateHeapNumber(from->get_scalar(i + from_start),
TENURED);
if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
}
- to_obj->set(i + to_start, value, UPDATE_WRITE_BARRIER);
+ to->set(i + to_start, value, UPDATE_WRITE_BARRIER);
}
}
- return to_obj;
+ return to;
}
-static void CopyDoubleToDoubleElements(FixedDoubleArray* from_obj,
+static void CopyDoubleToDoubleElements(FixedDoubleArray* from,
uint32_t from_start,
- FixedDoubleArray* to_obj,
+ FixedDoubleArray* to,
uint32_t to_start,
- int copy_size) {
- if (copy_size == -1) {
- copy_size = Min(from_obj->length() - from_start,
- to_obj->length() - to_start);
+ int raw_copy_size) {
+ int copy_size = raw_copy_size;
+ if (raw_copy_size < 0) {
+ ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+ raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = Min(from->length() - from_start,
+ to->length() - to_start);
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ to->set_the_hole(i);
+ }
+ }
}
- ASSERT(((copy_size + static_cast<int>(to_start)) <= to_obj->length() &&
- (copy_size + static_cast<int>(from_start)) <= from_obj->length()));
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+ (copy_size + static_cast<int>(from_start)) <= from->length());
if (copy_size == 0) return;
- Address to = to_obj->address() + FixedDoubleArray::kHeaderSize;
- Address from = from_obj->address() + FixedDoubleArray::kHeaderSize;
- to += kDoubleSize * to_start;
- from += kDoubleSize * from_start;
+ Address to_address = to->address() + FixedDoubleArray::kHeaderSize;
+ Address from_address = from->address() + FixedDoubleArray::kHeaderSize;
+ to_address += kDoubleSize * to_start;
+ from_address += kDoubleSize * from_start;
int words_per_double = (kDoubleSize / kPointerSize);
- CopyWords(reinterpret_cast<Object**>(to),
- reinterpret_cast<Object**>(from),
+ CopyWords(reinterpret_cast<Object**>(to_address),
+ reinterpret_cast<Object**>(from_address),
words_per_double * copy_size);
}
+static void CopyObjectToDoubleElements(FixedArray* from,
+ uint32_t from_start,
+ FixedDoubleArray* to,
+ uint32_t to_start,
+ int raw_copy_size) {
+ int copy_size = raw_copy_size;
+ if (raw_copy_size < 0) {
+ ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
+ raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = from->length() - from_start;
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ to->set_the_hole(i);
+ }
+ }
+ }
+ ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
+ (copy_size + static_cast<int>(from_start)) <= from->length());
+ if (copy_size == 0) return;
+ for (int i = 0; i < copy_size; i++) {
+ Object* hole_or_object = from->get(i + from_start);
+ if (hole_or_object->IsTheHole()) {
+ to->set_the_hole(i + to_start);
+ } else {
+ to->set(i + to_start, hole_or_object->Number());
+ }
+ }
+}
+
+
+static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from,
+ uint32_t from_start,
+ FixedDoubleArray* to,
+ uint32_t to_start,
+ int raw_copy_size) {
+ int copy_size = raw_copy_size;
+ if (copy_size < 0) {
+ ASSERT(copy_size == ElementsAccessor::kCopyToEnd ||
+ copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
+ copy_size = from->max_number_key() + 1 - from_start;
+ if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
+ for (int i = to_start + copy_size; i < to->length(); ++i) {
+ to->set_the_hole(i);
+ }
+ }
+ }
+ ASSERT(copy_size + static_cast<int>(to_start) <= to->length());
+ if (copy_size == 0) return;
+ for (int i = 0; i < copy_size; i++) {
+ int entry = from->FindEntry(i + from_start);
+ if (entry != SeededNumberDictionary::kNotFound) {
+ to->set(i + to_start, from->ValueAt(entry)->Number());
+ } else {
+ to->set_the_hole(i + to_start);
+ }
+ }
+}
+
+
// Base class for element handler implementations. Contains the
// the common logic for objects with different ElementsKinds.
// Subclasses must specialize method for which the element
@@ -369,7 +476,8 @@ class ElementsAccessorBase : public ElementsAccessor {
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int copy_size,
+ WriteBarrierMode mode) {
UNREACHABLE();
return NULL;
}
@@ -380,12 +488,16 @@ class ElementsAccessorBase : public ElementsAccessor {
ElementsKind to_kind,
uint32_t to_start,
int copy_size,
+ WriteBarrierMode mode,
FixedArrayBase* from) {
if (from == NULL) {
from = from_holder->elements();
}
+ if (from->length() == 0) {
+ return from;
+ }
return ElementsAccessorSubclass::CopyElementsImpl(
- from, from_start, to, to_kind, to_start, copy_size);
+ from, from_start, to, to_kind, to_start, copy_size, mode);
}
virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
@@ -622,16 +734,21 @@ class FastObjectElementsAccessor
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int copy_size,
+ WriteBarrierMode mode) {
switch (to_kind) {
case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS: {
- AssertNoAllocation no_gc;
CopyObjectToObjectElements(
- &no_gc, FixedArray::cast(from), ElementsTraits::Kind, from_start,
- FixedArray::cast(to), to_kind, to_start, copy_size);
+ FixedArray::cast(from), ElementsTraits::Kind, from_start,
+ FixedArray::cast(to), to_kind, to_start, copy_size, mode);
return from;
}
+ case FAST_DOUBLE_ELEMENTS:
+ CopyObjectToDoubleElements(
+ FixedArray::cast(from), from_start,
+ FixedDoubleArray::cast(to), to_start, copy_size);
+ return from;
default:
UNREACHABLE();
}
@@ -692,7 +809,8 @@ class FastDoubleElementsAccessor
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int copy_size,
+ WriteBarrierMode mode) {
switch (to_kind) {
case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS:
@@ -989,13 +1107,19 @@ class DictionaryElementsAccessor
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int copy_size,
+ WriteBarrierMode mode) {
switch (to_kind) {
case FAST_SMI_ONLY_ELEMENTS:
case FAST_ELEMENTS:
CopyDictionaryToObjectElements(
SeededNumberDictionary::cast(from), from_start,
- FixedArray::cast(to), to_kind, to_start, copy_size);
+ FixedArray::cast(to), to_kind, to_start, copy_size, mode);
+ return from;
+ case FAST_DOUBLE_ELEMENTS:
+ CopyDictionaryToDoubleElements(
+ SeededNumberDictionary::cast(from), from_start,
+ FixedDoubleArray::cast(to), to_start, copy_size);
return from;
default:
UNREACHABLE();
@@ -1128,12 +1252,13 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
- int copy_size) {
+ int copy_size,
+ WriteBarrierMode mode) {
FixedArray* parameter_map = FixedArray::cast(from);
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
return accessor->CopyElements(NULL, from_start, to, to_kind,
- to_start, copy_size, arguments);
+ to_start, copy_size, mode, arguments);
}
static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698