Index: src/parser.cc |
=================================================================== |
--- src/parser.cc (revision 4088) |
+++ src/parser.cc (working copy) |
@@ -211,6 +211,7 @@ |
ZoneList<ObjectLiteral::Property*>* properties, |
Handle<FixedArray> constants, |
bool* is_simple, |
+ bool* fast_elements, |
int* depth); |
// Populate the literals fixed array for a materialized array literal. |
@@ -3445,7 +3446,11 @@ |
ObjectLiteral* object_literal = expression->AsObjectLiteral(); |
if (object_literal != NULL) { |
ASSERT(object_literal->is_simple()); |
- result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL)); |
+ if (object_literal->fast_elements()) { |
+ result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); |
+ } else { |
+ result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); |
+ } |
result->set(kElementsSlot, *object_literal->constant_properties()); |
} else { |
ArrayLiteral* array_literal = expression->AsArrayLiteral(); |
@@ -3483,11 +3488,14 @@ |
ZoneList<ObjectLiteral::Property*>* properties, |
Handle<FixedArray> constant_properties, |
bool* is_simple, |
+ bool* fast_elements, |
int* depth) { |
int position = 0; |
// Accumulate the value in local variables and store it at the end. |
bool is_simple_acc = true; |
int depth_acc = 1; |
+ uint32_t max_element_index = 0; |
+ uint32_t elements = 0; |
for (int i = 0; i < properties->length(); i++) { |
ObjectLiteral::Property* property = properties->at(i); |
if (!IsBoilerplateProperty(property)) { |
@@ -3506,11 +3514,31 @@ |
Handle<Object> value = GetBoilerplateValue(property->value()); |
is_simple_acc = is_simple_acc && !value->IsUndefined(); |
+ // Keep track of the number of elements in the object literal and |
+ // the largest element index. If the largest element index is |
+ // much larger than the number of elements, creating an object |
+ // literal with fast elements will be a waste of space. |
+ uint32_t element_index = 0; |
+ if (key->IsString() |
+ && Handle<String>::cast(key)->AsArrayIndex(&element_index) |
+ && element_index > max_element_index) { |
+ max_element_index = element_index; |
+ elements++; |
+ } else if (key->IsSmi()) { |
+ int key_value = Smi::cast(*key)->value(); |
+ if (key_value > 0 |
+ && static_cast<uint32_t>(key_value) > max_element_index) { |
+ max_element_index = key_value; |
+ } |
+ elements++; |
+ } |
+ |
// Add name, value pair to the fixed array. |
constant_properties->set(position++, *key); |
constant_properties->set(position++, *value); |
} |
- |
+ *fast_elements = |
+ (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
*is_simple = is_simple_acc; |
*depth = depth_acc; |
} |
@@ -3608,15 +3636,18 @@ |
Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); |
bool is_simple = true; |
+ bool fast_elements = true; |
int depth = 1; |
BuildObjectLiteralConstantProperties(properties.elements(), |
constant_properties, |
&is_simple, |
+ &fast_elements, |
&depth); |
return new ObjectLiteral(constant_properties, |
properties.elements(), |
literal_index, |
is_simple, |
+ fast_elements, |
depth); |
} |
@@ -4123,15 +4154,18 @@ |
Handle<FixedArray> constant_properties = |
Factory::NewFixedArray(boilerplate_properties * 2, TENURED); |
bool is_simple = true; |
+ bool fast_elements = true; |
int depth = 1; |
BuildObjectLiteralConstantProperties(properties.elements(), |
constant_properties, |
&is_simple, |
+ &fast_elements, |
&depth); |
return new ObjectLiteral(constant_properties, |
properties.elements(), |
literal_index, |
is_simple, |
+ fast_elements, |
depth); |
} |