Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index 5104f6d0d144e98eb6343003df40d9f02662ed7e..e005eda0289a05f0d89c31018994d0d8ffb92a4b 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -242,11 +242,9 @@ BUILTIN(ArrayCodeGeneric) { |
} |
// Set length and elements on the array. |
- if (FLAG_smi_only_arrays) { |
- MaybeObject* maybe_object = |
- array->EnsureCanContainElements(FixedArray::cast(obj)); |
- if (maybe_object->IsFailure()) return maybe_object; |
- } |
+ MaybeObject* maybe_object = |
+ array->EnsureCanContainElements(FixedArray::cast(obj)); |
+ if (maybe_object->IsFailure()) return maybe_object; |
AssertNoAllocation no_gc; |
FixedArray* elms = FixedArray::cast(obj); |
@@ -402,15 +400,36 @@ static bool ArrayPrototypeHasNoElements(Heap* heap, |
MUST_USE_RESULT |
static inline MaybeObject* EnsureJSArrayWithWritableFastElements( |
- Heap* heap, Object* receiver) { |
+ Heap* heap, Object* receiver, Arguments* args, int first_added_arg) { |
if (!receiver->IsJSArray()) return NULL; |
JSArray* array = JSArray::cast(receiver); |
HeapObject* elms = array->elements(); |
- if (elms->map() == heap->fixed_array_map()) return elms; |
- if (elms->map() == heap->fixed_cow_array_map()) { |
- return array->EnsureWritableFastElements(); |
+ Map* map = elms->map(); |
+ if (map == heap->fixed_array_map()) { |
+ if (args == NULL || !array->HasFastSmiOnlyElements()) { |
+ return elms; |
+ } |
+ } else if (map == heap->fixed_cow_array_map()) { |
+ MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); |
+ if (args == NULL || !array->HasFastSmiOnlyElements() || |
+ maybe_writable_result->IsFailure()) { |
+ return maybe_writable_result; |
+ } |
+ } else { |
+ return NULL; |
} |
- return NULL; |
+ |
+ // Need to ensure that the arguments passed in args can be contained in |
+ // the array. |
+ int args_length = args->length(); |
+ if (first_added_arg >= args_length) return array->elements(); |
+ |
+ MaybeObject* maybe_array = array->EnsureCanContainElements( |
+ args, |
+ first_added_arg, |
+ args_length - first_added_arg); |
+ if (maybe_array->IsFailure()) return maybe_array; |
+ return array->elements(); |
} |
@@ -457,7 +476,7 @@ BUILTIN(ArrayPush) { |
Object* receiver = *args.receiver(); |
Object* elms_obj; |
{ MaybeObject* maybe_elms_obj = |
- EnsureJSArrayWithWritableFastElements(heap, receiver); |
+ EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1); |
if (maybe_elms_obj == NULL) { |
return CallJsBuiltin(isolate, "ArrayPush", args); |
} |
@@ -495,9 +514,6 @@ BUILTIN(ArrayPush) { |
elms = new_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); |
@@ -520,7 +536,7 @@ BUILTIN(ArrayPop) { |
Object* receiver = *args.receiver(); |
Object* elms_obj; |
{ MaybeObject* maybe_elms_obj = |
- EnsureJSArrayWithWritableFastElements(heap, receiver); |
+ EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args); |
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
} |
@@ -553,7 +569,7 @@ BUILTIN(ArrayShift) { |
Object* receiver = *args.receiver(); |
Object* elms_obj; |
{ MaybeObject* maybe_elms_obj = |
- EnsureJSArrayWithWritableFastElements(heap, receiver); |
+ EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
if (maybe_elms_obj == NULL) |
return CallJsBuiltin(isolate, "ArrayShift", args); |
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
@@ -595,7 +611,7 @@ BUILTIN(ArrayUnshift) { |
Object* receiver = *args.receiver(); |
Object* elms_obj; |
{ MaybeObject* maybe_elms_obj = |
- EnsureJSArrayWithWritableFastElements(heap, receiver); |
+ EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0); |
if (maybe_elms_obj == NULL) |
return CallJsBuiltin(isolate, "ArrayUnshift", args); |
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
@@ -614,11 +630,9 @@ BUILTIN(ArrayUnshift) { |
// we should never hit this case. |
ASSERT(to_add <= (Smi::kMaxValue - len)); |
- if (FLAG_smi_only_arrays) { |
- MaybeObject* maybe_object = |
- array->EnsureCanContainElements(&args, 1, to_add); |
- if (maybe_object->IsFailure()) return maybe_object; |
- } |
+ MaybeObject* maybe_object = |
+ array->EnsureCanContainElements(&args, 1, to_add); |
+ if (maybe_object->IsFailure()) return maybe_object; |
if (new_length > elms->length()) { |
// New backing storage is needed. |
@@ -747,11 +761,9 @@ BUILTIN(ArraySlice) { |
} |
FixedArray* result_elms = FixedArray::cast(result); |
- if (FLAG_smi_only_arrays) { |
- MaybeObject* maybe_object = |
- result_array->EnsureCanContainElements(result_elms); |
- if (maybe_object->IsFailure()) return maybe_object; |
- } |
+ MaybeObject* maybe_object = |
+ result_array->EnsureCanContainElements(result_elms); |
+ if (maybe_object->IsFailure()) return maybe_object; |
AssertNoAllocation no_gc; |
CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); |
@@ -770,7 +782,7 @@ BUILTIN(ArraySplice) { |
Object* receiver = *args.receiver(); |
Object* elms_obj; |
{ MaybeObject* maybe_elms_obj = |
- EnsureJSArrayWithWritableFastElements(heap, receiver); |
+ EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3); |
if (maybe_elms_obj == NULL) |
return CallJsBuiltin(isolate, "ArraySplice", args); |
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
@@ -857,12 +869,6 @@ BUILTIN(ArraySplice) { |
} |
int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; |
- |
- if (FLAG_smi_only_arrays) { |
- MaybeObject* maybe = array->EnsureCanContainElements(&args, 3, item_count); |
- if (maybe->IsFailure()) return maybe; |
- } |
- |
int new_length = len - actual_delete_count + item_count; |
bool elms_changed = false; |
@@ -999,15 +1005,13 @@ BUILTIN(ArrayConcat) { |
} |
FixedArray* result_elms = FixedArray::cast(result); |
- if (FLAG_smi_only_arrays) { |
+ // Ensure element type transitions happen before copying elements in. |
+ if (result_array->HasFastSmiOnlyElements()) { |
for (int i = 0; i < n_arguments; i++) { |
JSArray* array = JSArray::cast(args[i]); |
- int len = Smi::cast(array->length())->value(); |
- if (len > 0) { |
- FixedArray* elms = FixedArray::cast(array->elements()); |
- MaybeObject* maybe_object = |
- result_array->EnsureCanContainElements(elms); |
- if (maybe_object->IsFailure()) return maybe_object; |
+ if (!array->HasFastSmiOnlyElements()) { |
+ result_array->EnsureCanContainNonSmiElements(); |
+ break; |
} |
} |
} |