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:
parent
bccef0c712
commit
537d1d89b0
@ -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;
|
||||
}
|
||||
|
194
src/elements.cc
194
src/elements.cc
@ -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)];
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user