Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index fc6ca762f1495c98d7c29a6e24b6bb03ea995407..2eddaab42f00454f04c1126cb788cac497be2e3c 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -160,13 +160,22 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) { |
switch (copy->GetElementsKind()) { |
case JSObject::FAST_ELEMENTS: { |
FixedArray* elements = FixedArray::cast(copy->elements()); |
- for (int i = 0; i < elements->length(); i++) { |
- Object* value = elements->get(i); |
- if (value->IsJSObject()) { |
- JSObject* js_object = JSObject::cast(value); |
- result = DeepCopyBoilerplate(js_object); |
- if (result->IsFailure()) return result; |
- elements->set(i, result); |
+ if (elements->map() == Heap::fixed_cow_array_map()) { |
+ Counters::cow_arrays_created_runtime.Increment(); |
+#ifdef DEBUG |
+ for (int i = 0; i < elements->length(); i++) { |
+ ASSERT(!elements->get(i)->IsJSObject()); |
+ } |
+#endif |
+ } else { |
+ for (int i = 0; i < elements->length(); i++) { |
+ Object* value = elements->get(i); |
+ if (value->IsJSObject()) { |
+ JSObject* js_object = JSObject::cast(value); |
+ result = DeepCopyBoilerplate(js_object); |
+ if (result->IsFailure()) return result; |
+ elements->set(i, result); |
+ } |
} |
} |
break; |
@@ -343,18 +352,29 @@ static Handle<Object> CreateArrayLiteralBoilerplate( |
JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
Handle<Object> object = Factory::NewJSObject(constructor); |
- Handle<Object> copied_elements = Factory::CopyFixedArray(elements); |
+ const bool is_cow = (elements->map() == Heap::fixed_cow_array_map()); |
+ Handle<FixedArray> copied_elements = |
+ is_cow ? elements : Factory::CopyFixedArray(elements); |
Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
- for (int i = 0; i < content->length(); i++) { |
- if (content->get(i)->IsFixedArray()) { |
- // The value contains the constant_properties of a |
- // simple object literal. |
- Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
- Handle<Object> result = |
- CreateLiteralBoilerplate(literals, fa); |
- if (result.is_null()) return result; |
- content->set(i, *result); |
+ if (is_cow) { |
+#ifdef DEBUG |
+ // Copy-on-write arrays must be shallow (and simple). |
+ for (int i = 0; i < content->length(); i++) { |
+ ASSERT(!content->get(i)->IsFixedArray()); |
+ } |
+#endif |
+ } else { |
+ for (int i = 0; i < content->length(); i++) { |
+ if (content->get(i)->IsFixedArray()) { |
+ // The value contains the constant_properties of a |
+ // simple object literal. |
+ Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
+ Handle<Object> result = |
+ CreateLiteralBoilerplate(literals, fa); |
+ if (result.is_null()) return result; |
+ content->set(i, *result); |
+ } |
} |
} |
@@ -483,6 +503,10 @@ static Object* Runtime_CreateArrayLiteralShallow(Arguments args) { |
// Update the functions literal and return the boilerplate. |
literals->set(literals_index, *boilerplate); |
} |
+ if (JSObject::cast(*boilerplate)->elements()->map() == |
+ Heap::fixed_cow_array_map()) { |
+ Counters::cow_arrays_created_runtime.Increment(); |
+ } |
return Heap::CopyJSObject(JSObject::cast(*boilerplate)); |
} |
@@ -6699,9 +6723,13 @@ static Object* Runtime_DateYMDFromTime(Arguments args) { |
int year, month, day; |
DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); |
- res_array->SetElement(0, Smi::FromInt(year)); |
- res_array->SetElement(1, Smi::FromInt(month)); |
- res_array->SetElement(2, Smi::FromInt(day)); |
+ RUNTIME_ASSERT(res_array->elements()->map() == Heap::fixed_array_map()); |
+ FixedArray* elms = FixedArray::cast(res_array->elements()); |
+ RUNTIME_ASSERT(elms->length() == 3); |
+ |
+ elms->set(0, Smi::FromInt(year)); |
+ elms->set(1, Smi::FromInt(month)); |
+ elms->set(2, Smi::FromInt(day)); |
return Heap::undefined_value(); |
} |
@@ -8057,7 +8085,8 @@ static Object* Runtime_MoveArrayContents(Arguments args) { |
CONVERT_CHECKED(JSArray, to, args[1]); |
HeapObject* new_elements = from->elements(); |
Object* new_map; |
- if (new_elements->map() == Heap::fixed_array_map()) { |
+ if (new_elements->map() == Heap::fixed_array_map() || |
+ new_elements->map() == Heap::fixed_cow_array_map()) { |
new_map = to->map()->GetFastElementsMap(); |
} else { |
new_map = to->map()->GetSlowElementsMap(); |