| Index: src/runtime.cc
|
| diff --git a/src/runtime.cc b/src/runtime.cc
|
| index cb1a463b3f73d5fa0821524006bc16311a523408..58802f046cce8406df824c3048547ee33ce61c53 100644
|
| --- a/src/runtime.cc
|
| +++ b/src/runtime.cc
|
| @@ -432,64 +432,77 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
|
| // Create the JSArray.
|
| Handle<JSFunction> constructor(
|
| JSFunction::GlobalContextFromLiterals(*literals)->array_function());
|
| - Handle<Object> object = isolate->factory()->NewJSObject(constructor);
|
| + Handle<JSArray> object =
|
| + Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
|
|
|
| - if (elements->length() > kSmiOnlyLiteralMinimumLength) {
|
| + ElementsKind constant_elements_kind =
|
| + static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
|
| + Handle<FixedArrayBase> constant_elements_values(
|
| + FixedArrayBase::cast(elements->get(1)));
|
| +
|
| + ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS ||
|
| + constant_elements_kind == FAST_SMI_ONLY_ELEMENTS);
|
| + bool allow_literal_kind_transition = FLAG_smi_only_arrays &&
|
| + constant_elements_kind > object->GetElementsKind();
|
| +
|
| + if (!FLAG_smi_only_arrays &&
|
| + constant_elements_values->length() > kSmiOnlyLiteralMinimumLength &&
|
| + constant_elements_kind != object->GetElementsKind()) {
|
| + allow_literal_kind_transition = true;
|
| + }
|
| +
|
| + // If the ElementKinds of the constant values of the array literal are less
|
| + // specific that the ElementsKind of the boilerplate array object, change the
|
| + // boilerplate array object's map to reflect that kind.
|
| + if (allow_literal_kind_transition) {
|
| Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap(
|
| - Handle<JSObject>::cast(object),
|
| - FAST_SMI_ONLY_ELEMENTS);
|
| - HeapObject::cast(*object)->set_map(*smi_array_map);
|
| - }
|
| -
|
| - const bool is_cow =
|
| - (elements->map() == isolate->heap()->fixed_cow_array_map());
|
| - Handle<FixedArray> copied_elements =
|
| - is_cow ? elements : isolate->factory()->CopyFixedArray(elements);
|
| -
|
| - Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements);
|
| - bool has_non_smi = false;
|
| - if (is_cow) {
|
| - // Copy-on-write arrays must be shallow (and simple).
|
| - for (int i = 0; i < content->length(); i++) {
|
| - Object* current = content->get(i);
|
| - ASSERT(!current->IsFixedArray());
|
| - if (!current->IsSmi() && !current->IsTheHole()) {
|
| - has_non_smi = true;
|
| - }
|
| - }
|
| + object,
|
| + constant_elements_kind);
|
| + object->set_map(*smi_array_map);
|
| + }
|
| +
|
| + Handle<FixedArrayBase> copied_elements_values;
|
| + if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
|
| + ASSERT(FLAG_smi_only_arrays);
|
| + copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
|
| + Handle<FixedDoubleArray>::cast(constant_elements_values));
|
| + } else {
|
| + ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
|
| + constant_elements_kind == FAST_ELEMENTS);
|
| + const bool is_cow =
|
| + (constant_elements_values->map() ==
|
| + isolate->heap()->fixed_cow_array_map());
|
| + if (is_cow) {
|
| + copied_elements_values = constant_elements_values;
|
| #if DEBUG
|
| - for (int i = 0; i < content->length(); i++) {
|
| - ASSERT(!content->get(i)->IsFixedArray());
|
| - }
|
| + Handle<FixedArray> fixed_array_values =
|
| + Handle<FixedArray>::cast(copied_elements_values);
|
| + for (int i = 0; i < fixed_array_values->length(); i++) {
|
| + ASSERT(!fixed_array_values->get(i)->IsFixedArray());
|
| + }
|
| #endif
|
| - } else {
|
| - for (int i = 0; i < content->length(); i++) {
|
| - Object* current = content->get(i);
|
| - if (current->IsFixedArray()) {
|
| - // The value contains the constant_properties of a
|
| - // simple object or array literal.
|
| - Handle<FixedArray> fa(FixedArray::cast(content->get(i)));
|
| - Handle<Object> result =
|
| - CreateLiteralBoilerplate(isolate, literals, fa);
|
| - if (result.is_null()) return result;
|
| - content->set(i, *result);
|
| - has_non_smi = true;
|
| - } else {
|
| - if (!current->IsSmi() && !current->IsTheHole()) {
|
| - has_non_smi = true;
|
| + } else {
|
| + Handle<FixedArray> fixed_array_values =
|
| + Handle<FixedArray>::cast(constant_elements_values);
|
| + Handle<FixedArray> fixed_array_values_copy =
|
| + isolate->factory()->CopyFixedArray(fixed_array_values);
|
| + copied_elements_values = fixed_array_values_copy;
|
| + for (int i = 0; i < fixed_array_values->length(); i++) {
|
| + Object* current = fixed_array_values->get(i);
|
| + if (current->IsFixedArray()) {
|
| + // The value contains the constant_properties of a
|
| + // simple object or array literal.
|
| + Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
|
| + Handle<Object> result =
|
| + CreateLiteralBoilerplate(isolate, literals, fa);
|
| + if (result.is_null()) return result;
|
| + fixed_array_values_copy->set(i, *result);
|
| }
|
| }
|
| }
|
| }
|
| -
|
| - // Set the elements.
|
| - Handle<JSArray> js_object(Handle<JSArray>::cast(object));
|
| - isolate->factory()->SetContent(js_object, content);
|
| -
|
| - if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
|
| - isolate->factory()->EnsureCanContainNonSmiElements(js_object);
|
| - }
|
| -
|
| + object->set_elements(*copied_elements_values);
|
| + object->set_length(Smi::FromInt(copied_elements_values->length()));
|
| return object;
|
| }
|
|
|
| @@ -1663,19 +1676,6 @@ RUNTIME_FUNCTION(MaybeObject*,
|
| }
|
|
|
|
|
| -RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
|
| - ASSERT(args.length() == 1);
|
| - CONVERT_ARG_CHECKED(JSObject, object, 0);
|
| - if (object->HasFastSmiOnlyElements()) {
|
| - MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
|
| - Map* map;
|
| - if (!maybe_map->To<Map>(&map)) return maybe_map;
|
| - object->set_map(Map::cast(map));
|
| - }
|
| - return *object;
|
| -}
|
| -
|
| -
|
| RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
|
| HandleScope scope(isolate);
|
| ASSERT(args.length() == 4);
|
| @@ -7735,14 +7735,21 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
|
| int year, month, day;
|
| DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
|
|
|
| - RUNTIME_ASSERT(res_array->elements()->map() ==
|
| - isolate->heap()->fixed_array_map());
|
| - FixedArray* elms = FixedArray::cast(res_array->elements());
|
| - RUNTIME_ASSERT(elms->length() == 3);
|
| + FixedArrayBase* elms_base = FixedArrayBase::cast(res_array->elements());
|
| + RUNTIME_ASSERT(elms_base->length() == 3);
|
| + RUNTIME_ASSERT(res_array->GetElementsKind() <= FAST_DOUBLE_ELEMENTS);
|
|
|
| - elms->set(0, Smi::FromInt(year));
|
| - elms->set(1, Smi::FromInt(month));
|
| - elms->set(2, Smi::FromInt(day));
|
| + if (res_array->HasFastDoubleElements()) {
|
| + FixedDoubleArray* elms = FixedDoubleArray::cast(res_array->elements());
|
| + elms->set(0, year);
|
| + elms->set(1, month);
|
| + elms->set(2, day);
|
| + } else {
|
| + FixedArray* elms = FixedArray::cast(res_array->elements());
|
| + elms->set(0, Smi::FromInt(year));
|
| + elms->set(1, Smi::FromInt(month));
|
| + elms->set(2, Smi::FromInt(day));
|
| + }
|
|
|
| return isolate->heap()->undefined_value();
|
| }
|
|
|