| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index 79a4b5c229da1e10612ad65c354b2bcf0d2b1ccd..5c8e32b4269d554d9d4452e05e55d439c9951602 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -268,7 +268,7 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
|
| maybe_elms = heap->AllocateFixedArrayWithHoles(number_of_elements);
|
| }
|
| FixedArrayBase* elms;
|
| - if (!maybe_elms->To<FixedArrayBase>(&elms)) return maybe_elms;
|
| + if (!maybe_elms->To(&elms)) return maybe_elms;
|
|
|
| // Fill in the content
|
| switch (array->GetElementsKind()) {
|
| @@ -394,7 +394,7 @@ static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
|
|
|
| const int len = elms->length();
|
|
|
| - if (to_trim > FixedArrayBase::kHeaderSize / entry_size &&
|
| + if (to_trim * entry_size > FixedArrayBase::kHeaderSize &&
|
| elms->IsFixedArray() &&
|
| !heap->new_space()->Contains(elms)) {
|
| // If we are doing a big trim in old space then we zap the space that was
|
| @@ -577,7 +577,7 @@ BUILTIN(ArrayPush) {
|
| if (len > 0) {
|
| ElementsAccessor* accessor = array->GetElementsAccessor();
|
| MaybeObject* maybe_failure =
|
| - accessor->CopyElements(array, 0, new_elms, kind, 0, len, elms_obj);
|
| + accessor->CopyElements(NULL, 0, new_elms, kind, 0, len, elms_obj);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| }
|
| @@ -626,7 +626,7 @@ BUILTIN(ArrayPush) {
|
| if (len > 0) {
|
| ElementsAccessor* accessor = array->GetElementsAccessor();
|
| MaybeObject* maybe_failure =
|
| - accessor->CopyElements(array, 0, new_elms, kind, 0, len, elms_obj);
|
| + accessor->CopyElements(NULL, 0, new_elms, kind, 0, len, elms_obj);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| }
|
| @@ -791,7 +791,7 @@ BUILTIN(ArrayUnshift) {
|
| ElementsKind kind = array->GetElementsKind();
|
| ElementsAccessor* accessor = array->GetElementsAccessor();
|
| MaybeObject* maybe_failure =
|
| - accessor->CopyElements(array, 0, new_elms, kind, to_add, len, elms);
|
| + accessor->CopyElements(NULL, 0, new_elms, kind, to_add, len, elms);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| }
|
| @@ -936,12 +936,13 @@ BUILTIN(ArraySlice) {
|
| result_len,
|
| result_len);
|
|
|
| + AssertNoAllocation no_gc;
|
| if (result_len == 0) return maybe_array;
|
| if (!maybe_array->To(&result_array)) return maybe_array;
|
|
|
| ElementsAccessor* accessor = object->GetElementsAccessor();
|
| MaybeObject* maybe_failure =
|
| - accessor->CopyElements(object, k, result_array->elements(),
|
| + accessor->CopyElements(NULL, k, result_array->elements(),
|
| kind, 0, result_len, elms);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| @@ -1041,9 +1042,10 @@ BUILTIN(ArraySplice) {
|
| if (!maybe_array->To(&result_array)) return maybe_array;
|
|
|
| if (actual_delete_count > 0) {
|
| + AssertNoAllocation no_gc;
|
| ElementsAccessor* accessor = array->GetElementsAccessor();
|
| MaybeObject* maybe_failure =
|
| - accessor->CopyElements(array, actual_start, result_array->elements(),
|
| + accessor->CopyElements(NULL, actual_start, result_array->elements(),
|
| elements_kind, 0, actual_delete_count, elms_obj);
|
| // Cannot fail since the origin and target array are of the same elements
|
| // kind.
|
| @@ -1103,19 +1105,21 @@ BUILTIN(ArraySplice) {
|
| MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
|
| if (!maybe_obj->To(&new_elms)) return maybe_obj;
|
|
|
| + AssertNoAllocation no_gc;
|
| +
|
| ElementsKind kind = array->GetElementsKind();
|
| ElementsAccessor* accessor = array->GetElementsAccessor();
|
| if (actual_start > 0) {
|
| // Copy the part before actual_start as is.
|
| MaybeObject* maybe_failure = accessor->CopyElements(
|
| - array, 0, new_elms, kind, 0, actual_start, elms);
|
| + NULL, 0, new_elms, kind, 0, actual_start, elms);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| }
|
| const int to_copy = len - actual_delete_count - actual_start;
|
| if (to_copy > 0) {
|
| MaybeObject* maybe_failure = accessor->CopyElements(
|
| - array, actual_start + actual_delete_count, new_elms, kind,
|
| + NULL, actual_start + actual_delete_count, new_elms, kind,
|
| actual_start + item_count, to_copy, elms);
|
| ASSERT(!maybe_failure->IsFailure());
|
| USE(maybe_failure);
|
| @@ -1177,6 +1181,8 @@ BUILTIN(ArrayConcat) {
|
| int n_arguments = args.length();
|
| int result_len = 0;
|
| ElementsKind elements_kind = GetInitialFastElementsKind();
|
| + bool has_double = false;
|
| + bool is_holey = false;
|
| for (int i = 0; i < n_arguments; i++) {
|
| Object* arg = args[i];
|
| if (!arg->IsJSArray() ||
|
| @@ -1198,18 +1204,28 @@ BUILTIN(ArrayConcat) {
|
| }
|
|
|
| ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
|
| + has_double = has_double || IsFastDoubleElementsKind(arg_kind);
|
| + is_holey = is_holey || IsFastHoleyElementsKind(arg_kind);
|
| if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) {
|
| - elements_kind = IsFastHoleyElementsKind(elements_kind)
|
| - ? GetHoleyElementsKind(arg_kind) : arg_kind;
|
| + elements_kind = arg_kind;
|
| }
|
| }
|
|
|
| + if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind);
|
| +
|
| + // If a double array is concatted into a fast elements array, the fast
|
| + // elements array needs to be initialized to contain proper holes, since
|
| + // boxing doubles may cause incremental marking.
|
| + ArrayStorageAllocationMode mode =
|
| + has_double && IsFastObjectElementsKind(elements_kind)
|
| + ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
|
| JSArray* result_array;
|
| // Allocate result.
|
| MaybeObject* maybe_array =
|
| heap->AllocateJSArrayAndStorage(elements_kind,
|
| result_len,
|
| - result_len);
|
| + result_len,
|
| + mode);
|
| if (!maybe_array->To(&result_array)) return maybe_array;
|
| if (result_len == 0) return result_array;
|
|
|
|
|