Vector ICs: The Oracle needs to report feedback for the object literals and the count...
authormvstanton <mvstanton@chromium.org>
Thu, 10 Sep 2015 15:02:21 +0000 (08:02 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 10 Sep 2015 15:02:39 +0000 (15:02 +0000)
The refactoring is because it's awkward and error-prone to deterimine which IC slot an
ObjectLiteralProperty uses for feedback. The fix is for each one to know it's own slot. In the
numbering pass, we allocate slots for the ObjectLiteral, then hand out those slots into the
properties.

It adds one word to the ObjectLiteralProperty expression - I'm investigating if thats a
problem.

This changes makes compiling the object literal cleaner across the three compilers. Also, the
slot allocation logic in ObjectLiteral::ComputeFeedbackRequirements() was refactoring to mimic
the style in full-codegen. This is useful since it must remain in sync with
FullCodegen::VisitObjectLiteral().

Review URL: https://codereview.chromium.org/1321993004

Cr-Commit-Position: refs/heads/master@{#30686}

17 files changed:
src/ast-numbering.cc
src/ast.cc
src/ast.h
src/compiler/ast-graph-builder.cc
src/compiler/ast-graph-builder.h
src/full-codegen/arm/full-codegen-arm.cc
src/full-codegen/arm64/full-codegen-arm64.cc
src/full-codegen/full-codegen.cc
src/full-codegen/full-codegen.h
src/full-codegen/ia32/full-codegen-ia32.cc
src/full-codegen/mips/full-codegen-mips.cc
src/full-codegen/mips64/full-codegen-mips64.cc
src/full-codegen/x64/full-codegen-x64.cc
src/hydrogen.cc
src/type-info.cc
src/type-info.h
src/typing.cc

index 9d048cd9c0a5773da6d426fa7bf70201c2c55ff7..b36e1ff7e1d0d2c4249bd9a6b96a2fc20d03b9ed 100644 (file)
@@ -463,6 +463,7 @@ void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
     VisitObjectLiteralProperty(node->properties()->at(i));
   }
   ReserveFeedbackSlots(node);
+  node->LayoutFeedbackSlots();
 }
 
 
@@ -478,6 +479,7 @@ void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
   // marked expressions, no store code will be is emitted.
   node->CalculateEmitStore(zone());
   ReserveFeedbackSlots(node);
+  node->LayoutFeedbackSlots();
 }
 
 
index 19747d8b767be294e3a819db95f7beb14a3c68b2..1b39e3190aa4021ebc6217b063dc219e9582e9d2 100644 (file)
@@ -251,6 +251,7 @@ ObjectLiteralProperty::ObjectLiteralProperty(Expression* key, Expression* value,
                                              bool is_computed_name)
     : key_(key),
       value_(value),
+      ic_slot_or_count_(FeedbackVectorICSlot::Invalid().ToInt()),
       kind_(kind),
       emit_store_(true),
       is_static_(is_static),
@@ -263,6 +264,7 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
                                              bool is_computed_name)
     : key_(key),
       value_(value),
+      ic_slot_or_count_(FeedbackVectorICSlot::Invalid().ToInt()),
       emit_store_(true),
       is_static_(is_static),
       is_computed_name_(is_computed_name) {
@@ -287,35 +289,34 @@ FeedbackVectorRequirements ClassLiteral::ComputeFeedbackRequirements(
   // This logic that computes the number of slots needed for vector store
   // ICs must mirror FullCodeGenerator::VisitClassLiteral.
   int ic_slots = 0;
+  if (NeedsProxySlot()) {
+    ic_slots++;
+  }
+
   for (int i = 0; i < properties()->length(); i++) {
     ObjectLiteral::Property* property = properties()->at(i);
+    // In case we don't end up using any slots.
+    property->set_ic_slot_count(0);
 
     Expression* value = property->value();
-    if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++;
-  }
-
-  if (scope() != NULL && class_variable_proxy()->var()->IsUnallocated()) {
-    ic_slots++;
+    if (FunctionLiteral::NeedsHomeObject(value)) {
+      property->set_ic_slot_count(1);
+      ic_slots++;
+    }
   }
 
-#ifdef DEBUG
-  // FullCodeGenerator::VisitClassLiteral verifies that it consumes slot_count_
-  // slots.
-  slot_count_ = ic_slots;
-#endif
   return FeedbackVectorRequirements(0, ic_slots);
 }
 
 
-FeedbackVectorICSlot ClassLiteral::SlotForHomeObject(Expression* value,
-                                                     int* slot_index) const {
-  if (FLAG_vector_stores && FunctionLiteral::NeedsHomeObject(value)) {
-    DCHECK(slot_index != NULL && *slot_index >= 0 && *slot_index < slot_count_);
-    FeedbackVectorICSlot slot = GetNthSlot(*slot_index);
-    *slot_index += 1;
-    return slot;
+void ClassLiteral::LayoutFeedbackSlots() {
+  int base_slot = slot_.ToInt();
+  if (NeedsProxySlot()) base_slot++;
+
+  for (int i = 0; i < properties()->length(); i++) {
+    ObjectLiteral::Property* property = properties()->at(i);
+    base_slot += property->set_base_slot(base_slot);
   }
-  return FeedbackVectorICSlot::Invalid();
 }
 
 
@@ -336,55 +337,88 @@ bool ObjectLiteral::Property::emit_store() {
 }
 
 
+void ObjectLiteral::LayoutFeedbackSlots() {
+  int base_slot = slot_.ToInt();
+  for (int i = 0; i < properties()->length(); i++) {
+    ObjectLiteral::Property* property = properties()->at(i);
+    base_slot += property->set_base_slot(base_slot);
+  }
+}
+
+
 FeedbackVectorRequirements ObjectLiteral::ComputeFeedbackRequirements(
     Isolate* isolate, const ICSlotCache* cache) {
   if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0);
 
   // This logic that computes the number of slots needed for vector store
   // ics must mirror FullCodeGenerator::VisitObjectLiteral.
-  int ic_slots = 0;
-  bool saw_computed_name = false;
-  for (int i = 0; i < properties()->length(); i++) {
-    ObjectLiteral::Property* property = properties()->at(i);
+  int property_index = 0;
+  for (; property_index < properties()->length(); property_index++) {
+    ObjectLiteral::Property* property = properties()->at(property_index);
+    // In case we don't end up using any slots.
+    property->set_ic_slot_count(0);
+
+    if (property->is_computed_name()) break;
     if (property->IsCompileTimeValue()) continue;
-    saw_computed_name |= property->is_computed_name();
 
+    Literal* key = property->key()->AsLiteral();
     Expression* value = property->value();
-    if (saw_computed_name &&
-        property->kind() != ObjectLiteral::Property::PROTOTYPE) {
-      if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++;
-    } else if (property->emit_store()) {
-      if (property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL ||
-          property->kind() == ObjectLiteral::Property::COMPUTED) {
-        Literal* key = property->key()->AsLiteral();
-        if (key->value()->IsInternalizedString()) ic_slots++;
-        if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++;
-      } else if (property->kind() == ObjectLiteral::Property::GETTER ||
-                 property->kind() == ObjectLiteral::Property::SETTER) {
-        // We might need a slot for the home object.
-        if (FunctionLiteral::NeedsHomeObject(value)) ic_slots++;
-      }
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+        UNREACHABLE();
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      // Fall through.
+      case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
+        if (key->value()->IsInternalizedString()) {
+          if (property->emit_store()) {
+            int slot_count = 1;
+            if (FunctionLiteral::NeedsHomeObject(value)) {
+              slot_count++;
+            }
+            property->set_ic_slot_count(slot_count);
+          }
+          break;
+        }
+        if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) {
+          property->set_ic_slot_count(1);
+        }
+        break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        break;
+      case ObjectLiteral::Property::GETTER:
+        if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) {
+          property->set_ic_slot_count(1);
+        }
+        break;
+      case ObjectLiteral::Property::SETTER:
+        if (property->emit_store() && FunctionLiteral::NeedsHomeObject(value)) {
+          property->set_ic_slot_count(1);
+        }
+        break;
     }
   }
 
-#ifdef DEBUG
-  // FullCodeGenerator::VisitObjectLiteral verifies that it consumes slot_count_
-  // slots.
-  slot_count_ = ic_slots;
-#endif
-  return FeedbackVectorRequirements(0, ic_slots);
-}
+  for (; property_index < properties()->length(); property_index++) {
+    ObjectLiteral::Property* property = properties()->at(property_index);
 
+    Expression* value = property->value();
+    if (property->kind() != ObjectLiteral::Property::PROTOTYPE) {
+      if (FunctionLiteral::NeedsHomeObject(value)) {
+        property->set_ic_slot_count(1);
+      }
+    }
+  }
 
-FeedbackVectorICSlot ObjectLiteral::SlotForHomeObject(Expression* value,
-                                                      int* slot_index) const {
-  if (FLAG_vector_stores && FunctionLiteral::NeedsHomeObject(value)) {
-    DCHECK(slot_index != NULL && *slot_index >= 0 && *slot_index < slot_count_);
-    FeedbackVectorICSlot slot = GetNthSlot(*slot_index);
-    *slot_index += 1;
-    return slot;
+  // How many slots did we allocate?
+  int ic_slots = 0;
+  for (int i = 0; i < properties()->length(); i++) {
+    ObjectLiteral::Property* property = properties()->at(i);
+    ic_slots += property->ic_slot_count();
   }
-  return FeedbackVectorICSlot::Invalid();
+
+  return FeedbackVectorRequirements(0, ic_slots);
 }
 
 
index 9ba05653dacddd9aaee50933385e7e9fcbc0f7a7..0486c3ee3f4f19a17f021857f6f2344ce27a447c 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1399,7 +1399,38 @@ class ObjectLiteralProperty final : public ZoneObject {
   bool is_static() const { return is_static_; }
   bool is_computed_name() const { return is_computed_name_; }
 
+  FeedbackVectorICSlot GetSlot(int offset = 0) const {
+    if (ic_slot_or_count_ == FeedbackVectorICSlot::Invalid().ToInt()) {
+      return FeedbackVectorICSlot::Invalid();
+    }
+    return FeedbackVectorICSlot(ic_slot_or_count_ + offset);
+  }
+
+  int ic_slot_count() const {
+    if (ic_slot_or_count_ == FeedbackVectorICSlot::Invalid().ToInt()) {
+      return 0;
+    }
+    return ic_slot_or_count_;
+  }
+
   void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
+  void set_ic_slot_count(int count) {
+    // Should only be called once.
+    if (count == 0) {
+      ic_slot_or_count_ = FeedbackVectorICSlot::Invalid().ToInt();
+    } else {
+      ic_slot_or_count_ = count;
+    }
+  }
+
+  int set_base_slot(int slot) {
+    if (ic_slot_count() > 0) {
+      int count = ic_slot_count();
+      ic_slot_or_count_ = slot;
+      return count;
+    }
+    return 0;
+  }
 
  protected:
   friend class AstNodeFactory;
@@ -1413,6 +1444,7 @@ class ObjectLiteralProperty final : public ZoneObject {
  private:
   Expression* key_;
   Expression* value_;
+  int ic_slot_or_count_;
   Kind kind_;
   bool emit_store_;
   bool is_static_;
@@ -1477,8 +1509,8 @@ class ObjectLiteral final : public MaterializedLiteral {
 
   struct Accessors: public ZoneObject {
     Accessors() : getter(NULL), setter(NULL) {}
-    Expression* getter;
-    Expression* setter;
+    ObjectLiteralProperty* getter;
+    ObjectLiteralProperty* setter;
   };
 
   BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
@@ -1499,18 +1531,10 @@ class ObjectLiteral final : public MaterializedLiteral {
     slot_ = slot;
   }
   Code::Kind FeedbackICSlotKind(int index) override { return Code::STORE_IC; }
-  FeedbackVectorICSlot GetNthSlot(int n) const {
-    return FeedbackVectorICSlot(slot_.ToInt() + n);
-  }
 
-  // If value needs a home object, returns a valid feedback vector ic slot
-  // given by slot_index, and increments slot_index.
-  FeedbackVectorICSlot SlotForHomeObject(Expression* value,
-                                         int* slot_index) const;
-
-#ifdef DEBUG
-  int slot_count() const { return slot_count_; }
-#endif
+  // After feedback slots were assigned, propagate information to the properties
+  // which need it.
+  void LayoutFeedbackSlots();
 
  protected:
   ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
@@ -1523,9 +1547,6 @@ class ObjectLiteral final : public MaterializedLiteral {
         has_elements_(false),
         may_store_doubles_(false),
         has_function_(has_function),
-#ifdef DEBUG
-        slot_count_(0),
-#endif
         slot_(FeedbackVectorICSlot::Invalid()) {
   }
   static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
@@ -1539,11 +1560,6 @@ class ObjectLiteral final : public MaterializedLiteral {
   bool has_elements_;
   bool may_store_doubles_;
   bool has_function_;
-#ifdef DEBUG
-  // slot_count_ helps validate that the logic to allocate ic slots and the
-  // logic to use them are in sync.
-  int slot_count_;
-#endif
   FeedbackVectorICSlot slot_;
 };
 
@@ -2714,18 +2730,17 @@ class ClassLiteral final : public Expression {
     slot_ = slot;
   }
   Code::Kind FeedbackICSlotKind(int index) override { return Code::STORE_IC; }
-  FeedbackVectorICSlot GetNthSlot(int n) const {
-    return FeedbackVectorICSlot(slot_.ToInt() + n);
+
+  bool NeedsProxySlot() const {
+    return FLAG_vector_stores && scope() != NULL &&
+           class_variable_proxy()->var()->IsUnallocated();
   }
 
-  // If value needs a home object, returns a valid feedback vector ic slot
-  // given by slot_index, and increments slot_index.
-  FeedbackVectorICSlot SlotForHomeObject(Expression* value,
-                                         int* slot_index) const;
+  FeedbackVectorICSlot ProxySlot() const { return slot_; }
 
-#ifdef DEBUG
-  int slot_count() const { return slot_count_; }
-#endif
+  // After feedback slots were assigned, propagate information to the properties
+  // which need it.
+  void LayoutFeedbackSlots();
 
  protected:
   ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope,
@@ -2740,9 +2755,6 @@ class ClassLiteral final : public Expression {
         constructor_(constructor),
         properties_(properties),
         end_position_(end_position),
-#ifdef DEBUG
-        slot_count_(0),
-#endif
         slot_(FeedbackVectorICSlot::Invalid()) {
   }
 
@@ -2758,11 +2770,6 @@ class ClassLiteral final : public Expression {
   FunctionLiteral* constructor_;
   ZoneList<Property*>* properties_;
   int end_position_;
-#ifdef DEBUG
-  // slot_count_ helps validate that the logic to allocate ic slots and the
-  // logic to use them are in sync.
-  int slot_count_;
-#endif
   FeedbackVectorICSlot slot_;
 };
 
index 7b9e3662afaaf3ce5c2286995e28482e3aa1cfbf..52d4a470f6f52955c6c916b3b973017e17a5b05b 100644 (file)
@@ -1570,7 +1570,6 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
   environment()->Push(proto);
 
   // Create nodes to store method values into the literal.
-  int store_slot_index = 0;
   for (int i = 0; i < expr->properties()->length(); i++) {
     ObjectLiteral::Property* property = expr->properties()->at(i);
     environment()->Push(property->is_static() ? literal : proto);
@@ -1593,9 +1592,8 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
     Node* value = environment()->Pop();
     Node* key = environment()->Pop();
     Node* receiver = environment()->Pop();
-    VectorSlotPair feedback = CreateVectorSlotPair(
-        expr->SlotForHomeObject(property->value(), &store_slot_index));
-    BuildSetHomeObject(value, receiver, property->value(), feedback);
+
+    BuildSetHomeObject(value, receiver, property);
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
@@ -1638,10 +1636,9 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
     DCHECK_NOT_NULL(expr->class_variable_proxy());
     Variable* var = expr->class_variable_proxy()->var();
     FrameStateBeforeAndAfter states(this, BailoutId::None());
-    VectorSlotPair feedback =
-        CreateVectorSlotPair(FLAG_vector_stores && var->IsUnallocated()
-                                 ? expr->GetNthSlot(store_slot_index++)
-                                 : FeedbackVectorICSlot::Invalid());
+    VectorSlotPair feedback = CreateVectorSlotPair(
+        expr->NeedsProxySlot() ? expr->ProxySlot()
+                               : FeedbackVectorICSlot::Invalid());
     BuildVariableAssignment(var, literal, Token::INIT_CONST, feedback,
                             BailoutId::None(), states);
   }
@@ -1720,7 +1717,6 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
 
   // Create nodes to store computed values into the literal.
   int property_index = 0;
-  int store_slot_index = 0;
   AccessorTable accessor_table(zone());
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
@@ -1744,17 +1740,12 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
             Node* value = environment()->Pop();
             Handle<Name> name = key->AsPropertyName();
             VectorSlotPair feedback =
-                FLAG_vector_stores
-                    ? CreateVectorSlotPair(expr->GetNthSlot(store_slot_index++))
-                    : VectorSlotPair();
+                CreateVectorSlotPair(property->GetSlot(0));
             Node* store = BuildNamedStore(literal, name, value, feedback,
                                           TypeFeedbackId::None());
             states.AddToNode(store, key->id(),
                              OutputFrameStateCombine::Ignore());
-            VectorSlotPair home_feedback = CreateVectorSlotPair(
-                expr->SlotForHomeObject(property->value(), &store_slot_index));
-            BuildSetHomeObject(value, literal, property->value(),
-                               home_feedback);
+            BuildSetHomeObject(value, literal, property, 1);
           } else {
             VisitForEffect(property->value());
           }
@@ -1773,9 +1764,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
           Node* set_property = NewNode(op, receiver, key, value, language);
           // SetProperty should not lazy deopt on an object literal.
           PrepareFrameState(set_property, BailoutId::None());
-          VectorSlotPair home_feedback = CreateVectorSlotPair(
-              expr->SlotForHomeObject(property->value(), &store_slot_index));
-          BuildSetHomeObject(value, receiver, property->value(), home_feedback);
+          BuildSetHomeObject(value, receiver, property);
         }
         break;
       }
@@ -1794,12 +1783,12 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
       }
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = property->value();
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = property->value();
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1810,16 +1799,8 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
   for (AccessorTable::Iterator it = accessor_table.begin();
        it != accessor_table.end(); ++it) {
     VisitForValue(it->first);
-    VisitForValueOrNull(it->second->getter);
-    VectorSlotPair feedback_getter = CreateVectorSlotPair(
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
-    BuildSetHomeObject(environment()->Top(), literal, it->second->getter,
-                       feedback_getter);
-    VisitForValueOrNull(it->second->setter);
-    VectorSlotPair feedback_setter = CreateVectorSlotPair(
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
-    BuildSetHomeObject(environment()->Top(), literal, it->second->setter,
-                       feedback_setter);
+    VisitObjectLiteralAccessor(literal, it->second->getter);
+    VisitObjectLiteralAccessor(literal, it->second->setter);
     Node* setter = environment()->Pop();
     Node* getter = environment()->Pop();
     Node* name = environment()->Pop();
@@ -1864,9 +1845,7 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     Node* value = environment()->Pop();
     Node* key = environment()->Pop();
     Node* receiver = environment()->Pop();
-    VectorSlotPair feedback = CreateVectorSlotPair(
-        expr->SlotForHomeObject(property->value(), &store_slot_index));
-    BuildSetHomeObject(value, receiver, property->value(), feedback);
+    BuildSetHomeObject(value, receiver, property);
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
       case ObjectLiteral::Property::COMPUTED:
@@ -1907,14 +1886,21 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     NewNode(op, literal);
   }
 
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
-
   ast_context()->ProduceValue(environment()->Pop());
 }
 
 
+void AstGraphBuilder::VisitObjectLiteralAccessor(
+    Node* home_object, ObjectLiteralProperty* property) {
+  if (property == nullptr) {
+    VisitForValueOrNull(nullptr);
+  } else {
+    VisitForValue(property->value());
+    BuildSetHomeObject(environment()->Top(), home_object, property);
+  }
+}
+
+
 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
   Node* closure = GetFunctionClosure();
 
@@ -3808,11 +3794,14 @@ Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) {
 
 
 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
-                                          Expression* expr,
-                                          const VectorSlotPair& feedback) {
+                                          ObjectLiteralProperty* property,
+                                          int slot_number) {
+  Expression* expr = property->value();
   if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
   Handle<Name> name = isolate()->factory()->home_object_symbol();
   FrameStateBeforeAndAfter states(this, BailoutId::None());
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(property->GetSlot(slot_number));
   Node* store = BuildNamedStore(value, name, home_object, feedback,
                                 TypeFeedbackId::None());
   states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
index f5ad2620fc0c53c25762fc725ff4bb68c1069256..8b90f072a02a7249aa8fc2f200f85406ba6ffdaf 100644 (file)
@@ -326,8 +326,9 @@ class AstGraphBuilder : public AstVisitor {
 
   // Builder for adding the [[HomeObject]] to a value if the value came from a
   // function literal and needs a home object. Do nothing otherwise.
-  Node* BuildSetHomeObject(Node* value, Node* home_object, Expression* expr,
-                           const VectorSlotPair& feedback);
+  Node* BuildSetHomeObject(Node* value, Node* home_object,
+                           ObjectLiteralProperty* property,
+                           int slot_number = 0);
 
   // Builders for error reporting at runtime.
   Node* BuildThrowError(Node* exception, BailoutId bailout_id);
@@ -402,6 +403,10 @@ class AstGraphBuilder : public AstVisitor {
                             const VectorSlotPair& feedback,
                             BailoutId bailout_id);
 
+  // Dispatched from VisitObjectLiteral.
+  void VisitObjectLiteralAccessor(Node* home_object,
+                                  ObjectLiteralProperty* property);
+
   // Dispatched from VisitClassLiteral.
   void VisitClassLiteralContents(ClassLiteral* expr);
 
index b67c63de7a67b3f803d313ee97d62ea7d687e89b..a29ff82e166506cb7cb87c56544f2df18fb9c55c 100644 (file)
@@ -1250,18 +1250,29 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
-    __ mov(StoreDescriptor::NameRegister(),
-           Operand(isolate()->factory()->home_object_symbol()));
-    __ ldr(StoreDescriptor::ValueRegister(),
-           MemOperand(sp, offset * kPointerSize));
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+  __ mov(StoreDescriptor::NameRegister(),
+         Operand(isolate()->factory()->home_object_symbol()));
+  __ ldr(StoreDescriptor::ValueRegister(),
+         MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ Move(StoreDescriptor::ReceiverRegister(), r0);
+  __ mov(StoreDescriptor::NameRegister(),
+         Operand(isolate()->factory()->home_object_symbol()));
+  __ ldr(StoreDescriptor::ValueRegister(),
+         MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1531,12 +1542,19 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ LoadRoot(r1, Heap::kNullValueRootIndex);
     __ push(r1);
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1566,10 +1584,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1597,7 +1611,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
             __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
@@ -1605,14 +1619,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
 
             if (NeedsHomeObject(value)) {
-              __ Move(StoreDescriptor::ReceiverRegister(), r0);
-              __ mov(StoreDescriptor::NameRegister(),
-                     Operand(isolate()->factory()->home_object_symbol()));
-              __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp));
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1625,8 +1632,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ mov(r0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes
           __ push(r0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1645,12 +1653,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1665,13 +1673,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     __ push(r0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->getter, 2,
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
     EmitAccessor(it->second->setter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->setter, 3,
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
     __ mov(r0, Operand(Smi::FromInt(NONE)));
     __ push(r0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1706,8 +1708,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1753,10 +1756,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(r0);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2434,8 +2433,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in r0.
   DCHECK(lit != NULL);
   __ push(r0);
@@ -2469,8 +2467,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
index 63cbf2cabcd65a558b2dfc831c8bdecf4176afda..e460ac3220523de43e0792d03a4a7646a548bd2a 100644 (file)
@@ -1246,17 +1246,27 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ Peek(StoreDescriptor::ReceiverRegister(), 0);
-    __ Mov(StoreDescriptor::NameRegister(),
-           Operand(isolate()->factory()->home_object_symbol()));
-    __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ Peek(StoreDescriptor::ReceiverRegister(), 0);
+  __ Mov(StoreDescriptor::NameRegister(),
+         Operand(isolate()->factory()->home_object_symbol()));
+  __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ Move(StoreDescriptor::ReceiverRegister(), x0);
+  __ Mov(StoreDescriptor::NameRegister(),
+         Operand(isolate()->factory()->home_object_symbol()));
+  __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1518,12 +1528,19 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ LoadRoot(x10, Heap::kNullValueRootIndex);
     __ Push(x10);
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1553,10 +1570,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1584,7 +1597,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ Mov(StoreDescriptor::NameRegister(), Operand(key->value()));
             __ Peek(StoreDescriptor::ReceiverRegister(), 0);
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
@@ -1592,14 +1605,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
 
             if (NeedsHomeObject(value)) {
-              __ Mov(StoreDescriptor::ReceiverRegister(), x0);
-              __ Mov(StoreDescriptor::NameRegister(),
-                     Operand(isolate()->factory()->home_object_symbol()));
-              __ Peek(StoreDescriptor::ValueRegister(), 0);
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1611,8 +1617,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ Mov(x0, Smi::FromInt(SLOPPY));  // Language mode
           __ Push(x0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1630,12 +1637,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         break;
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1650,13 +1657,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
       __ Push(x10);
       VisitForStackValue(it->first);
       EmitAccessor(it->second->getter);
-      EmitSetHomeObjectIfNeeded(
-          it->second->getter, 2,
-          expr->SlotForHomeObject(it->second->getter, &store_slot_index));
       EmitAccessor(it->second->setter);
-      EmitSetHomeObjectIfNeeded(
-          it->second->setter, 3,
-          expr->SlotForHomeObject(it->second->setter, &store_slot_index));
       __ Mov(x10, Smi::FromInt(NONE));
       __ Push(x10);
       __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1691,8 +1692,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1738,10 +1740,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(x0);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2145,8 +2143,7 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in x0.
   DCHECK(lit != NULL);
   __ push(x0);
@@ -2180,8 +2177,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
index 5ef9d0a0b935eb2f163cb43f4bd1785010135320..e889185571d4e8e38a997bbb05d2f401f7f60855 100644 (file)
@@ -1300,23 +1300,13 @@ void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
     __ CallRuntime(Runtime::kDefineClass, 5);
     PrepareForBailoutForId(lit->CreateLiteralId(), TOS_REG);
 
-    int store_slot_index = 0;
-    EmitClassDefineProperties(lit, &store_slot_index);
+    EmitClassDefineProperties(lit);
 
     if (lit->scope() != NULL) {
       DCHECK_NOT_NULL(lit->class_variable_proxy());
-      FeedbackVectorICSlot slot =
-          FLAG_vector_stores &&
-                  lit->class_variable_proxy()->var()->IsUnallocated()
-              ? lit->GetNthSlot(store_slot_index++)
-              : FeedbackVectorICSlot::Invalid();
       EmitVariableAssignment(lit->class_variable_proxy()->var(),
-                             Token::INIT_CONST, slot);
+                             Token::INIT_CONST, lit->ProxySlot());
     }
-
-    // Verify that compilation exactly consumed the number of store ic slots
-    // that the ClassLiteral node had to offer.
-    DCHECK(!FLAG_vector_stores || store_slot_index == lit->slot_count());
   }
 
   context()->Plug(result_register());
index bc78fda68da5efc0738c8a4510edaffc19ebe847..da629d9a200a7b3e61d83b1f6250687a9d7b2712 100644 (file)
@@ -552,7 +552,7 @@ class FullCodeGenerator: public AstVisitor {
   void EmitVariableLoad(VariableProxy* proxy,
                         TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
 
-  void EmitAccessor(Expression* expression);
+  void EmitAccessor(ObjectLiteralProperty* property);
 
   bool NeedsHoleCheckForLoad(VariableProxy* proxy);
 
@@ -586,7 +586,7 @@ class FullCodeGenerator: public AstVisitor {
   // Adds the properties to the class (function) object and to its prototype.
   // Expects the class (function) in the accumulator. The class (function) is
   // in the accumulator after installing all the properties.
-  void EmitClassDefineProperties(ClassLiteral* lit, int* used_store_slots);
+  void EmitClassDefineProperties(ClassLiteral* lit);
 
   // Pushes the property key as a Name on the stack.
   void EmitPropertyKey(ObjectLiteralProperty* property, BailoutId bailout_id);
@@ -640,9 +640,11 @@ class FullCodeGenerator: public AstVisitor {
   // Adds the [[HomeObject]] to |initializer| if it is a FunctionLiteral.
   // The value of the initializer is expected to be at the top of the stack.
   // |offset| is the offset in the stack where the home object can be found.
-  void EmitSetHomeObjectIfNeeded(
-      Expression* initializer, int offset,
-      FeedbackVectorICSlot slot = FeedbackVectorICSlot::Invalid());
+  void EmitSetHomeObject(Expression* initializer, int offset,
+                         FeedbackVectorICSlot slot);
+
+  void EmitSetHomeObjectAccumulator(Expression* initializer, int offset,
+                                    FeedbackVectorICSlot slot);
 
   void EmitLoadSuperConstructor(SuperCallReference* super_call_ref);
 
index a7715707f19eaab5f97daf90838152de251b556c..42c12b3773fb90b5b53b03b0908bec3f7f9aaa0f 100644 (file)
@@ -1180,18 +1180,27 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
-    __ mov(StoreDescriptor::NameRegister(),
-           Immediate(isolate()->factory()->home_object_symbol()));
-    __ mov(StoreDescriptor::ValueRegister(),
-           Operand(esp, offset * kPointerSize));
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
+  __ mov(StoreDescriptor::NameRegister(),
+         Immediate(isolate()->factory()->home_object_symbol()));
+  __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ mov(StoreDescriptor::ReceiverRegister(), eax);
+  __ mov(StoreDescriptor::NameRegister(),
+         Immediate(isolate()->factory()->home_object_symbol()));
+  __ mov(StoreDescriptor::ValueRegister(), Operand(esp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1463,11 +1472,18 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ push(Immediate(isolate()->factory()->null_value()));
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1503,10 +1519,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1534,22 +1546,14 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ mov(StoreDescriptor::NameRegister(), Immediate(key->value()));
             __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
             }
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
-
             if (NeedsHomeObject(value)) {
-              __ mov(StoreDescriptor::ReceiverRegister(), eax);
-              __ mov(StoreDescriptor::NameRegister(),
-                     Immediate(isolate()->factory()->home_object_symbol()));
-              __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0));
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1560,8 +1564,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ push(Immediate(Smi::FromInt(SLOPPY)));  // Language mode
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1576,12 +1581,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         break;
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1594,15 +1599,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
        ++it) {
     __ push(Operand(esp, 0));  // Duplicate receiver.
     VisitForStackValue(it->first);
-    EmitAccessor(it->second->getter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->getter, 2,
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
 
+    EmitAccessor(it->second->getter);
     EmitAccessor(it->second->setter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->setter, 3,
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
 
     __ push(Immediate(Smi::FromInt(NONE)));
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1636,8 +1635,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1679,10 +1679,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(eax);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2353,8 +2349,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in eax.
   DCHECK(lit != NULL);
   __ push(eax);
@@ -2386,8 +2381,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
index 9e72de905d1136921f25b9ce6fa7bab9f3de031c..35747a6087be9657c3e94e7a6759798c99d69198 100644 (file)
@@ -1249,18 +1249,29 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
-    __ li(StoreDescriptor::NameRegister(),
-          Operand(isolate()->factory()->home_object_symbol()));
-    __ lw(StoreDescriptor::ValueRegister(),
-          MemOperand(sp, offset * kPointerSize));
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+  __ li(StoreDescriptor::NameRegister(),
+        Operand(isolate()->factory()->home_object_symbol()));
+  __ lw(StoreDescriptor::ValueRegister(),
+        MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ Move(StoreDescriptor::ReceiverRegister(), v0);
+  __ li(StoreDescriptor::NameRegister(),
+        Operand(isolate()->factory()->home_object_symbol()));
+  __ lw(StoreDescriptor::ValueRegister(),
+        MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1530,12 +1541,19 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ LoadRoot(a1, Heap::kNullValueRootIndex);
     __ push(a1);
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1564,10 +1582,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1596,7 +1610,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
             __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
@@ -1604,14 +1618,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
 
             if (NeedsHomeObject(value)) {
-              __ Move(StoreDescriptor::ReceiverRegister(), v0);
-              __ li(StoreDescriptor::NameRegister(),
-                    Operand(isolate()->factory()->home_object_symbol()));
-              __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp));
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1624,8 +1631,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ li(a0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes.
           __ push(a0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1643,12 +1651,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         break;
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1663,13 +1671,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     __ push(a0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->getter, 2,
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
     EmitAccessor(it->second->setter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->setter, 3,
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
     __ li(a0, Operand(Smi::FromInt(NONE)));
     __ push(a0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1704,8 +1706,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1751,10 +1754,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(v0);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2426,8 +2425,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in v0.
   DCHECK(lit != NULL);
   __ push(v0);
@@ -2461,8 +2459,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
@@ -3164,7 +3163,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
 
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
-  // ignored.
+  // ignored.g
   DCHECK(!expr->expression()->IsSuperPropertyReference());
   VisitForStackValue(expr->expression());
 
index 468cce1d2c94397b767756c9eed8279d9a5e5c00..fa35b5f08b56fe6e5b5c149330278cb047fbb081 100644 (file)
@@ -1247,18 +1247,29 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
-    __ li(StoreDescriptor::NameRegister(),
-          Operand(isolate()->factory()->home_object_symbol()));
-    __ ld(StoreDescriptor::ValueRegister(),
-          MemOperand(sp, offset * kPointerSize));
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+  __ li(StoreDescriptor::NameRegister(),
+        Operand(isolate()->factory()->home_object_symbol()));
+  __ ld(StoreDescriptor::ValueRegister(),
+        MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ Move(StoreDescriptor::ReceiverRegister(), v0);
+  __ li(StoreDescriptor::NameRegister(),
+        Operand(isolate()->factory()->home_object_symbol()));
+  __ ld(StoreDescriptor::ValueRegister(),
+        MemOperand(sp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1528,12 +1539,19 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ LoadRoot(a1, Heap::kNullValueRootIndex);
     __ push(a1);
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1562,10 +1580,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1594,7 +1608,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
             __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
@@ -1602,14 +1616,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
 
             if (NeedsHomeObject(value)) {
-              __ Move(StoreDescriptor::ReceiverRegister(), v0);
-              __ li(StoreDescriptor::NameRegister(),
-                    Operand(isolate()->factory()->home_object_symbol()));
-              __ ld(StoreDescriptor::ValueRegister(), MemOperand(sp));
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1622,8 +1629,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ li(a0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes.
           __ push(a0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1641,12 +1649,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         break;
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1661,13 +1669,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     __ push(a0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->getter, 2,
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
     EmitAccessor(it->second->setter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->setter, 3,
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
     __ li(a0, Operand(Smi::FromInt(NONE)));
     __ push(a0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1702,8 +1704,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1749,10 +1752,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(v0);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2425,8 +2424,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in v0.
   DCHECK(lit != NULL);
   __ push(v0);
@@ -2460,8 +2458,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
index f9af3c7cb5725671178c7e79d00a772ccbed0d04..3876eb39f8ef1aa16a98f5db3511cef08d1546ad 100644 (file)
@@ -1208,18 +1208,29 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
 }
 
 
-void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
-                                                  int offset,
-                                                  FeedbackVectorICSlot slot) {
-  if (NeedsHomeObject(initializer)) {
-    __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
-    __ Move(StoreDescriptor::NameRegister(),
-            isolate()->factory()->home_object_symbol());
-    __ movp(StoreDescriptor::ValueRegister(),
-            Operand(rsp, offset * kPointerSize));
-    if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
-    CallStoreIC();
-  }
+void FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
+                                          FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
+  __ Move(StoreDescriptor::NameRegister(),
+          isolate()->factory()->home_object_symbol());
+  __ movp(StoreDescriptor::ValueRegister(),
+          Operand(rsp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
+}
+
+
+void FullCodeGenerator::EmitSetHomeObjectAccumulator(
+    Expression* initializer, int offset, FeedbackVectorICSlot slot) {
+  DCHECK(NeedsHomeObject(initializer));
+  __ movp(StoreDescriptor::ReceiverRegister(), rax);
+  __ Move(StoreDescriptor::NameRegister(),
+          isolate()->factory()->home_object_symbol());
+  __ movp(StoreDescriptor::ValueRegister(),
+          Operand(rsp, offset * kPointerSize));
+  if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
+  CallStoreIC();
 }
 
 
@@ -1492,11 +1503,18 @@ void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
 }
 
 
-void FullCodeGenerator::EmitAccessor(Expression* expression) {
+void FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
+  Expression* expression = (property == NULL) ? NULL : property->value();
   if (expression == NULL) {
     __ PushRoot(Heap::kNullValueRootIndex);
   } else {
     VisitForStackValue(expression);
+    if (NeedsHomeObject(expression)) {
+      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
+             property->kind() == ObjectLiteral::Property::SETTER);
+      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
+      EmitSetHomeObject(expression, offset, property->GetSlot());
+    }
   }
 }
 
@@ -1530,10 +1548,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
 
   AccessorTable accessor_table(zone());
   int property_index = 0;
-  // store_slot_index points to the vector IC slot for the next store IC used.
-  // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots
-  // and must be updated if the number of store ICs emitted here changes.
-  int store_slot_index = 0;
   for (; property_index < expr->properties()->length(); property_index++) {
     ObjectLiteral::Property* property = expr->properties()->at(property_index);
     if (property->is_computed_name()) break;
@@ -1561,7 +1575,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             __ Move(StoreDescriptor::NameRegister(), key->value());
             __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
             if (FLAG_vector_stores) {
-              EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
+              EmitLoadStoreICSlot(property->GetSlot(0));
               CallStoreIC();
             } else {
               CallStoreIC(key->LiteralFeedbackId());
@@ -1569,14 +1583,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
 
             if (NeedsHomeObject(value)) {
-              __ movp(StoreDescriptor::ReceiverRegister(), rax);
-              __ Move(StoreDescriptor::NameRegister(),
-                      isolate()->factory()->home_object_symbol());
-              __ movp(StoreDescriptor::ValueRegister(), Operand(rsp, 0));
-              if (FLAG_vector_stores) {
-                EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
-              }
-              CallStoreIC();
+              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
             }
           } else {
             VisitForEffect(value);
@@ -1587,8 +1594,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          EmitSetHomeObjectIfNeeded(
-              value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+          if (NeedsHomeObject(value)) {
+            EmitSetHomeObject(value, 2, property->GetSlot());
+          }
           __ Push(Smi::FromInt(SLOPPY));  // Language mode
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1603,12 +1611,12 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
         break;
       case ObjectLiteral::Property::GETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->getter = value;
+          accessor_table.lookup(key)->second->getter = property;
         }
         break;
       case ObjectLiteral::Property::SETTER:
         if (property->emit_store()) {
-          accessor_table.lookup(key)->second->setter = value;
+          accessor_table.lookup(key)->second->setter = property;
         }
         break;
     }
@@ -1622,13 +1630,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     __ Push(Operand(rsp, 0));  // Duplicate receiver.
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->getter, 2,
-        expr->SlotForHomeObject(it->second->getter, &store_slot_index));
     EmitAccessor(it->second->setter);
-    EmitSetHomeObjectIfNeeded(
-        it->second->setter, 3,
-        expr->SlotForHomeObject(it->second->setter, &store_slot_index));
     __ Push(Smi::FromInt(NONE));
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
   }
@@ -1661,8 +1663,9 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
     } else {
       EmitPropertyKey(property, expr->GetIdForProperty(property_index));
       VisitForStackValue(value);
-      EmitSetHomeObjectIfNeeded(
-          value, 2, expr->SlotForHomeObject(value, &store_slot_index));
+      if (NeedsHomeObject(value)) {
+        EmitSetHomeObject(value, 2, property->GetSlot());
+      }
 
       switch (property->kind()) {
         case ObjectLiteral::Property::CONSTANT:
@@ -1704,10 +1707,6 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
   } else {
     context()->Plug(rax);
   }
-
-  // Verify that compilation exactly consumed the number of store ic slots that
-  // the ObjectLiteral node had to offer.
-  DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count());
 }
 
 
@@ -2377,8 +2376,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
 }
 
 
-void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
-                                                  int* used_store_slots) {
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
   // Constructor is in rax.
   DCHECK(lit != NULL);
   __ Push(rax);
@@ -2410,8 +2408,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit,
     }
 
     VisitForStackValue(value);
-    EmitSetHomeObjectIfNeeded(value, 2,
-                              lit->SlotForHomeObject(value, used_store_slots));
+    if (NeedsHomeObject(value)) {
+      EmitSetHomeObject(value, 2, property->GetSlot());
+    }
 
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
index 4152312338d91b158c578515f1bb490ec64d0036..79a9d5e35b3c6742fb7ef622ad77c2730ba41c5e 100644 (file)
@@ -5894,7 +5894,6 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
   // The object is expected in the bailout environment during computation
   // of the property values and is the value of the entire expression.
   Push(literal);
-  int store_slot_index = 0;
   for (int i = 0; i < expr->properties()->length(); i++) {
     ObjectLiteral::Property* property = expr->properties()->at(i);
     if (property->is_computed_name()) return Bailout(kComputedPropertyName);
@@ -5918,7 +5917,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
             Handle<Map> map = property->GetReceiverType();
             Handle<String> name = key->AsPropertyName();
             HValue* store;
-            FeedbackVectorICSlot slot = expr->GetNthSlot(store_slot_index++);
+            FeedbackVectorICSlot slot = property->GetSlot();
             if (map.is_null()) {
               // If we don't know the monomorphic type, do a generic store.
               CHECK_ALIVE(store = BuildNamedGeneric(STORE, NULL, slot, literal,
@@ -5946,8 +5945,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
             if (FunctionLiteral::NeedsHomeObject(property->value())) {
               Handle<Symbol> sym = isolate()->factory()->home_object_symbol();
               HInstruction* store_home = BuildNamedGeneric(
-                  STORE, NULL, expr->GetNthSlot(store_slot_index++), value, sym,
-                  literal);
+                  STORE, NULL, property->GetSlot(1), value, sym, literal);
               AddInstruction(store_home);
               DCHECK(store_home->HasObservableSideEffects());
               Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE);
@@ -5966,9 +5964,6 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
     }
   }
 
-  // Crankshaft may not consume all the slots because it doesn't emit accessors.
-  DCHECK(!FLAG_vector_stores || store_slot_index <= expr->slot_count());
-
   if (expr->has_function()) {
     // Return the result of the transformation to fast properties
     // instead of the original since this operation changes the map
index 317b4e38896b13ca9dc43b8d91a93671e199ed4c..f6ad3529230441d25b657b8b42d9d5c0e1171651 100644 (file)
@@ -198,7 +198,8 @@ void TypeFeedbackOracle::GetStoreModeAndKeyType(
 void TypeFeedbackOracle::GetStoreModeAndKeyType(
     FeedbackVectorICSlot slot, KeyedAccessStoreMode* store_mode,
     IcCheckType* key_type) {
-  if (!slot.IsInvalid()) {
+  if (!slot.IsInvalid() &&
+      feedback_vector_->GetKind(slot) == Code::KEYED_STORE_IC) {
     KeyedStoreICNexus nexus(feedback_vector_, slot);
     *store_mode = nexus.GetKeyedAccessStoreMode();
     *key_type = nexus.GetKeyType();
@@ -414,6 +415,13 @@ void TypeFeedbackOracle::CountReceiverTypes(TypeFeedbackId id,
 }
 
 
+void TypeFeedbackOracle::CountReceiverTypes(FeedbackVectorICSlot slot,
+                                            SmallMapList* receiver_types) {
+  receiver_types->Clear();
+  if (!slot.IsInvalid()) CollectReceiverTypes(slot, receiver_types);
+}
+
+
 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot,
                                               Handle<Name> name,
                                               Code::Flags flags,
@@ -462,8 +470,15 @@ void TypeFeedbackOracle::CollectReceiverTypes(TypeFeedbackId ast_id,
 
 void TypeFeedbackOracle::CollectReceiverTypes(FeedbackVectorICSlot slot,
                                               SmallMapList* types) {
-  KeyedStoreICNexus nexus(feedback_vector_, slot);
-  CollectReceiverTypes<FeedbackNexus>(&nexus, types);
+  Code::Kind kind = feedback_vector_->GetKind(slot);
+  if (kind == Code::STORE_IC) {
+    StoreICNexus nexus(feedback_vector_, slot);
+    CollectReceiverTypes<FeedbackNexus>(&nexus, types);
+  } else {
+    DCHECK(kind == Code::KEYED_STORE_IC);
+    KeyedStoreICNexus nexus(feedback_vector_, slot);
+    CollectReceiverTypes<FeedbackNexus>(&nexus, types);
+  }
 }
 
 
index 9698e4a8337f768b221ba079af0692a6cb32525e..96cc39f0079cf6f7c386af974fe4985978f8ff06 100644 (file)
@@ -66,6 +66,8 @@ class TypeFeedbackOracle: public ZoneObject {
                                     IcCheckType* key_type);
   void CountReceiverTypes(TypeFeedbackId id,
                           SmallMapList* receiver_types);
+  void CountReceiverTypes(FeedbackVectorICSlot slot,
+                          SmallMapList* receiver_types);
 
   void CollectReceiverTypes(FeedbackVectorICSlot slot, SmallMapList* types);
   void CollectReceiverTypes(TypeFeedbackId id,
index fb758828b076524a47c6be702050437507d4be95..db5ca61a8e71b217dcbb8bce2d2894def51b20bd 100644 (file)
@@ -396,8 +396,13 @@ void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
           prop->emit_store()) {
         // Record type feed back for the property.
         TypeFeedbackId id = prop->key()->AsLiteral()->LiteralFeedbackId();
+        FeedbackVectorICSlot slot = prop->GetSlot();
         SmallMapList maps;
-        oracle()->CollectReceiverTypes(id, &maps);
+        if (FLAG_vector_stores) {
+          oracle()->CollectReceiverTypes(slot, &maps);
+        } else {
+          oracle()->CollectReceiverTypes(id, &maps);
+        }
         prop->set_receiver_type(maps.length() == 1 ? maps.at(0)
                                                    : Handle<Map>::null());
       }
@@ -612,12 +617,18 @@ void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
 void AstTyper::VisitCountOperation(CountOperation* expr) {
   // Collect type feedback.
   TypeFeedbackId store_id = expr->CountStoreFeedbackId();
+  FeedbackVectorICSlot slot = expr->CountSlot();
   KeyedAccessStoreMode store_mode;
   IcCheckType key_type;
-  oracle()->GetStoreModeAndKeyType(store_id, &store_mode, &key_type);
+  if (FLAG_vector_stores) {
+    oracle()->GetStoreModeAndKeyType(slot, &store_mode, &key_type);
+    oracle()->CountReceiverTypes(slot, expr->GetReceiverTypes());
+  } else {
+    oracle()->GetStoreModeAndKeyType(store_id, &store_mode, &key_type);
+    oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes());
+  }
   expr->set_store_mode(store_mode);
   expr->set_key_type(key_type);
-  oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes());
   expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId()));
   // TODO(rossberg): merge the count type with the generic expression type.