Chromium Code Reviews| Index: src/builtins.cc |
| diff --git a/src/builtins.cc b/src/builtins.cc |
| index 90a8d3e1b843caa04ec42c00cc04457c13364c5c..102f867bcd4b11e41e65d39ee65626bc879ec168 100644 |
| --- a/src/builtins.cc |
| +++ b/src/builtins.cc |
| @@ -1,4 +1,4 @@ |
| -// Copyright 2011 the V8 project authors. All rights reserved. |
| +// Copyright 2012 the V8 project authors. All rights reserved. |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| @@ -193,13 +193,20 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args, |
| JSArray* array; |
| if (CalledAsConstructor(isolate)) { |
| array = JSArray::cast((*args)[0]); |
| + array->set_length(Smi::FromInt(0)); |
| + array->set_elements(heap->empty_fixed_array()); |
| + if (!FLAG_smi_only_arrays) { |
| + if (array->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { |
| + // Initialize elements and length in case the transition fails. |
|
Jakob Kummerow
2012/01/23 17:16:55
This comment seems misplaced.
danno
2012/01/26 21:32:34
Done.
|
| + Context* global_context = isolate->context()->global_context(); |
| + array->set_map(Map::cast(global_context->object_js_array_map())); |
| + } |
| + } |
| } else { |
| // Allocate the JS Array |
| - Object* obj; |
| - { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor); |
| - if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| - } |
| - array = JSArray::cast(obj); |
| + MaybeObject* maybe_obj = |
| + heap->AllocateEmptyJSArray(FAST_SMI_ONLY_ELEMENTS); |
| + if (!maybe_obj->To(&array)) return maybe_obj; |
| } |
| // Optimize the case where there is one argument and the argument is a |
| @@ -301,29 +308,6 @@ BUILTIN(ArrayCodeGeneric) { |
| } |
| -MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) { |
| - JSFunction* array_function = |
| - heap->isolate()->context()->global_context()->array_function(); |
| - Object* result; |
| - { MaybeObject* maybe_result = heap->AllocateJSObject(array_function); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - return result; |
| -} |
| - |
| - |
| -MUST_USE_RESULT static MaybeObject* AllocateEmptyJSArray(Heap* heap) { |
| - Object* result; |
| - { MaybeObject* maybe_result = AllocateJSArray(heap); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - JSArray* result_array = JSArray::cast(result); |
| - result_array->set_length(Smi::FromInt(0)); |
| - result_array->set_elements(heap->empty_fixed_array()); |
| - return result_array; |
| -} |
| - |
| - |
| static void CopyElements(Heap* heap, |
| AssertNoAllocation* no_gc, |
| FixedArray* dst, |
| @@ -331,6 +315,7 @@ static void CopyElements(Heap* heap, |
| FixedArray* src, |
| int src_index, |
| int len) { |
| + if (len == 0) return; |
| ASSERT(dst != src); // Use MoveElements instead. |
| ASSERT(dst->map() != HEAP->fixed_cow_array_map()); |
| ASSERT(len > 0); |
| @@ -352,6 +337,7 @@ static void MoveElements(Heap* heap, |
| FixedArray* src, |
| int src_index, |
| int len) { |
| + if (len == 0) return; |
| ASSERT(dst->map() != HEAP->fixed_cow_array_map()); |
| memmove(dst->data_start() + dst_index, |
| src->data_start() + src_index, |
| @@ -543,9 +529,7 @@ BUILTIN(ArrayPush) { |
| FixedArray* new_elms = FixedArray::cast(obj); |
| AssertNoAllocation no_gc; |
| - if (len > 0) { |
| - CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); |
| - } |
| + CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len); |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| @@ -681,9 +665,7 @@ BUILTIN(ArrayUnshift) { |
| } |
| FixedArray* new_elms = FixedArray::cast(obj); |
| AssertNoAllocation no_gc; |
| - if (len > 0) { |
| - CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len); |
| - } |
| + CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len); |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| array->set_elements(elms); |
| @@ -781,45 +763,22 @@ BUILTIN(ArraySlice) { |
| int final = (relative_end < 0) ? Max(len + relative_end, 0) |
| : Min(relative_end, len); |
| + ElementsKind elements_kind = JSObject::cast(receiver)->GetElementsKind(); |
| + |
| // Calculate the length of result array. |
| int result_len = final - k; |
|
Jakob Kummerow
2012/01/23 17:16:55
"= Max(final - k, 0)" please, as there's no guaran
danno
2012/01/26 21:32:34
Done.
|
| - if (result_len <= 0) { |
| - return AllocateEmptyJSArray(heap); |
| - } |
| - |
| - Object* result; |
| - { MaybeObject* maybe_result = AllocateJSArray(heap); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - JSArray* result_array = JSArray::cast(result); |
| - |
| - { MaybeObject* maybe_result = |
| - heap->AllocateUninitializedFixedArray(result_len); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - FixedArray* result_elms = FixedArray::cast(result); |
| - MaybeObject* maybe_object = |
| - result_array->EnsureCanContainElements(result_elms, |
| - DONT_ALLOW_DOUBLE_ELEMENTS); |
| - if (maybe_object->IsFailure()) return maybe_object; |
| + MaybeObject* maybe_array = |
| + heap->AllocateJSArrayAndStorage(elements_kind, |
| + result_len, |
| + result_len); |
| + JSArray* result_array; |
| + if (!maybe_array->To(&result_array)) return maybe_array; |
| AssertNoAllocation no_gc; |
| - CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len); |
| - |
| - // Set elements. |
| - result_array->set_elements(result_elms); |
| - |
| - // Set the length. |
| - result_array->set_length(Smi::FromInt(result_len)); |
| + CopyElements(heap, &no_gc, FixedArray::cast(result_array->elements()), 0, |
| + elms, k, result_len); |
| - // Set the ElementsKind. |
| - ElementsKind elements_kind = JSObject::cast(receiver)->GetElementsKind(); |
| - if (IsMoreGeneralElementsKindTransition(result_array->GetElementsKind(), |
| - elements_kind)) { |
| - MaybeObject* maybe = result_array->TransitionElementsKind(elements_kind); |
| - if (maybe->IsFailure()) return maybe; |
| - } |
| return result_array; |
| } |
| @@ -880,47 +839,22 @@ BUILTIN(ArraySplice) { |
| } |
| JSArray* result_array = NULL; |
| - if (actual_delete_count == 0) { |
| - Object* result; |
| - { MaybeObject* maybe_result = AllocateEmptyJSArray(heap); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - result_array = JSArray::cast(result); |
| - } else { |
| - // Allocate result array. |
| - Object* result; |
| - { MaybeObject* maybe_result = AllocateJSArray(heap); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - result_array = JSArray::cast(result); |
| - |
| - { MaybeObject* maybe_result = |
| - heap->AllocateUninitializedFixedArray(actual_delete_count); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - FixedArray* result_elms = FixedArray::cast(result); |
| + ElementsKind elements_kind = |
| + JSObject::cast(receiver)->GetElementsKind(); |
| + MaybeObject* maybe_array = |
| + heap->AllocateJSArrayAndStorage(elements_kind, |
| + actual_delete_count, |
| + actual_delete_count); |
| + if (!maybe_array->To(&result_array)) return maybe_array; |
| + { |
| AssertNoAllocation no_gc; |
| // Fill newly created array. |
| CopyElements(heap, |
| &no_gc, |
| - result_elms, 0, |
| + FixedArray::cast(result_array->elements()), 0, |
| elms, actual_start, |
| actual_delete_count); |
| - |
| - // Set elements. |
| - result_array->set_elements(result_elms); |
| - |
| - // Set the length. |
| - result_array->set_length(Smi::FromInt(actual_delete_count)); |
| - |
| - // Set the ElementsKind. |
| - ElementsKind elements_kind = array->GetElementsKind(); |
| - if (IsMoreGeneralElementsKindTransition(result_array->GetElementsKind(), |
| - elements_kind)) { |
| - MaybeObject* maybe = result_array->TransitionElementsKind(elements_kind); |
| - if (maybe->IsFailure()) return maybe; |
| - } |
| } |
| int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0; |
| @@ -935,7 +869,7 @@ BUILTIN(ArraySplice) { |
| if (trim_array) { |
| const int delta = actual_delete_count - item_count; |
| - if (actual_start > 0) { |
| + { |
| AssertNoAllocation no_gc; |
| MoveElements(heap, &no_gc, elms, delta, elms, 0, actual_start); |
| } |
| @@ -967,18 +901,17 @@ BUILTIN(ArraySplice) { |
| } |
| FixedArray* new_elms = FixedArray::cast(obj); |
| - AssertNoAllocation no_gc; |
| - // Copy the part before actual_start as is. |
| - if (actual_start > 0) { |
| + { |
| + AssertNoAllocation no_gc; |
| + // Copy the part before actual_start as is. |
| CopyElements(heap, &no_gc, new_elms, 0, elms, 0, actual_start); |
| - } |
| - const int to_copy = len - actual_delete_count - actual_start; |
| - if (to_copy > 0) { |
| + const int to_copy = len - actual_delete_count - actual_start; |
| CopyElements(heap, &no_gc, |
| new_elms, actual_start + item_count, |
| elms, actual_start + actual_delete_count, |
| to_copy); |
| } |
| + |
| FillWithHoles(heap, new_elms, new_length, capacity); |
| elms = new_elms; |
| @@ -1022,6 +955,7 @@ BUILTIN(ArrayConcat) { |
| // and calculating total length. |
| int n_arguments = args.length(); |
| int result_len = 0; |
| + ElementsKind elements_kind = FAST_SMI_ONLY_ELEMENTS; |
| for (int i = 0; i < n_arguments; i++) { |
| Object* arg = args[i]; |
| if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastTypeElements() |
| @@ -1041,54 +975,34 @@ BUILTIN(ArrayConcat) { |
| if (result_len > FixedArray::kMaxLength) { |
| return CallJsBuiltin(isolate, "ArrayConcat", args); |
| } |
| - } |
| - if (result_len == 0) { |
| - return AllocateEmptyJSArray(heap); |
| + if (!JSArray::cast(arg)->HasFastTypeElements()) { |
|
Jakob Kummerow
2012/01/23 17:16:55
This condition will never be true, as it's already
danno
2012/01/26 21:32:34
Done.
|
| + elements_kind = FAST_ELEMENTS; |
| + } |
| } |
| // Allocate result. |
| - Object* result; |
| - { MaybeObject* maybe_result = AllocateJSArray(heap); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - JSArray* result_array = JSArray::cast(result); |
| - |
| - { MaybeObject* maybe_result = |
| - heap->AllocateUninitializedFixedArray(result_len); |
| - if (!maybe_result->ToObject(&result)) return maybe_result; |
| - } |
| - FixedArray* result_elms = FixedArray::cast(result); |
| - |
| - // 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]); |
| - if (!array->HasFastSmiOnlyElements()) { |
| - result_array->EnsureCanContainHeapObjectElements(); |
| - break; |
| - } |
| - } |
| - } |
| + JSArray* result_array; |
| + MaybeObject* maybe_array = |
| + heap->AllocateJSArrayAndStorage(elements_kind, |
| + result_len, |
| + result_len); |
| + if (!maybe_array->To(&result_array)) return maybe_array; |
| + if (result_len == 0) return result_array; |
| // Copy data. |
| AssertNoAllocation no_gc; |
| int start_pos = 0; |
| + FixedArray* result_elms(FixedArray::cast(result_array->elements())); |
| 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()); |
| - CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len); |
| - start_pos += len; |
| - } |
| + FixedArray* elms = FixedArray::cast(array->elements()); |
| + CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len); |
| + start_pos += len; |
| } |
| ASSERT(start_pos == result_len); |
| - // Set the length and elements. |
| - result_array->set_length(Smi::FromInt(result_len)); |
| - result_array->set_elements(result_elms); |
| - |
| return result_array; |
| } |