| 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();
|
|
|