Move CopyElements to the accessor of the target.

Review URL: https://chromiumcodereview.appspot.com/11416238

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13292 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2013-01-02 10:09:42 +00:00
parent bccef0c712
commit 537d1d89b0
4 changed files with 130 additions and 104 deletions

View File

@ -576,7 +576,7 @@ BUILTIN(ArrayPush) {
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, new_elms, kind, 0,
NULL, 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
@ -623,7 +623,7 @@ BUILTIN(ArrayPush) {
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, new_elms, kind, 0,
NULL, 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
@ -785,7 +785,7 @@ BUILTIN(ArrayUnshift) {
ElementsKind kind = array->GetElementsKind();
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, new_elms, kind, to_add,
NULL, 0, kind, new_elms, to_add,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
@ -934,9 +934,8 @@ BUILTIN(ArraySlice) {
if (!maybe_array->To(&result_array)) return maybe_array;
ElementsAccessor* accessor = object->GetElementsAccessor();
MaybeObject* maybe_failure =
accessor->CopyElements(NULL, k, result_array->elements(),
kind, 0, result_len, elms);
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, k, kind, result_array->elements(), 0, result_len, elms);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
@ -1037,9 +1036,9 @@ BUILTIN(ArraySplice) {
if (actual_delete_count > 0) {
AssertNoAllocation no_gc;
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure =
accessor->CopyElements(NULL, actual_start, result_array->elements(),
elements_kind, 0, actual_delete_count, elms_obj);
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, actual_start, elements_kind, result_array->elements(),
0, actual_delete_count, elms_obj);
// Cannot fail since the origin and target array are of the same elements
// kind.
ASSERT(!maybe_failure->IsFailure());
@ -1105,12 +1104,12 @@ BUILTIN(ArraySplice) {
if (actual_start > 0) {
// Copy the part before actual_start as is.
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, new_elms, kind, 0, actual_start, elms);
NULL, 0, kind, new_elms, 0, actual_start, elms);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
}
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, actual_start + actual_delete_count, new_elms, kind,
NULL, actual_start + actual_delete_count, kind, new_elms,
actual_start + item_count,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms);
ASSERT(!maybe_failure->IsFailure());
@ -1220,13 +1219,14 @@ BUILTIN(ArrayConcat) {
int j = 0;
FixedArrayBase* storage = result_array->elements();
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
for (int i = 0; i < n_arguments; i++) {
JSArray* array = JSArray::cast(args[i]);
int len = Smi::cast(array->length())->value();
ElementsKind from_kind = array->GetElementsKind();
if (len > 0) {
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure =
accessor->CopyElements(array, 0, storage, elements_kind, j, len);
accessor->CopyElements(array, 0, from_kind, storage, j, len);
if (maybe_failure->IsFailure()) return maybe_failure;
j += len;
}

View File

@ -686,7 +686,7 @@ class ElementsAccessorBase : public ElementsAccessor {
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
uint32_t from_start,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
uint32_t to_start,
int packed_size,
int copy_size) {
@ -696,8 +696,8 @@ class ElementsAccessorBase : public ElementsAccessor {
MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
uint32_t from_start,
ElementsKind from_kind,
FixedArrayBase* to,
ElementsKind to_kind,
uint32_t to_start,
int copy_size,
FixedArrayBase* from) {
@ -707,8 +707,7 @@ class ElementsAccessorBase : public ElementsAccessor {
}
if (from_holder) {
ElementsKind elements_kind = from_holder->GetElementsKind();
bool is_packed = IsFastPackedElementsKind(elements_kind) &&
bool is_packed = IsFastPackedElementsKind(from_kind) &&
from_holder->IsJSArray();
if (is_packed) {
packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value();
@ -718,7 +717,7 @@ class ElementsAccessorBase : public ElementsAccessor {
}
}
return ElementsAccessorSubclass::CopyElementsImpl(
from, from_start, to, to_kind, to_start, packed_size, copy_size);
from, from_start, to, from_kind, to_start, packed_size, copy_size);
}
MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
@ -1003,6 +1002,41 @@ class FastElementsAccessor
};
static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
switch (array->map()->instance_type()) {
case FIXED_ARRAY_TYPE:
if (array->IsDictionary()) {
return DICTIONARY_ELEMENTS;
} else {
return FAST_HOLEY_ELEMENTS;
}
case FIXED_DOUBLE_ARRAY_TYPE:
return FAST_HOLEY_DOUBLE_ELEMENTS;
case EXTERNAL_BYTE_ARRAY_TYPE:
return EXTERNAL_BYTE_ELEMENTS;
case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
case EXTERNAL_SHORT_ARRAY_TYPE:
return EXTERNAL_SHORT_ELEMENTS;
case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
case EXTERNAL_INT_ARRAY_TYPE:
return EXTERNAL_INT_ELEMENTS;
case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
return EXTERNAL_UNSIGNED_INT_ELEMENTS;
case EXTERNAL_FLOAT_ARRAY_TYPE:
return EXTERNAL_FLOAT_ELEMENTS;
case EXTERNAL_DOUBLE_ARRAY_TYPE:
return EXTERNAL_DOUBLE_ELEMENTS;
case EXTERNAL_PIXEL_ARRAY_TYPE:
return EXTERNAL_PIXEL_ELEMENTS;
default:
UNREACHABLE();
}
return FAST_HOLEY_ELEMENTS;
}
template<typename FastElementsAccessorSubclass,
typename KindTraits>
class FastSmiOrObjectElementsAccessor
@ -1018,29 +1052,49 @@ class FastSmiOrObjectElementsAccessor
static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
uint32_t from_start,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
uint32_t to_start,
int packed_size,
int copy_size) {
if (IsFastSmiOrObjectElementsKind(to_kind)) {
CopyObjectToObjectElements(
from, KindTraits::Kind, from_start, to, to_kind, to_start, copy_size);
} else if (IsFastDoubleElementsKind(to_kind)) {
if (IsFastSmiElementsKind(KindTraits::Kind)) {
if (IsFastPackedElementsKind(KindTraits::Kind) &&
packed_size != kPackedSizeNotKnown) {
CopyPackedSmiToDoubleElements(
from, from_start, to, to_start, packed_size, copy_size);
} else {
CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
}
} else {
CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
ElementsKind to_kind = KindTraits::Kind;
switch (from_kind) {
case FAST_SMI_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
CopyObjectToObjectElements(
from, from_kind, from_start, to, to_kind, to_start, copy_size);
return to->GetHeap()->undefined_value();
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
return CopyDoubleToObjectElements(
from, from_start, to, to_kind, to_start, copy_size);
case DICTIONARY_ELEMENTS:
CopyDictionaryToObjectElements(
from, from_start, to, to_kind, to_start, copy_size);
return to->GetHeap()->undefined_value();
case NON_STRICT_ARGUMENTS_ELEMENTS: {
// TODO(verwaest): This is a temporary hack to support extending
// NON_STRICT_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
// This case should be UNREACHABLE().
FixedArray* parameter_map = FixedArray::cast(from);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
ElementsKind from_kind = ElementsKindForArray(arguments);
return CopyElementsImpl(arguments, from_start, to, from_kind,
to_start, packed_size, copy_size);
}
} else {
UNREACHABLE();
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();
}
return to->GetHeap()->undefined_value();
return NULL;
}
@ -1129,22 +1183,40 @@ class FastDoubleElementsAccessor
static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
uint32_t from_start,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
uint32_t to_start,
int packed_size,
int copy_size) {
switch (to_kind) {
switch (from_kind) {
case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
CopyPackedSmiToDoubleElements(
from, from_start, to, to_start, packed_size, copy_size);
break;
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
return CopyDoubleToObjectElements(
from, from_start, to, to_kind, to_start, copy_size);
CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
break;
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
return from;
default:
break;
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
break;
case DICTIONARY_ELEMENTS:
CopyDictionaryToDoubleElements(
from, from_start, to, to_start, copy_size);
break;
case NON_STRICT_ARGUMENTS_ELEMENTS:
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();
}
return to->GetHeap()->undefined_value();
@ -1460,27 +1532,12 @@ class DictionaryElementsAccessor
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
uint32_t from_start,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
uint32_t to_start,
int packed_size,
int copy_size) {
switch (to_kind) {
case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
CopyDictionaryToObjectElements(
from, from_start, to, to_kind, to_start, copy_size);
return from;
case FAST_DOUBLE_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
CopyDictionaryToDoubleElements(
from, from_start, to, to_start, copy_size);
return from;
default:
UNREACHABLE();
}
return to->GetHeap()->undefined_value();
UNREACHABLE();
return NULL;
}
@ -1707,15 +1764,12 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
MUST_USE_RESULT static MaybeObject* CopyElementsImpl(FixedArrayBase* from,
uint32_t from_start,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
uint32_t to_start,
int packed_size,
int copy_size) {
FixedArray* parameter_map = FixedArray::cast(from);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
return accessor->CopyElements(NULL, from_start, to, to_kind,
to_start, copy_size, arguments);
UNREACHABLE();
return NULL;
}
static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) {
@ -1761,35 +1815,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
switch (array->map()->instance_type()) {
case FIXED_ARRAY_TYPE:
if (array->IsDictionary()) {
return elements_accessors_[DICTIONARY_ELEMENTS];
} else {
return elements_accessors_[FAST_HOLEY_ELEMENTS];
}
case EXTERNAL_BYTE_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_BYTE_ELEMENTS];
case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS];
case EXTERNAL_SHORT_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_SHORT_ELEMENTS];
case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS];
case EXTERNAL_INT_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_INT_ELEMENTS];
case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS];
case EXTERNAL_FLOAT_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS];
case EXTERNAL_DOUBLE_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS];
case EXTERNAL_PIXEL_ARRAY_TYPE:
return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS];
default:
UNREACHABLE();
return NULL;
}
return elements_accessors_[ElementsKindForArray(array)];
}

View File

@ -143,17 +143,17 @@ class ElementsAccessor {
MUST_USE_RESULT virtual MaybeObject* CopyElements(
JSObject* source_holder,
uint32_t source_start,
ElementsKind source_kind,
FixedArrayBase* destination,
ElementsKind destination_kind,
uint32_t destination_start,
int copy_size,
FixedArrayBase* source = NULL) = 0;
MUST_USE_RESULT MaybeObject* CopyElements(JSObject* from_holder,
FixedArrayBase* to,
ElementsKind to_kind,
ElementsKind from_kind,
FixedArrayBase* from = NULL) {
return CopyElements(from_holder, 0, to, to_kind, 0,
return CopyElements(from_holder, 0, from_kind, to, 0,
kCopyToEndAndInitializeToHole, from);
}

View File

@ -9609,9 +9609,9 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
}
}
FixedArrayBase* old_elements = elements();
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind);
MaybeObject* maybe_obj =
accessor->CopyElements(this, new_elements, new_elements_kind);
accessor->CopyElements(this, new_elements, elements_kind);
if (maybe_obj->IsFailure()) return maybe_obj;
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
@ -9669,9 +9669,9 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
}
FixedArrayBase* old_elements = elements();
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS);
{ MaybeObject* maybe_obj =
accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS);
accessor->CopyElements(this, elems, elements_kind);
if (maybe_obj->IsFailure()) return maybe_obj;
}
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {