Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1579)

Unified Diff: src/builtins.cc

Issue 9073007: Store transitioned JSArray maps in global context (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index 90a8d3e1b843caa04ec42c00cc04457c13364c5c..4bb451cadedf6c8a0f9274e60b07610908697911 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,21 @@ static MaybeObject* ArrayCodeGenericCommon(Arguments* args,
JSArray* array;
if (CalledAsConstructor(isolate)) {
array = JSArray::cast((*args)[0]);
+ // Initialize elements and length in case later allocations fail so that the
+ // array object is initialized in a valid state.
+ 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) {
+ 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 +309,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 +316,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 +338,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 +530,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 +666,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 +764,22 @@ BUILTIN(ArraySlice) {
int final = (relative_end < 0) ? Max(len + relative_end, 0)
: Min(relative_end, len);
- // Calculate the length of result array.
- int result_len = final - k;
- 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);
+ ElementsKind elements_kind = JSObject::cast(receiver)->GetElementsKind();
- { MaybeObject* maybe_result =
- heap->AllocateUninitializedFixedArray(result_len);
- if (!maybe_result->ToObject(&result)) return maybe_result;
- }
- FixedArray* result_elms = FixedArray::cast(result);
+ // Calculate the length of result array.
+ int result_len = Max(final - k, 0);
- 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 +840,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 +870,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 +902,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 +956,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 +976,34 @@ BUILTIN(ArrayConcat) {
if (result_len > FixedArray::kMaxLength) {
return CallJsBuiltin(isolate, "ArrayConcat", args);
}
- }
- if (result_len == 0) {
- return AllocateEmptyJSArray(heap);
+ if (!JSArray::cast(arg)->HasFastElements()) {
+ 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;
}
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698