Index: src/ast.cc |
=================================================================== |
--- src/ast.cc (revision 5712) |
+++ src/ast.cc (working copy) |
@@ -140,6 +140,7 @@ |
ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
+ emit_store_ = true; |
key_ = key; |
value_ = value; |
Object* k = *key->handle(); |
@@ -156,6 +157,7 @@ |
ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { |
+ emit_store_ = true; |
key_ = new Literal(value->name()); |
value_ = value; |
kind_ = is_getter ? GETTER : SETTER; |
@@ -169,6 +171,78 @@ |
} |
+void ObjectLiteral::Property::set_emit_store(bool emit_store) { |
+ emit_store_ = emit_store; |
+} |
+ |
+ |
+bool ObjectLiteral::Property::emit_store() { |
+ return emit_store_; |
+} |
+ |
+ |
+bool IsEqualString(void* first, void* second) { |
+ Handle<String> h1(reinterpret_cast<String**>(first)); |
+ Handle<String> h2(reinterpret_cast<String**>(second)); |
+ return (*h1)->Equals(*h2); |
+} |
+ |
+bool IsEqualSmi(void* first, void* second) { |
+ Handle<Smi> h1(reinterpret_cast<Smi**>(first)); |
+ Handle<Smi> h2(reinterpret_cast<Smi**>(second)); |
+ return (*h1)->value() == (*h2)->value(); |
+} |
+ |
+void ObjectLiteral::CalculateEmitStore() { |
+ HashMap properties(&IsEqualString); |
+ HashMap elements(&IsEqualSmi); |
+ for (int i = this->properties()->length() - 1; i >= 0; i--) { |
+ ObjectLiteral::Property* property = this->properties()->at(i); |
+ Literal* literal = property->key(); |
+ Handle<Object> handle = literal->handle(); |
+ |
+ if (handle->IsNull()) { |
+ continue; |
+ } |
+ |
+ uint32_t hash; |
+ HashMap* table; |
+ void* key; |
+ uint32_t index; |
+ if (handle->IsSymbol()) { |
+ Handle<String> name(String::cast(*handle)); |
+ ASSERT(!name->AsArrayIndex(&index)); |
+ key = name.location(); |
+ hash = name->Hash(); |
+ table = &properties; |
+ } else if (handle->ToArrayIndex(&index)) { |
+ key = handle.location(); |
+ hash = index; |
+ table = &elements; |
+ } else { |
+ ASSERT(handle->IsNumber()); |
+ double num = handle->Number(); |
+ char arr[100]; |
+ Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
+ const char* str = DoubleToCString(num, buffer); |
+ Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); |
+ key = name.location(); |
+ hash = name->Hash(); |
+ table = &properties; |
+ } |
+ // If the key of a computed property is in the table, do not emit |
+ // a store for the property later. |
+ if (property->kind() == ObjectLiteral::Property::COMPUTED) { |
+ if (table->Lookup(literal, hash, false) != NULL) { |
+ property->set_emit_store(false); |
+ } |
+ } |
+ // Add key to the table. |
+ table->Lookup(literal, hash, true); |
+ } |
+} |
+ |
+ |
void TargetCollector::AddTarget(BreakTarget* target) { |
// Add the label to the collector, but discard duplicates. |
int length = targets_->length(); |