MaterializedLiteral expressions need to cache expression depth.
A problem arises in recursive literal expressions due to recent changes that defer allocation of constant literal properties from parse time. We were calculating expression depth as a side-effect of a lazy constant property build, but subsequent calls for the depth always returned 1. Cache the correct depth in the MaterializedLiteral instead. (Related-to/very-partial-revert-of https://codereview.chromium.org/61873003) R=ulan@chromium.org Review URL: https://codereview.chromium.org/78493002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17929 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
718b38648f
commit
b90d87c382
@ -1635,8 +1635,7 @@ void FullCodeGenerator::EmitAccessor(Expression* expression) {
|
||||
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ObjectLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantProperties(isolate(), &depth);
|
||||
expr->BuildConstantProperties(isolate());
|
||||
Handle<FixedArray> constant_properties = expr->constant_properties();
|
||||
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
|
||||
@ -1651,7 +1650,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
__ mov(r0, Operand(Smi::FromInt(flags)));
|
||||
int properties_count = constant_properties->length() / 2;
|
||||
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
|
||||
depth > 1 || Serializer::enabled() ||
|
||||
expr->depth() > 1 || Serializer::enabled() ||
|
||||
flags != ObjectLiteral::kFastElements ||
|
||||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
|
||||
__ Push(r3, r2, r1, r0);
|
||||
@ -1770,8 +1769,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ArrayLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantElements(isolate(), &depth);
|
||||
expr->BuildConstantElements(isolate());
|
||||
ZoneList<Expression*>* subexprs = expr->values();
|
||||
int length = subexprs->length();
|
||||
Handle<FixedArray> constant_elements = expr->constant_elements();
|
||||
@ -1795,7 +1793,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ CallStub(&stub);
|
||||
__ IncrementCounter(
|
||||
isolate()->counters()->cow_arrays_created_stub(), 1, r1, r2);
|
||||
} else if (depth > 1 || Serializer::enabled() ||
|
||||
} else if (expr->depth() > 1 || Serializer::enabled() ||
|
||||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
||||
__ Push(r3, r2, r1);
|
||||
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
||||
|
27
src/ast.cc
27
src/ast.cc
@ -262,7 +262,7 @@ bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) {
|
||||
}
|
||||
|
||||
|
||||
void ObjectLiteral::BuildConstantProperties(Isolate* isolate, int* depth) {
|
||||
void ObjectLiteral::BuildConstantProperties(Isolate* isolate) {
|
||||
if (!constant_properties_.is_null()) return;
|
||||
|
||||
// Allocate a fixed array to hold all the constant properties.
|
||||
@ -283,9 +283,8 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate, int* depth) {
|
||||
}
|
||||
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;
|
||||
m_literal->BuildConstants(isolate);
|
||||
if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1;
|
||||
}
|
||||
|
||||
// Add CONSTANT and COMPUTED properties to boilerplate. Use undefined
|
||||
@ -334,11 +333,11 @@ void ObjectLiteral::BuildConstantProperties(Isolate* isolate, int* depth) {
|
||||
fast_elements_ =
|
||||
(max_element_index <= 32) || ((2 * elements) >= max_element_index);
|
||||
set_is_simple(is_simple);
|
||||
if (depth != NULL) *depth = depth_acc;
|
||||
set_depth(depth_acc);
|
||||
}
|
||||
|
||||
|
||||
void ArrayLiteral::BuildConstantElements(Isolate* isolate, int* depth) {
|
||||
void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
|
||||
if (!constant_elements_.is_null()) return;
|
||||
|
||||
// Allocate a fixed array to hold all the object literals.
|
||||
@ -355,9 +354,10 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate, int* depth) {
|
||||
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;
|
||||
m_literal->BuildConstants(isolate);
|
||||
if (m_literal->depth() + 1 > depth_acc) {
|
||||
depth_acc = m_literal->depth() + 1;
|
||||
}
|
||||
}
|
||||
Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate);
|
||||
if (boilerplate_value->IsTheHole()) {
|
||||
@ -392,7 +392,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate, int* depth) {
|
||||
|
||||
constant_elements_ = literals;
|
||||
set_is_simple(is_simple);
|
||||
if (depth != NULL) *depth = depth_acc;
|
||||
set_depth(depth_acc);
|
||||
}
|
||||
|
||||
|
||||
@ -408,14 +408,15 @@ Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression,
|
||||
}
|
||||
|
||||
|
||||
void MaterializedLiteral::BuildConstants(Isolate* isolate, int* depth) {
|
||||
void MaterializedLiteral::BuildConstants(Isolate* isolate) {
|
||||
if (IsArrayLiteral()) {
|
||||
return AsArrayLiteral()->BuildConstantElements(isolate, depth);
|
||||
return AsArrayLiteral()->BuildConstantElements(isolate);
|
||||
}
|
||||
if (IsObjectLiteral()) {
|
||||
return AsObjectLiteral()->BuildConstantProperties(isolate, depth);
|
||||
return AsObjectLiteral()->BuildConstantProperties(isolate);
|
||||
}
|
||||
ASSERT(IsRegExpLiteral());
|
||||
ASSERT(depth() >= 1); // Depth should be initialized.
|
||||
}
|
||||
|
||||
|
||||
|
25
src/ast.h
25
src/ast.h
@ -1409,13 +1409,20 @@ class MaterializedLiteral : public Expression {
|
||||
|
||||
int literal_index() { return literal_index_; }
|
||||
|
||||
int depth() const {
|
||||
// only callable after initialization.
|
||||
ASSERT(depth_ >= 1);
|
||||
return depth_;
|
||||
}
|
||||
|
||||
protected:
|
||||
MaterializedLiteral(Isolate* isolate,
|
||||
int literal_index,
|
||||
int pos)
|
||||
: Expression(isolate, pos),
|
||||
literal_index_(literal_index),
|
||||
is_simple_(false) {}
|
||||
is_simple_(false),
|
||||
depth_(0) {}
|
||||
|
||||
// A materialized literal is simple if the values consist of only
|
||||
// constants and simple object and array literals.
|
||||
@ -1423,8 +1430,13 @@ class MaterializedLiteral : public Expression {
|
||||
void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
|
||||
friend class CompileTimeValue;
|
||||
|
||||
void set_depth(int depth) {
|
||||
ASSERT(depth >= 1);
|
||||
depth_ = depth;
|
||||
}
|
||||
|
||||
// Populate the constant properties/elements fixed array.
|
||||
void BuildConstants(Isolate* isolate, int* depth);
|
||||
void BuildConstants(Isolate* isolate);
|
||||
friend class ArrayLiteral;
|
||||
friend class ObjectLiteral;
|
||||
|
||||
@ -1438,6 +1450,7 @@ class MaterializedLiteral : public Expression {
|
||||
private:
|
||||
int literal_index_;
|
||||
bool is_simple_;
|
||||
int depth_;
|
||||
};
|
||||
|
||||
|
||||
@ -1505,7 +1518,7 @@ class ObjectLiteral V8_FINAL : public MaterializedLiteral {
|
||||
static bool IsBoilerplateProperty(Property* property);
|
||||
|
||||
// Populate the constant properties fixed array.
|
||||
void BuildConstantProperties(Isolate* isolate, int* depth = NULL);
|
||||
void BuildConstantProperties(Isolate* isolate);
|
||||
|
||||
// Mark all computed expressions that are bound to a key that
|
||||
// is shadowed by a later occurrence of the same key. For the
|
||||
@ -1564,7 +1577,9 @@ class RegExpLiteral V8_FINAL : public MaterializedLiteral {
|
||||
int pos)
|
||||
: MaterializedLiteral(isolate, literal_index, pos),
|
||||
pattern_(pattern),
|
||||
flags_(flags) {}
|
||||
flags_(flags) {
|
||||
set_depth(1);
|
||||
}
|
||||
|
||||
private:
|
||||
Handle<String> pattern_;
|
||||
@ -1587,7 +1602,7 @@ class ArrayLiteral V8_FINAL : public MaterializedLiteral {
|
||||
}
|
||||
|
||||
// Populate the constant elements fixed array.
|
||||
void BuildConstantElements(Isolate* isolate, int* depth = NULL);
|
||||
void BuildConstantElements(Isolate* isolate);
|
||||
|
||||
protected:
|
||||
ArrayLiteral(Isolate* isolate,
|
||||
|
@ -1575,8 +1575,7 @@ void FullCodeGenerator::EmitAccessor(Expression* expression) {
|
||||
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ObjectLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantProperties(isolate(), &depth);
|
||||
expr->BuildConstantProperties(isolate());
|
||||
Handle<FixedArray> constant_properties = expr->constant_properties();
|
||||
int flags = expr->fast_elements()
|
||||
? ObjectLiteral::kFastElements
|
||||
@ -1586,7 +1585,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
: ObjectLiteral::kNoFlags;
|
||||
int properties_count = constant_properties->length() / 2;
|
||||
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
|
||||
depth > 1 || Serializer::enabled() ||
|
||||
expr->depth() > 1 || Serializer::enabled() ||
|
||||
flags != ObjectLiteral::kFastElements ||
|
||||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
|
||||
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
@ -1705,8 +1704,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ArrayLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantElements(isolate(), &depth);
|
||||
expr->BuildConstantElements(isolate());
|
||||
ZoneList<Expression*>* subexprs = expr->values();
|
||||
int length = subexprs->length();
|
||||
Handle<FixedArray> constant_elements = expr->constant_elements();
|
||||
@ -1733,7 +1731,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
DONT_TRACK_ALLOCATION_SITE,
|
||||
length);
|
||||
__ CallStub(&stub);
|
||||
} else if (depth > 1 || Serializer::enabled() ||
|
||||
} else if (expr->depth() > 1 || Serializer::enabled() ||
|
||||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
||||
__ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ push(FieldOperand(ebx, JSFunction::kLiteralsOffset));
|
||||
|
@ -1645,8 +1645,7 @@ void FullCodeGenerator::EmitAccessor(Expression* expression) {
|
||||
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ObjectLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantProperties(isolate(), &depth);
|
||||
expr->BuildConstantProperties(isolate());
|
||||
Handle<FixedArray> constant_properties = expr->constant_properties();
|
||||
__ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
|
||||
@ -1661,7 +1660,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
__ li(a0, Operand(Smi::FromInt(flags)));
|
||||
int properties_count = constant_properties->length() / 2;
|
||||
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
|
||||
depth > 1 || Serializer::enabled() ||
|
||||
expr->depth() > 1 || Serializer::enabled() ||
|
||||
flags != ObjectLiteral::kFastElements ||
|
||||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
|
||||
__ Push(a3, a2, a1, a0);
|
||||
@ -1780,8 +1779,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ArrayLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantElements(isolate(), &depth);
|
||||
expr->BuildConstantElements(isolate());
|
||||
ZoneList<Expression*>* subexprs = expr->values();
|
||||
int length = subexprs->length();
|
||||
|
||||
@ -1808,7 +1806,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
__ CallStub(&stub);
|
||||
__ IncrementCounter(isolate()->counters()->cow_arrays_created_stub(),
|
||||
1, a1, a2);
|
||||
} else if (depth > 1 || Serializer::enabled() ||
|
||||
} else if (expr->depth() > 1 || Serializer::enabled() ||
|
||||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
||||
__ Push(a3, a2, a1);
|
||||
__ CallRuntime(Runtime::kCreateArrayLiteral, 3);
|
||||
|
@ -1596,8 +1596,7 @@ void FullCodeGenerator::EmitAccessor(Expression* expression) {
|
||||
void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ObjectLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantProperties(isolate(), &depth);
|
||||
expr->BuildConstantProperties(isolate());
|
||||
Handle<FixedArray> constant_properties = expr->constant_properties();
|
||||
int flags = expr->fast_elements()
|
||||
? ObjectLiteral::kFastElements
|
||||
@ -1607,7 +1606,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
: ObjectLiteral::kNoFlags;
|
||||
int properties_count = constant_properties->length() / 2;
|
||||
if ((FLAG_track_double_fields && expr->may_store_doubles()) ||
|
||||
depth > 1 || Serializer::enabled() ||
|
||||
expr->depth() > 1 || Serializer::enabled() ||
|
||||
flags != ObjectLiteral::kFastElements ||
|
||||
properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
|
||||
__ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
@ -1726,8 +1725,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
Comment cmnt(masm_, "[ ArrayLiteral");
|
||||
|
||||
int depth = 1;
|
||||
expr->BuildConstantElements(isolate(), &depth);
|
||||
expr->BuildConstantElements(isolate());
|
||||
ZoneList<Expression*>* subexprs = expr->values();
|
||||
int length = subexprs->length();
|
||||
Handle<FixedArray> constant_elements = expr->constant_elements();
|
||||
@ -1754,7 +1752,7 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
DONT_TRACK_ALLOCATION_SITE,
|
||||
length);
|
||||
__ CallStub(&stub);
|
||||
} else if (depth > 1 || Serializer::enabled() ||
|
||||
} else if (expr->depth() > 1 || Serializer::enabled() ||
|
||||
length > FastCloneShallowArrayStub::kMaximumClonedLength) {
|
||||
__ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
__ push(FieldOperand(rbx, JSFunction::kLiteralsOffset));
|
||||
|
Loading…
Reference in New Issue
Block a user