Revision: 17557
Author: [email protected]
Date: Thu Nov 7 12:08:37 2013 UTC
Log: Defer allocation of constant literal properties.
This moves building of constant properties and elements arrays for all
materialized literals into the compiler. The parser no longer allocates
while parsing ObjectLiteral and ArrayLiteral expressions.
[email protected]
Review URL: https://codereview.chromium.org/61873003
http://code.google.com/p/v8/source/detail?r=17557
Modified:
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/ast.cc
/branches/bleeding_edge/src/ast.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/mips/full-codegen-mips.cc
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Nov 7 09:34:52
2013 UTC
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Thu Nov 7 12:08:37
2013 UTC
@@ -1634,6 +1634,9 @@
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
+
+ int depth = 1;
+ expr->BuildConstantProperties(isolate(), &depth);
Handle<FixedArray> constant_properties = expr->constant_properties();
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
@@ -1648,7 +1651,7 @@
__ mov(r0, Operand(Smi::FromInt(flags)));
int properties_count = constant_properties->length() / 2;
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
- expr->depth() > 1 || Serializer::enabled() ||
+ depth > 1 || Serializer::enabled() ||
flags != ObjectLiteral::kFastElements ||
properties_count >
FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ Push(r3, r2, r1, r0);
@@ -1767,6 +1770,8 @@
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
+ int depth = 1;
+ expr->BuildConstantElements(isolate(), &depth);
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1790,8 +1795,7 @@
__ CallStub(&stub);
__ IncrementCounter(
isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
- } else if (expr->depth() > 1 ||
- Serializer::enabled() ||
+ } else if (depth > 1 || Serializer::enabled() ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ Push(r3, r2, r1);
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
=======================================
--- /branches/bleeding_edge/src/ast.cc Fri Oct 25 11:10:28 2013 UTC
+++ /branches/bleeding_edge/src/ast.cc Thu Nov 7 12:08:37 2013 UTC
@@ -254,6 +254,169 @@
}
}
}
+
+
+bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property*
property) {
+ return property != NULL &&
+ property->kind() != ObjectLiteral::Property::PROTOTYPE;
+}
+
+
+void ObjectLiteral::BuildConstantProperties(Isolate* isolate, int* depth) {
+ if (!constant_properties_.is_null()) return;
+
+ // Allocate a fixed array to hold all the constant properties.
+ Handle<FixedArray> constant_properties =
isolate->factory()->NewFixedArray(
+ boilerplate_properties_ * 2, TENURED);
+
+ int position = 0;
+ // Accumulate the value in local variables and store it at the end.
+ bool is_simple = 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)) {
+ is_simple = false;
+ continue;
+ }
+ MaterializedLiteral* m_literal =
property->value()->AsMaterializedLiteral();
+ if (m_literal != NULL) {
+ int inner_depth = 1;
+ m_literal->BuildConstants(isolate, &inner_depth);
+ if (inner_depth >= depth_acc) depth_acc = inner_depth + 1;
+ }
+
+ // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
+ // value for COMPUTED properties, the real value is filled in at
+ // runtime. The enumeration order is maintained.
+ Handle<Object> key = property->key()->value();
+ Handle<Object> value = GetBoilerplateValue(property->value(), isolate);
+
+ // Ensure objects that may, at any point in time, contain fields with
double
+ // representation are always treated as nested objects. This is true
for
+ // computed fields (value is undefined), and smi and double literals
+ // (value->IsNumber()).
+ // TODO(verwaest): Remove once we can store them inline.
+ if (FLAG_track_double_fields &&
+ (value->IsNumber() || value->IsUninitialized())) {
+ may_store_doubles_ = true;
+ }
+
+ is_simple = is_simple && !value->IsUninitialized();
+
+ // 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);
+ }
+
+ constant_properties_ = constant_properties;
+ fast_elements_ =
+ (max_element_index <= 32) || ((2 * elements) >= max_element_index);
+ set_is_simple(is_simple);
+ if (depth != NULL) *depth = depth_acc;
+}
+
+
+void ArrayLiteral::BuildConstantElements(Isolate* isolate, int* depth) {
+ if (!constant_elements_.is_null()) return;
+
+ // Allocate a fixed array to hold all the object literals.
+ Handle<JSArray> array =
+ isolate->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS);
+ isolate->factory()->SetElementsCapacityAndLength(
+ array, values()->length(), values()->length());
+
+ // Fill in the literals.
+ bool is_simple = true;
+ int depth_acc = 1;
+ bool is_holey = false;
+ for (int i = 0, n = values()->length(); i < n; i++) {
+ Expression* element = values()->at(i);
+ MaterializedLiteral* m_literal = element->AsMaterializedLiteral();
+ if (m_literal != NULL) {
+ int inner_depth = 1;
+ m_literal->BuildConstants(isolate, &inner_depth);
+ if (inner_depth + 1 > depth_acc) depth_acc = inner_depth + 1;
+ }
+ Handle<Object> boilerplate_value = GetBoilerplateValue(element,
isolate);
+ if (boilerplate_value->IsTheHole()) {
+ is_holey = true;
+ } else if (boilerplate_value->IsUninitialized()) {
+ is_simple = false;
+ JSObject::SetOwnElement(
+ array, i, handle(Smi::FromInt(0), isolate), kNonStrictMode);
+ } else {
+ JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode);
+ }
+ }
+
+ Handle<FixedArrayBase> element_values(array->elements());
+
+ // Simple and shallow arrays can be lazily copied, we transform the
+ // elements array to a copy-on-write array.
+ if (is_simple && depth_acc == 1 && values()->length() > 0 &&
+ array->HasFastSmiOrObjectElements()) {
+ element_values->set_map(isolate->heap()->fixed_cow_array_map());
+ }
+
+ // Remember both the literal's constant values as well as the
ElementsKind
+ // in a 2-element FixedArray.
+ Handle<FixedArray> literals = isolate->factory()->NewFixedArray(2,
TENURED);
+
+ ElementsKind kind = array->GetElementsKind();
+ kind = is_holey ? GetHoleyElementsKind(kind) :
GetPackedElementsKind(kind);
+
+ literals->set(0, Smi::FromInt(kind));
+ literals->set(1, *element_values);
+
+ constant_elements_ = literals;
+ set_is_simple(is_simple);
+ if (depth != NULL) *depth = depth_acc;
+}
+
+
+Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression*
expression,
+ Isolate* isolate) {
+ if (expression->AsLiteral() != NULL) {
+ return expression->AsLiteral()->value();
+ }
+ if (CompileTimeValue::IsCompileTimeValue(expression)) {
+ return CompileTimeValue::GetValue(isolate, expression);
+ }
+ return isolate->factory()->uninitialized_value();
+}
+
+
+void MaterializedLiteral::BuildConstants(Isolate* isolate, int* depth) {
+ if (IsArrayLiteral()) {
+ return AsArrayLiteral()->BuildConstantElements(isolate, depth);
+ }
+ if (IsObjectLiteral()) {
+ return AsObjectLiteral()->BuildConstantProperties(isolate, depth);
+ }
+ ASSERT(IsRegExpLiteral());
+}
void TargetCollector::AddTarget(Label* target, Zone* zone) {
=======================================
--- /branches/bleeding_edge/src/ast.h Wed Oct 23 10:41:21 2013 UTC
+++ /branches/bleeding_edge/src/ast.h Thu Nov 7 12:08:37 2013 UTC
@@ -1408,28 +1408,36 @@
virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
int literal_index() { return literal_index_; }
-
- // A materialized literal is simple if the values consist of only
- // constants and simple object and array literals.
- bool is_simple() const { return is_simple_; }
-
- int depth() const { return depth_; }
protected:
MaterializedLiteral(Isolate* isolate,
int literal_index,
- bool is_simple,
- int depth,
int pos)
: Expression(isolate, pos),
literal_index_(literal_index),
- is_simple_(is_simple),
- depth_(depth) {}
+ is_simple_(false) {}
+
+ // A materialized literal is simple if the values consist of only
+ // constants and simple object and array literals.
+ bool is_simple() const { return is_simple_; }
+ void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
+ friend class CompileTimeValue;
+
+ // Populate the constant properties/elements fixed array.
+ void BuildConstants(Isolate* isolate, int* depth);
+ friend class ArrayLiteral;
+ friend class ObjectLiteral;
+
+ // If the expression is a literal, return the literal value;
+ // if the expression is a materialized literal and is simple return a
+ // compile time value as encoded by CompileTimeValue::GetValue().
+ // Otherwise, return undefined literal as the placeholder
+ // in the object literal boilerplate.
+ Handle<Object> GetBoilerplateValue(Expression* expression, Isolate*
isolate);
private:
int literal_index_;
bool is_simple_;
- int depth_;
};
@@ -1492,6 +1500,12 @@
bool fast_elements() const { return fast_elements_; }
bool may_store_doubles() const { return may_store_doubles_; }
bool has_function() const { return has_function_; }
+
+ // Decide if a property should be in the object boilerplate.
+ static bool IsBoilerplateProperty(Property* property);
+
+ // Populate the constant properties fixed array.
+ void BuildConstantProperties(Isolate* isolate, int* depth = NULL);
// Mark all computed expressions that are bound to a key that
// is shadowed by a later occurrence of the same key. For the
@@ -1512,25 +1526,22 @@
protected:
ObjectLiteral(Isolate* isolate,
- Handle<FixedArray> constant_properties,
ZoneList<Property*>* properties,
int literal_index,
- bool is_simple,
- bool fast_elements,
- int depth,
- bool may_store_doubles,
+ int boilerplate_properties,
bool has_function,
int pos)
- : MaterializedLiteral(isolate, literal_index, is_simple, depth, pos),
- constant_properties_(constant_properties),
+ : MaterializedLiteral(isolate, literal_index, pos),
properties_(properties),
- fast_elements_(fast_elements),
- may_store_doubles_(may_store_doubles),
+ boilerplate_properties_(boilerplate_properties),
+ fast_elements_(false),
+ may_store_doubles_(false),
has_function_(has_function) {}
private:
Handle<FixedArray> constant_properties_;
ZoneList<Property*>* properties_;
+ int boilerplate_properties_;
bool fast_elements_;
bool may_store_doubles_;
bool has_function_;
@@ -1551,7 +1562,7 @@
Handle<String> flags,
int literal_index,
int pos)
- : MaterializedLiteral(isolate, literal_index, false, 1, pos),
+ : MaterializedLiteral(isolate, literal_index, pos),
pattern_(pattern),
flags_(flags) {}
@@ -1574,17 +1585,16 @@
BailoutId GetIdForElement(int i) {
return BailoutId(first_element_id_.ToInt() + i);
}
+
+ // Populate the constant elements fixed array.
+ void BuildConstantElements(Isolate* isolate, int* depth = NULL);
protected:
ArrayLiteral(Isolate* isolate,
- Handle<FixedArray> constant_elements,
ZoneList<Expression*>* values,
int literal_index,
- bool is_simple,
- int depth,
int pos)
- : MaterializedLiteral(isolate, literal_index, is_simple, depth, pos),
- constant_elements_(constant_elements),
+ : MaterializedLiteral(isolate, literal_index, pos),
values_(values),
first_element_id_(ReserveIdRange(isolate, values->length())) {}
@@ -3066,18 +3076,14 @@
}
ObjectLiteral* NewObjectLiteral(
- Handle<FixedArray> constant_properties,
ZoneList<ObjectLiteral::Property*>* properties,
int literal_index,
- bool is_simple,
- bool fast_elements,
- int depth,
- bool may_store_doubles,
+ int boilerplate_properties,
bool has_function,
int pos) {
ObjectLiteral* lit = new(zone_) ObjectLiteral(
- isolate_, constant_properties, properties, literal_index,
- is_simple, fast_elements, depth, may_store_doubles, has_function,
pos);
+ isolate_, properties, literal_index, boilerplate_properties,
+ has_function, pos);
VISIT_AND_RETURN(ObjectLiteral, lit)
}
@@ -3099,15 +3105,11 @@
VISIT_AND_RETURN(RegExpLiteral, lit);
}
- ArrayLiteral* NewArrayLiteral(Handle<FixedArray> constant_elements,
- ZoneList<Expression*>* values,
+ ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
int literal_index,
- bool is_simple,
- int depth,
int pos) {
ArrayLiteral* lit = new(zone_) ArrayLiteral(
- isolate_, constant_elements, values, literal_index, is_simple,
- depth, pos);
+ isolate_, values, literal_index, pos);
VISIT_AND_RETURN(ArrayLiteral, lit)
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Nov 6 15:45:43 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Thu Nov 7 12:08:37 2013 UTC
@@ -4310,6 +4310,7 @@
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ expr->BuildConstantProperties(isolate());
Handle<JSFunction> closure =
function_state()->compilation_info()->closure();
HInstruction* literal;
@@ -4431,6 +4432,7 @@
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ expr->BuildConstantElements(isolate());
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
HInstruction* literal;
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Nov 7
09:34:52 2013 UTC
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Nov 7
12:08:37 2013 UTC
@@ -1574,6 +1574,9 @@
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
+
+ int depth = 1;
+ expr->BuildConstantProperties(isolate(), &depth);
Handle<FixedArray> constant_properties = expr->constant_properties();
int flags = expr->fast_elements()
? ObjectLiteral::kFastElements
@@ -1583,7 +1586,7 @@
: ObjectLiteral::kNoFlags;
int properties_count = constant_properties->length() / 2;
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
- expr->depth() > 1 || Serializer::enabled() ||
+ depth > 1 || Serializer::enabled() ||
flags != ObjectLiteral::kFastElements ||
properties_count >
FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
@@ -1702,6 +1705,8 @@
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
+ int depth = 1;
+ expr->BuildConstantElements(isolate(), &depth);
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1728,8 +1733,7 @@
DONT_TRACK_ALLOCATION_SITE,
length);
__ CallStub(&stub);
- } else if (expr->depth() > 1 ||
- Serializer::enabled() ||
+ } else if (depth > 1 || Serializer::enabled() ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Tue Nov 5
19:56:40 2013 UTC
+++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Thu Nov 7
12:08:37 2013 UTC
@@ -1644,6 +1644,9 @@
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
+
+ int depth = 1;
+ expr->BuildConstantProperties(isolate(), &depth);
Handle<FixedArray> constant_properties = expr->constant_properties();
__ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
@@ -1658,7 +1661,7 @@
__ li(a0, Operand(Smi::FromInt(flags)));
int properties_count = constant_properties->length() / 2;
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
- expr->depth() > 1 || Serializer::enabled() ||
+ depth > 1 || Serializer::enabled() ||
flags != ObjectLiteral::kFastElements ||
properties_count >
FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ Push(a3, a2, a1, a0);
@@ -1777,6 +1780,8 @@
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
+ int depth = 1;
+ expr->BuildConstantElements(isolate(), &depth);
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
@@ -1803,8 +1808,7 @@
__ CallStub(&stub);
__ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
1, a1, a2);
- } else if (expr->depth() > 1 ||
- Serializer::enabled() ||
+ } else if (depth > 1 || Serializer::enabled() ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ Push(a3, a2, a1);
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
=======================================
--- /branches/bleeding_edge/src/parser.cc Wed Nov 6 17:05:50 2013 UTC
+++ /branches/bleeding_edge/src/parser.cc Thu Nov 7 12:08:37 2013 UTC
@@ -3660,61 +3660,7 @@
// Update the scope information before the pre-parsing bailout.
int literal_index =
current_function_state_->NextMaterializedLiteralIndex();
- // Allocate a fixed array to hold all the object literals.
- Handle<JSArray> array =
- isolate()->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS);
- isolate()->factory()->SetElementsCapacityAndLength(
- array, values->length(), values->length());
-
- // Fill in the literals.
- Heap* heap = isolate()->heap();
- bool is_simple = true;
- int depth = 1;
- bool is_holey = false;
- for (int i = 0, n = values->length(); i < n; i++) {
- MaterializedLiteral* m_literal =
values->at(i)->AsMaterializedLiteral();
- if (m_literal != NULL && m_literal->depth() + 1 > depth) {
- depth = m_literal->depth() + 1;
- }
- Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
- if (boilerplate_value->IsTheHole()) {
- is_holey = true;
- } else if (boilerplate_value->IsUninitialized()) {
- is_simple = false;
- JSObject::SetOwnElement(
- array, i, handle(Smi::FromInt(0), isolate()), kNonStrictMode);
- } else {
- JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode);
- }
- }
-
- Handle<FixedArrayBase> element_values(array->elements());
-
- // Simple and shallow arrays can be lazily copied, we transform the
- // elements array to a copy-on-write array.
- if (is_simple && depth == 1 && values->length() > 0 &&
- array->HasFastSmiOrObjectElements()) {
- element_values->set_map(heap->fixed_cow_array_map());
- }
-
- // Remember both the literal's constant values as well as the
ElementsKind
- // in a 2-element FixedArray.
- Handle<FixedArray> literals = isolate()->factory()->NewFixedArray(2,
TENURED);
-
- ElementsKind kind = array->GetElementsKind();
- kind = is_holey ? GetHoleyElementsKind(kind) :
GetPackedElementsKind(kind);
-
- literals->set(0, Smi::FromInt(kind));
- literals->set(1, *element_values);
-
- return factory()->NewArrayLiteral(
- literals, values, literal_index, is_simple, depth, pos);
-}
-
-
-bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) {
- return property != NULL &&
- property->kind() != ObjectLiteral::Property::PROTOTYPE;
+ return factory()->NewArrayLiteral(values, literal_index, pos);
}
@@ -3759,89 +3705,6 @@
Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value)
{
return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot)));
}
-
-
-Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
- if (expression->AsLiteral() != NULL) {
- return expression->AsLiteral()->value();
- }
- if (CompileTimeValue::IsCompileTimeValue(expression)) {
- return CompileTimeValue::GetValue(isolate(), expression);
- }
- return isolate()->factory()->uninitialized_value();
-}
-
-
-void Parser::BuildObjectLiteralConstantProperties(
- ZoneList<ObjectLiteral::Property*>* properties,
- Handle<FixedArray> constant_properties,
- bool* is_simple,
- bool* fast_elements,
- int* depth,
- bool* may_store_doubles) {
- 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)) {
- is_simple_acc = false;
- continue;
- }
- MaterializedLiteral* m_literal =
property->value()->AsMaterializedLiteral();
- if (m_literal != NULL && m_literal->depth() >= depth_acc) {
- depth_acc = m_literal->depth() + 1;
- }
-
- // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
- // value for COMPUTED properties, the real value is filled in at
- // runtime. The enumeration order is maintained.
- Handle<Object> key = property->key()->value();
- Handle<Object> value = GetBoilerplateValue(property->value());
-
- // Ensure objects that may, at any point in time, contain fields with
double
- // representation are always treated as nested objects. This is true
for
- // computed fields (value is undefined), and smi and double literals
- // (value->IsNumber()).
- // TODO(verwaest): Remove once we can store them inline.
- if (FLAG_track_double_fields &&
- (value->IsNumber() || value->IsUninitialized())) {
- *may_store_doubles = true;
- }
-
- is_simple_acc = is_simple_acc && !value->IsUninitialized();
-
- // 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;
-}
Expression* Parser::ParseObjectLiteral(bool* ok) {
@@ -3912,7 +3775,7 @@
// Specification only allows zero parameters for get and one for
set.
ObjectLiteral::Property* property =
factory()->NewObjectLiteralProperty(is_getter, value,
next_pos);
- if (IsBoilerplateProperty(property)) {
+ if (ObjectLiteral::IsBoilerplateProperty(property)) {
number_of_boilerplate_properties++;
}
properties->Add(property, zone());
@@ -3984,7 +3847,9 @@
}
// Count CONSTANT or COMPUTED properties to maintain the enumeration
order.
- if (IsBoilerplateProperty(property))
number_of_boilerplate_properties++;
+ if (ObjectLiteral::IsBoilerplateProperty(property)) {
+ number_of_boilerplate_properties++;
+ }
properties->Add(property, zone());
// TODO(1240767): Consider allowing trailing comma.
@@ -4000,26 +3865,9 @@
// Computation of literal_index must happen before pre parse bailout.
int literal_index =
current_function_state_->NextMaterializedLiteralIndex();
- Handle<FixedArray> constant_properties =
isolate()->factory()->NewFixedArray(
- number_of_boilerplate_properties * 2, TENURED);
-
- bool is_simple = true;
- bool fast_elements = true;
- int depth = 1;
- bool may_store_doubles = false;
- BuildObjectLiteralConstantProperties(properties,
- constant_properties,
- &is_simple,
- &fast_elements,
- &depth,
- &may_store_doubles);
- return factory()->NewObjectLiteral(constant_properties,
- properties,
+ return factory()->NewObjectLiteral(properties,
literal_index,
- is_simple,
- fast_elements,
- depth,
- may_store_doubles,
+ number_of_boilerplate_properties,
has_function,
pos);
}
=======================================
--- /branches/bleeding_edge/src/parser.h Tue Oct 15 08:32:58 2013 UTC
+++ /branches/bleeding_edge/src/parser.h Thu Nov 7 12:08:37 2013 UTC
@@ -653,25 +653,6 @@
Expression* ParseObjectLiteral(bool* ok);
Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
- // Populate the constant properties fixed array for a materialized object
- // literal.
- void BuildObjectLiteralConstantProperties(
- ZoneList<ObjectLiteral::Property*>* properties,
- Handle<FixedArray> constants,
- bool* is_simple,
- bool* fast_elements,
- int* depth,
- bool* may_store_doubles);
-
- // Decide if a property should be in the object boilerplate.
- bool IsBoilerplateProperty(ObjectLiteral::Property* property);
- // If the expression is a literal, return the literal value;
- // if the expression is a materialized literal and is simple return a
- // compile time value as encoded by CompileTimeValue::GetValue().
- // Otherwise, return undefined literal as the placeholder
- // in the object literal boilerplate.
- Handle<Object> GetBoilerplateValue(Expression* expression);
-
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt,
Expression* each,
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu Nov 7 09:34:52
2013 UTC
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Thu Nov 7 12:08:37
2013 UTC
@@ -1595,6 +1595,9 @@
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
+
+ int depth = 1;
+ expr->BuildConstantProperties(isolate(), &depth);
Handle<FixedArray> constant_properties = expr->constant_properties();
int flags = expr->fast_elements()
? ObjectLiteral::kFastElements
@@ -1604,7 +1607,7 @@
: ObjectLiteral::kNoFlags;
int properties_count = constant_properties->length() / 2;
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
- expr->depth() > 1 || Serializer::enabled() ||
+ depth > 1 || Serializer::enabled() ||
flags != ObjectLiteral::kFastElements ||
properties_count >
FastCloneShallowObjectStub::kMaximumClonedProperties) {
__ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
@@ -1723,6 +1726,8 @@
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
+ int depth = 1;
+ expr->BuildConstantElements(isolate(), &depth);
ZoneList<Expression*>* subexprs = expr->values();
int length = subexprs->length();
Handle<FixedArray> constant_elements = expr->constant_elements();
@@ -1749,8 +1754,7 @@
DONT_TRACK_ALLOCATION_SITE,
length);
__ CallStub(&stub);
- } else if (expr->depth() > 1 ||
- Serializer::enabled() ||
+ } else if (depth > 1 || Serializer::enabled() ||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
__ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.