Chromium Code Reviews| Index: src/builtins.cc |
| diff --git a/src/builtins.cc b/src/builtins.cc |
| index d403a951cfb1c4ed0795cdb941c03a9c91a9ccda..0e499eab7ba04c8602fac0a0069b0bab58f4e865 100644 |
| --- a/src/builtins.cc |
| +++ b/src/builtins.cc |
| @@ -202,7 +202,7 @@ BUILTIN(ArrayCodeGeneric) { |
| } |
| // 'array' now contains the JSArray we should initialize. |
| - ASSERT(array->HasFastElements()); |
| + ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
| // Optimize the case where there is one argument and the argument is a |
| // small smi. |
| @@ -215,7 +215,8 @@ BUILTIN(ArrayCodeGeneric) { |
| { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len); |
| if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| } |
| - array->SetContent(FixedArray::cast(obj)); |
| + MaybeObject* maybe_obj = array->SetContent(FixedArray::cast(obj)); |
| + if (maybe_obj->IsFailure()) return maybe_obj; |
| return array; |
| } |
| } |
| @@ -248,6 +249,9 @@ BUILTIN(ArrayCodeGeneric) { |
| } |
| // Set length and elements on the array. |
| + MaybeObject* maybe_object = |
| + array->EnsureCanContainElements(FixedArray::cast(obj)); |
| + if (maybe_object->IsFailure()) return maybe_object; |
| array->set_elements(FixedArray::cast(obj)); |
| array->set_length(len); |
| @@ -475,9 +479,11 @@ BUILTIN(ArrayPush) { |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| - array->set_elements(elms); |
| } |
| + MaybeObject* maybe = array->EnsureCanContainElements(&args, 1, to_add); |
| + if (maybe->IsFailure()) return maybe; |
| + |
| // Add the provided values. |
| AssertNoAllocation no_gc; |
| WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| @@ -485,6 +491,10 @@ BUILTIN(ArrayPush) { |
| elms->set(index + len, args[index + 1], mode); |
| } |
| + if (elms != array->elements()) { |
| + array->set_elements(elms); |
| + } |
| + |
| // Set the length. |
| array->set_length(Smi::FromInt(new_length)); |
| return Smi::FromInt(new_length); |
| @@ -539,7 +549,7 @@ BUILTIN(ArrayShift) { |
| } |
| FixedArray* elms = FixedArray::cast(elms_obj); |
| JSArray* array = JSArray::cast(receiver); |
| - ASSERT(array->HasFastElements()); |
| + ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
| int len = Smi::cast(array->length())->value(); |
| if (len == 0) return heap->undefined_value(); |
| @@ -583,7 +593,7 @@ BUILTIN(ArrayUnshift) { |
| } |
| FixedArray* elms = FixedArray::cast(elms_obj); |
| JSArray* array = JSArray::cast(receiver); |
| - ASSERT(array->HasFastElements()); |
| + ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
| int len = Smi::cast(array->length())->value(); |
| int to_add = args.length() - 1; |
| @@ -608,6 +618,9 @@ BUILTIN(ArrayUnshift) { |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| + |
| + MaybeObject* maybe_object = array->EnsureCanContainElements(elms); |
| + if (maybe_object->IsFailure()) return maybe_object; |
| array->set_elements(elms); |
| } else { |
| AssertNoAllocation no_gc; |
| @@ -617,7 +630,14 @@ BUILTIN(ArrayUnshift) { |
| // Add the provided values. |
| AssertNoAllocation no_gc; |
|
Jakob Kummerow
2011/09/16 16:30:34
Scope or move this, you're calling EnsureCanContai
danno
2011/09/21 14:32:04
Done.
|
| WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| + bool only_smis = array->HasFastSmiOnlyElements(); |
| for (int i = 0; i < to_add; i++) { |
| + if (only_smis && !args[i+1]->IsSmi() && |
|
Jakob Kummerow
2011/09/16 16:30:34
nit: spaces around '+'
(also in the next line)
danno
2011/09/21 14:32:04
Done.
|
| + args[i+1] != heap->the_hole_value()) { |
| + MaybeObject* maybe_object = array->EnsureCanContainNonSmiElements(); |
| + if (maybe_object->IsFailure()) return maybe_object; |
| + only_smis = false; |
| + } |
| elms->set(i, args[i + 1], mode); |
| } |
| @@ -725,6 +745,9 @@ BUILTIN(ArraySlice) { |
| CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); |
| // Set elements. |
| + MaybeObject* maybe_object = |
| + result_array->EnsureCanContainElements(result_elms); |
| + if (maybe_object->IsFailure()) return maybe_object; |
| result_array->set_elements(result_elms); |
| // Set the length. |
| @@ -748,7 +771,7 @@ BUILTIN(ArraySplice) { |
| } |
| FixedArray* elms = FixedArray::cast(elms_obj); |
| JSArray* array = JSArray::cast(receiver); |
| - ASSERT(array->HasFastElements()); |
| + ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
| int len = Smi::cast(array->length())->value(); |
| @@ -809,6 +832,12 @@ BUILTIN(ArraySplice) { |
| } |
| FixedArray* result_elms = FixedArray::cast(result); |
| + if (!array->HasFastSmiOnlyElements()) { |
| + MaybeObject* maybe_result_array = |
| + result_array->EnsureCanContainNonSmiElements(); |
| + if (maybe_result_array->IsFailure()) return maybe_result_array; |
| + } |
| + |
| AssertNoAllocation no_gc; |
| // Fill newly created array. |
| CopyElements(heap, |
| @@ -828,6 +857,8 @@ BUILTIN(ArraySplice) { |
| int new_length = len - actual_delete_count + item_count; |
| + WriteBarrierMode write_barrier_mode = UPDATE_WRITE_BARRIER; |
| + bool elms_changed = false; |
| if (item_count < actual_delete_count) { |
| // Shrink the array. |
| const bool trim_array = !heap->lo_space()->Contains(elms) && |
| @@ -842,7 +873,9 @@ BUILTIN(ArraySplice) { |
| } |
| elms = LeftTrimFixedArray(heap, elms, delta); |
| - array->set_elements(elms, SKIP_WRITE_BARRIER); |
| + elms_changed = true; |
| + // elms in new space, can skip write barrier. |
| + write_barrier_mode = SKIP_WRITE_BARRIER; |
| } else { |
| AssertNoAllocation no_gc; |
| MoveElements(heap, &no_gc, |
| @@ -882,7 +915,7 @@ BUILTIN(ArraySplice) { |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| - array->set_elements(elms); |
| + elms_changed = true; |
| } else { |
| AssertNoAllocation no_gc; |
| MoveElements(heap, &no_gc, |
| @@ -892,12 +925,19 @@ BUILTIN(ArraySplice) { |
| } |
| } |
| + MaybeObject* maybe = array->EnsureCanContainElements(&args, 3, item_count); |
| + if (maybe->IsFailure()) return maybe; |
| + |
| AssertNoAllocation no_gc; |
| WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc); |
| for (int k = actual_start; k < actual_start + item_count; k++) { |
| elms->set(k, args[3 + k - actual_start], mode); |
| } |
| + if (elms_changed) { |
| + array->set_elements(elms, write_barrier_mode); |
| + } |
| + |
| // Set the length. |
| array->set_length(Smi::FromInt(new_length)); |
| @@ -971,6 +1011,9 @@ BUILTIN(ArrayConcat) { |
| ASSERT(start_pos == result_len); |
| // Set the length and elements. |
| + MaybeObject* maybe_object = |
| + result_array->EnsureCanContainElements(result_elms); |
| + if (maybe_object->IsFailure()) return maybe_object; |
| result_array->set_length(Smi::FromInt(result_len)); |
| result_array->set_elements(result_elms); |