Don't count duplicate assignments to the same property as distinct ones.

In the ThisNamedPropertyAssignmentFinder, duplicate assignments to the same
property were counted as distinct assignments.  As a simple fix, subsequent
ones overwrite the previously recorded assignment.

This will reorder the assignments, but it is safe since they are restricted
to have only constants and parameters on the right-hand side (and there are
no assignments to the parameters).

R=vegorov@chromium.org
BUG=
TEST=

Review URL: http://codereview.chromium.org/8139037

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2011-10-06 12:38:18 +00:00
parent 11d79c5233
commit fa425b54b7

View File

@ -957,17 +957,18 @@ class InitializationBlockFinder : public ParserFinder {
};
// A ThisNamedPropertyAssigmentFinder finds and marks statements of the form
// A ThisNamedPropertyAssignmentFinder finds and marks statements of the form
// this.x = ...;, where x is a named property. It also determines whether a
// function contains only assignments of this type.
class ThisNamedPropertyAssigmentFinder : public ParserFinder {
class ThisNamedPropertyAssignmentFinder : public ParserFinder {
public:
explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate)
explicit ThisNamedPropertyAssignmentFinder(Isolate* isolate)
: isolate_(isolate),
only_simple_this_property_assignments_(true),
names_(NULL),
assigned_arguments_(NULL),
assigned_constants_(NULL) {}
names_(0),
assigned_arguments_(0),
assigned_constants_(0) {
}
void Update(Scope* scope, Statement* stat) {
// Bail out if function already has property assignment that are
@ -994,19 +995,17 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
// Returns a fixed array containing three elements for each assignment of the
// form this.x = y;
Handle<FixedArray> GetThisPropertyAssignments() {
if (names_ == NULL) {
if (names_.is_empty()) {
return isolate_->factory()->empty_fixed_array();
}
ASSERT(names_ != NULL);
ASSERT(assigned_arguments_ != NULL);
ASSERT_EQ(names_->length(), assigned_arguments_->length());
ASSERT_EQ(names_->length(), assigned_constants_->length());
ASSERT_EQ(names_.length(), assigned_arguments_.length());
ASSERT_EQ(names_.length(), assigned_constants_.length());
Handle<FixedArray> assignments =
isolate_->factory()->NewFixedArray(names_->length() * 3);
for (int i = 0; i < names_->length(); i++) {
assignments->set(i * 3, *names_->at(i));
assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
assignments->set(i * 3 + 2, *assigned_constants_->at(i));
isolate_->factory()->NewFixedArray(names_.length() * 3);
for (int i = 0; i < names_.length(); ++i) {
assignments->set(i * 3, *names_[i]);
assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_[i]));
assignments->set(i * 3 + 2, *assigned_constants_[i]);
}
return assignments;
}
@ -1063,18 +1062,37 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
AssignmentFromSomethingElse();
}
// We will potentially reorder the property assignments, so they must be
// simple enough that the ordering does not matter.
void AssignmentFromParameter(Handle<String> name, int index) {
EnsureAllocation();
names_->Add(name);
assigned_arguments_->Add(index);
assigned_constants_->Add(isolate_->factory()->undefined_value());
EnsureInitialized();
for (int i = 0; i < names_.length(); ++i) {
if (name->Equals(*names_[i])) {
assigned_arguments_[i] = index;
assigned_constants_[i] = isolate_->factory()->undefined_value();
return;
}
}
names_.Add(name);
assigned_arguments_.Add(index);
assigned_constants_.Add(isolate_->factory()->undefined_value());
}
void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
EnsureAllocation();
names_->Add(name);
assigned_arguments_->Add(-1);
assigned_constants_->Add(value);
EnsureInitialized();
for (int i = 0; i < names_.length(); ++i) {
if (name->Equals(*names_[i])) {
assigned_arguments_[i] = -1;
assigned_constants_[i] = value;
return;
}
}
names_.Add(name);
assigned_arguments_.Add(-1);
assigned_constants_.Add(value);
}
void AssignmentFromSomethingElse() {
@ -1082,22 +1100,21 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
only_simple_this_property_assignments_ = false;
}
void EnsureAllocation() {
if (names_ == NULL) {
ASSERT(assigned_arguments_ == NULL);
ASSERT(assigned_constants_ == NULL);
Zone* zone = isolate_->zone();
names_ = new(zone) ZoneStringList(4);
assigned_arguments_ = new(zone) ZoneList<int>(4);
assigned_constants_ = new(zone) ZoneObjectList(4);
void EnsureInitialized() {
if (names_.capacity() == 0) {
ASSERT(assigned_arguments_.capacity() == 0);
ASSERT(assigned_constants_.capacity() == 0);
names_.Initialize(4);
assigned_arguments_.Initialize(4);
assigned_constants_.Initialize(4);
}
}
Isolate* isolate_;
bool only_simple_this_property_assignments_;
ZoneStringList* names_;
ZoneList<int>* assigned_arguments_;
ZoneObjectList* assigned_constants_;
ZoneStringList names_;
ZoneList<int> assigned_arguments_;
ZoneObjectList assigned_constants_;
};
@ -1136,7 +1153,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
ASSERT(processor != NULL);
InitializationBlockFinder block_finder(top_scope_, target_stack_);
ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
ThisNamedPropertyAssignmentFinder this_property_assignment_finder(isolate());
bool directive_prologue = true; // Parsing directive prologue.
while (peek() != end_token) {