Refactored interface of FeedbackVectorSpec and friends.
authorishell <ishell@chromium.org>
Mon, 28 Sep 2015 11:41:40 +0000 (04:41 -0700)
committerCommit bot <commit-bot@chromium.org>
Mon, 28 Sep 2015 11:41:48 +0000 (11:41 +0000)
This is a second step towards merging FeedbackVectorSlot and FeedbackVectorICSlot.

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

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

src/ast-numbering.cc
src/ast.cc
src/ast.h
src/factory.cc
src/factory.h
src/heap/heap.cc
src/type-feedback-vector.cc
src/type-feedback-vector.h
test/cctest/interpreter/test-bytecode-generator.cc
test/cctest/interpreter/test-interpreter.cc
test/cctest/test-feedback-vector.cc

index a89b5fb..cc615f6 100644 (file)
@@ -65,21 +65,8 @@ class AstNumberingVisitor final : public AstVisitor {
 
   template <typename Node>
   void ReserveFeedbackSlots(Node* node) {
-    FeedbackVectorRequirements reqs =
-        node->ComputeFeedbackRequirements(isolate(), &ic_slot_cache_);
-    if (reqs.slots() > 0) {
-      node->SetFirstFeedbackSlot(FeedbackVectorSlot(properties_.slots()));
-      properties_.increase_slots(reqs.slots());
-    }
-    if (reqs.ic_slots() > 0) {
-      int ic_slots = properties_.ic_slots();
-      node->SetFirstFeedbackICSlot(FeedbackVectorICSlot(ic_slots),
-                                   &ic_slot_cache_);
-      properties_.increase_ic_slots(reqs.ic_slots());
-      for (int i = 0; i < reqs.ic_slots(); i++) {
-        properties_.SetKind(ic_slots + i, node->FeedbackICSlotKind(i));
-      }
-    }
+    node->AssignFeedbackVectorSlots(isolate(), properties_.get_spec(),
+                                    &ic_slot_cache_);
   }
 
   BailoutReason dont_optimize_reason() const { return dont_optimize_reason_; }
index 3880f76..8c5b916 100644 (file)
@@ -98,17 +98,9 @@ void VariableProxy::BindTo(Variable* var) {
 }
 
 
-void VariableProxy::SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                                           ICSlotCache* cache) {
-  variable_feedback_slot_ = slot;
-  if (var()->IsUnallocated()) {
-    cache->Put(var(), slot);
-  }
-}
-
-
-FeedbackVectorRequirements VariableProxy::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
+void VariableProxy::AssignFeedbackVectorSlots(Isolate* isolate,
+                                              FeedbackVectorSpec* spec,
+                                              ICSlotCache* cache) {
   if (UsesVariableFeedbackSlot()) {
     // VariableProxies that point to the same Variable within a function can
     // make their loads from the same IC slot.
@@ -117,46 +109,39 @@ FeedbackVectorRequirements VariableProxy::ComputeFeedbackRequirements(
       if (entry != NULL) {
         variable_feedback_slot_ = FeedbackVectorICSlot(
             static_cast<int>(reinterpret_cast<intptr_t>(entry->value)));
-        return FeedbackVectorRequirements(0, 0);
+        return;
       }
     }
-    return FeedbackVectorRequirements(0, 1);
+    variable_feedback_slot_ = spec->AddLoadICSlot();
+    if (var()->IsUnallocated()) {
+      cache->Put(var(), variable_feedback_slot_);
+    }
   }
-  return FeedbackVectorRequirements(0, 0);
 }
 
 
-static int GetStoreICSlots(Expression* expr) {
-  int ic_slots = 0;
+static void AssignVectorSlots(Expression* expr, FeedbackVectorSpec* spec,
+                              FeedbackVectorICSlot* out_slot) {
   if (FLAG_vector_stores) {
     Property* property = expr->AsProperty();
     LhsKind assign_type = Property::GetAssignType(property);
     if ((assign_type == VARIABLE &&
          expr->AsVariableProxy()->var()->IsUnallocated()) ||
         assign_type == NAMED_PROPERTY || assign_type == KEYED_PROPERTY) {
-      ic_slots++;
+      // TODO(ishell): consider using ICSlotCache for variables here.
+      FeedbackVectorSlotKind kind = assign_type == KEYED_PROPERTY
+                                        ? FeedbackVectorSlotKind::KEYED_STORE_IC
+                                        : FeedbackVectorSlotKind::STORE_IC;
+      *out_slot = spec->AddSlot(kind);
     }
   }
-  return ic_slots;
-}
-
-
-static FeedbackVectorSlotKind GetStoreICKind(Expression* expr) {
-  LhsKind assign_type = Property::GetAssignType(expr->AsProperty());
-  return assign_type == KEYED_PROPERTY ? FeedbackVectorSlotKind::KEYED_STORE_IC
-                                       : FeedbackVectorSlotKind::STORE_IC;
-}
-
-
-FeedbackVectorRequirements ForEachStatement::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  int ic_slots = GetStoreICSlots(each());
-  return FeedbackVectorRequirements(0, ic_slots);
 }
 
 
-FeedbackVectorSlotKind ForEachStatement::FeedbackICSlotKind(int index) {
-  return GetStoreICKind(each());
+void ForEachStatement::AssignFeedbackVectorSlots(Isolate* isolate,
+                                                 FeedbackVectorSpec* spec,
+                                                 ICSlotCache* cache) {
+  AssignVectorSlots(each(), spec, &each_slot_);
 }
 
 
@@ -172,27 +157,17 @@ Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
       slot_(FeedbackVectorICSlot::Invalid()) {}
 
 
-FeedbackVectorRequirements Assignment::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  int ic_slots = GetStoreICSlots(target());
-  return FeedbackVectorRequirements(0, ic_slots);
-}
-
-
-FeedbackVectorSlotKind Assignment::FeedbackICSlotKind(int index) {
-  return GetStoreICKind(target());
-}
-
-
-FeedbackVectorRequirements CountOperation::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  int ic_slots = GetStoreICSlots(expression());
-  return FeedbackVectorRequirements(0, ic_slots);
+void Assignment::AssignFeedbackVectorSlots(Isolate* isolate,
+                                           FeedbackVectorSpec* spec,
+                                           ICSlotCache* cache) {
+  AssignVectorSlots(target(), spec, &slot_);
 }
 
 
-FeedbackVectorSlotKind CountOperation::FeedbackICSlotKind(int index) {
-  return GetStoreICKind(expression());
+void CountOperation::AssignFeedbackVectorSlots(Isolate* isolate,
+                                               FeedbackVectorSpec* spec,
+                                               ICSlotCache* cache) {
+  AssignVectorSlots(expression(), spec, &slot_);
 }
 
 
@@ -283,9 +258,10 @@ ObjectLiteralProperty::ObjectLiteralProperty(AstValueFactory* ast_value_factory,
 }
 
 
-FeedbackVectorRequirements ClassLiteral::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0);
+void ClassLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
+                                             FeedbackVectorSpec* spec,
+                                             ICSlotCache* cache) {
+  if (!FLAG_vector_stores) return;
 
   // This logic that computes the number of slots needed for vector store
   // ICs must mirror FullCodeGenerator::VisitClassLiteral.
@@ -306,7 +282,9 @@ FeedbackVectorRequirements ClassLiteral::ComputeFeedbackRequirements(
     }
   }
 
-  return FeedbackVectorRequirements(0, ic_slots);
+  if (ic_slots > 0) {
+    slot_ = spec->AddStoreICSlots(ic_slots);
+  }
 }
 
 
@@ -347,9 +325,10 @@ void ObjectLiteral::LayoutFeedbackSlots() {
 }
 
 
-FeedbackVectorRequirements ObjectLiteral::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  if (!FLAG_vector_stores) return FeedbackVectorRequirements(0, 0);
+void ObjectLiteral::AssignFeedbackVectorSlots(Isolate* isolate,
+                                              FeedbackVectorSpec* spec,
+                                              ICSlotCache* cache) {
+  if (!FLAG_vector_stores) return;
 
   // This logic that computes the number of slots needed for vector store
   // ics must mirror FullCodeGenerator::VisitObjectLiteral.
@@ -419,7 +398,9 @@ FeedbackVectorRequirements ObjectLiteral::ComputeFeedbackRequirements(
     ic_slots += property->ic_slot_count();
   }
 
-  return FeedbackVectorRequirements(0, ic_slots);
+  if (ic_slots > 0) {
+    slot_ = spec->AddStoreICSlots(ic_slots);
+  }
 }
 
 
@@ -782,11 +763,14 @@ bool Call::IsUsingCallFeedbackSlot(Isolate* isolate) const {
 }
 
 
-FeedbackVectorRequirements Call::ComputeFeedbackRequirements(
-    Isolate* isolate, const ICSlotCache* cache) {
-  int ic_slots = IsUsingCallFeedbackICSlot(isolate) ? 1 : 0;
-  int slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0;
-  return FeedbackVectorRequirements(slots, ic_slots);
+void Call::AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                     ICSlotCache* cache) {
+  if (IsUsingCallFeedbackICSlot(isolate)) {
+    ic_slot_ = spec->AddCallICSlot();
+  }
+  if (IsUsingCallFeedbackSlot(isolate)) {
+    slot_ = spec->AddStubSlot();
+  }
 }
 
 
index 7f5b85f..b7ccaf3 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -138,20 +138,6 @@ typedef ZoneList<Handle<Object>> ZoneObjectList;
   friend class AstNodeFactory;
 
 
-class FeedbackVectorRequirements {
- public:
-  FeedbackVectorRequirements(int slots, int ic_slots)
-      : slots_(slots), ic_slots_(ic_slots) {}
-
-  int slots() const { return slots_; }
-  int ic_slots() const { return ic_slots_; }
-
- private:
-  int slots_;
-  int ic_slots_;
-};
-
-
 class ICSlotCache {
  public:
   explicit ICSlotCache(Zone* zone)
@@ -192,20 +178,13 @@ class AstProperties final BASE_EMBEDDED {
   int node_count() { return node_count_; }
   void add_node_count(int count) { node_count_ += count; }
 
-  int slots() const { return spec_.slots(); }
-  void increase_slots(int count) { spec_.increase_slots(count); }
-
-  int ic_slots() const { return spec_.ic_slots(); }
-  void increase_ic_slots(int count) { spec_.increase_ic_slots(count); }
-  void SetKind(int ic_slot, FeedbackVectorSlotKind kind) {
-    spec_.SetKind(ic_slot, kind);
-  }
-  const ZoneFeedbackVectorSpec* get_spec() const { return &spec_; }
+  const FeedbackVectorSpec* get_spec() const { return &spec_; }
+  FeedbackVectorSpec* get_spec() { return &spec_; }
 
  private:
   Flags flags_;
   int node_count_;
-  ZoneFeedbackVectorSpec spec_;
+  FeedbackVectorSpec spec_;
 };
 
 DEFINE_OPERATORS_FOR_FLAGS(AstProperties::Flags)
@@ -249,15 +228,10 @@ class AstNode: public ZoneObject {
   // node types which don't actually have this. Note that this is conceptually
   // not really nice, but multiple inheritance would introduce yet another
   // vtable entry per node, something we don't want for space reasons.
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) {
-    return FeedbackVectorRequirements(0, 0);
-  }
-  virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
-  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                                      ICSlotCache* cache) {
-    UNREACHABLE();
-  }
+  virtual void AssignFeedbackVectorSlots(Isolate* isolate,
+                                         FeedbackVectorSpec* spec,
+                                         ICSlotCache* cache) {}
+
   // Each ICSlot stores a kind of IC which the participating node should know.
   virtual FeedbackVectorSlotKind FeedbackICSlotKind(int index) {
     UNREACHABLE();
@@ -808,13 +782,8 @@ class ForEachStatement : public IterationStatement {
   Expression* each() const { return each_; }
   Expression* subject() const { return subject_; }
 
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    each_slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
   FeedbackVectorICSlot EachFeedbackSlot() const { return each_slot_; }
 
  protected:
@@ -840,15 +809,10 @@ class ForInStatement final : public ForEachStatement {
   }
 
   // Type feedback information.
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override {
-    FeedbackVectorRequirements base =
-        ForEachStatement::ComputeFeedbackRequirements(isolate, cache);
-    DCHECK(base.slots() == 0 && base.ic_slots() <= 1);
-    return FeedbackVectorRequirements(1, base.ic_slots());
-  }
-  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override {
-    for_in_feedback_slot_ = slot;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override {
+    ForEachStatement::AssignFeedbackVectorSlots(isolate, spec, cache);
+    for_in_feedback_slot_ = spec->AddStubSlot();
   }
 
   FeedbackVectorSlot ForInFeedbackSlot() {
@@ -1550,15 +1514,8 @@ class ObjectLiteral final : public MaterializedLiteral {
 
   // Object literals need one feedback slot for each non-trivial value, as well
   // as some slots for home objects.
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return FeedbackVectorSlotKind::STORE_IC;
-  }
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
 
   // After feedback slots were assigned, propagate information to the properties
   // which need it.
@@ -1731,14 +1688,9 @@ class VariableProxy final : public Expression {
     return var()->IsUnallocated() || var()->IsLookupSlot();
   }
 
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
 
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override;
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return FeedbackVectorSlotKind::LOAD_IC;
-  }
   FeedbackVectorICSlot VariableFeedbackSlot() {
     return variable_feedback_slot_;
   }
@@ -1835,17 +1787,12 @@ class Property final : public Expression {
 
   bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
 
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override {
-    return FeedbackVectorRequirements(0, 1);
-  }
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    property_feedback_slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return key()->IsPropertyName() ? FeedbackVectorSlotKind::LOAD_IC
-                                   : FeedbackVectorSlotKind::KEYED_LOAD_IC;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override {
+    FeedbackVectorSlotKind kind = key()->IsPropertyName()
+                                      ? FeedbackVectorSlotKind::LOAD_IC
+                                      : FeedbackVectorSlotKind::KEYED_LOAD_IC;
+    property_feedback_slot_ = spec->AddSlot(kind);
   }
 
   FeedbackVectorICSlot PropertyFeedbackSlot() const {
@@ -1894,16 +1841,8 @@ class Call final : public Expression {
   ZoneList<Expression*>* arguments() const { return arguments_; }
 
   // Type feedback information.
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    ic_slot_ = slot;
-  }
-  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override { slot_ = slot; }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return FeedbackVectorSlotKind::CALL_IC;
-  }
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
 
   FeedbackVectorSlot CallFeedbackSlot() const { return slot_; }
 
@@ -2013,12 +1952,9 @@ class CallNew final : public Expression {
   ZoneList<Expression*>* arguments() const { return arguments_; }
 
   // Type feedback information.
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override {
-    return FeedbackVectorRequirements(1, 0);
-  }
-  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) override {
-    callnew_feedback_slot_ = slot;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override {
+    callnew_feedback_slot_ = spec->AddStubSlot();
   }
 
   FeedbackVectorSlot CallNewFeedbackSlot() {
@@ -2247,13 +2183,8 @@ class CountOperation final : public Expression {
     return TypeFeedbackId(local_id(3));
   }
 
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
   FeedbackVectorICSlot CountSlot() const { return slot_; }
 
  protected:
@@ -2425,13 +2356,8 @@ class Assignment final : public Expression {
     bit_field_ = StoreModeField::update(bit_field_, mode);
   }
 
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
   FeedbackVectorICSlot AssignmentSlot() const { return slot_; }
 
  protected:
@@ -2475,17 +2401,12 @@ class Yield final : public Expression {
 
   // Type feedback information.
   bool HasFeedbackSlots() const { return yield_kind() == kDelegating; }
-  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override {
-    return FeedbackVectorRequirements(0, HasFeedbackSlots() ? 3 : 0);
-  }
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    yield_first_feedback_slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return index == 0 ? FeedbackVectorSlotKind::KEYED_LOAD_IC
-                      : FeedbackVectorSlotKind::LOAD_IC;
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override {
+    if (HasFeedbackSlots()) {
+      yield_first_feedback_slot_ = spec->AddKeyedLoadICSlot();
+      spec->AddLoadICSlots(2);
+    }
   }
 
   FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
@@ -2654,7 +2575,7 @@ class FunctionLiteral final : public Expression {
   void set_ast_properties(AstProperties* ast_properties) {
     ast_properties_ = *ast_properties;
   }
-  const ZoneFeedbackVectorSpec* feedback_vector_spec() const {
+  const FeedbackVectorSpec* feedback_vector_spec() const {
     return ast_properties_.get_spec();
   }
   bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
@@ -2753,15 +2674,8 @@ class ClassLiteral final : public Expression {
 
   // Object literals need one feedback slot for each non-trivial value, as well
   // as some slots for home objects.
-  FeedbackVectorRequirements ComputeFeedbackRequirements(
-      Isolate* isolate, const ICSlotCache* cache) override;
-  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot,
-                              ICSlotCache* cache) override {
-    slot_ = slot;
-  }
-  FeedbackVectorSlotKind FeedbackICSlotKind(int index) override {
-    return FeedbackVectorSlotKind::STORE_IC;
-  }
+  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
+                                 ICSlotCache* cache) override;
 
   bool NeedsProxySlot() const {
     return FLAG_vector_stores && scope() != NULL &&
index c3a3b15..e3e8bc2 100644 (file)
@@ -2058,9 +2058,9 @@ void Factory::BecomeJSFunction(Handle<JSProxy> proxy) {
 
 
 template Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
-    const ZoneFeedbackVectorSpec* spec);
-template Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
     const FeedbackVectorSpec* spec);
+template Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
+    const StaticFeedbackVectorSpec* spec);
 
 template <typename Spec>
 Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(const Spec* spec) {
@@ -2128,7 +2128,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
   share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
   share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
   share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
-  FeedbackVectorSpec empty_spec(0);
+  StaticFeedbackVectorSpec empty_spec;
   Handle<TypeFeedbackVector> feedback_vector =
       NewTypeFeedbackVector(&empty_spec);
   share->set_feedback_vector(*feedback_vector, SKIP_WRITE_BARRIER);
index e044a1f..69ae7d9 100644 (file)
@@ -11,7 +11,7 @@
 namespace v8 {
 namespace internal {
 
-class FeedbackVectorSpec;
+class StaticFeedbackVectorSpec;
 
 // Interface for handle based allocation.
 class Factory final {
index f0648e2..c0fc2c4 100644 (file)
@@ -2700,7 +2700,7 @@ void Heap::CreateInitialObjects() {
                                       FeedbackVectorSlotKind::KEYED_LOAD_IC,
                                       FeedbackVectorSlotKind::STORE_IC,
                                       FeedbackVectorSlotKind::KEYED_STORE_IC};
-    FeedbackVectorSpec spec(0, 4, kinds);
+    StaticFeedbackVectorSpec spec(0, 4, kinds);
     Handle<TypeFeedbackVector> dummy_vector =
         factory->NewTypeFeedbackVector(&spec);
     for (int i = 0; i < 4; i++) {
index 1a60a8e..9da3c65 100644 (file)
@@ -36,9 +36,9 @@ void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot,
 
 
 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
-    Isolate* isolate, const FeedbackVectorSpec* spec);
+    Isolate* isolate, const StaticFeedbackVectorSpec* spec);
 template Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
-    Isolate* isolate, const ZoneFeedbackVectorSpec* spec);
+    Isolate* isolate, const FeedbackVectorSpec* spec);
 
 
 // static
@@ -84,9 +84,9 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(Isolate* isolate,
 }
 
 
-template int TypeFeedbackVector::GetIndexFromSpec(const ZoneFeedbackVectorSpec*,
+template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*,
                                                   FeedbackVectorICSlot);
-template int TypeFeedbackVector::GetIndexFromSpec(const ZoneFeedbackVectorSpec*,
+template int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec*,
                                                   FeedbackVectorSlot);
 
 
@@ -123,7 +123,7 @@ int TypeFeedbackVector::PushAppliedArgumentsIndex() {
 Handle<TypeFeedbackVector> TypeFeedbackVector::CreatePushAppliedArgumentsVector(
     Isolate* isolate) {
   FeedbackVectorSlotKind kinds[] = {FeedbackVectorSlotKind::KEYED_LOAD_IC};
-  FeedbackVectorSpec spec(0, 1, kinds);
+  StaticFeedbackVectorSpec spec(0, 1, kinds);
   Handle<TypeFeedbackVector> feedback_vector =
       isolate->factory()->NewTypeFeedbackVector(&spec);
   DCHECK(PushAppliedArgumentsIndex() ==
@@ -143,7 +143,7 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
 
 
 bool TypeFeedbackVector::SpecDiffersFrom(
-    const ZoneFeedbackVectorSpec* other_spec) const {
+    const FeedbackVectorSpec* other_spec) const {
   if (other_spec->slots() != Slots() || other_spec->ic_slots() != ICSlots()) {
     return true;
   }
index 0c921ed..64fcda4 100644 (file)
@@ -33,13 +33,11 @@ enum class FeedbackVectorSlotKind {
 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
 
 
-class FeedbackVectorSpec {
+class StaticFeedbackVectorSpec {
  public:
-  FeedbackVectorSpec() : slots_(0), ic_slots_(0), ic_kinds_(NULL) {}
-  explicit FeedbackVectorSpec(int slots)
-      : slots_(slots), ic_slots_(0), ic_kinds_(NULL) {}
-  FeedbackVectorSpec(int slots, int ic_slots,
-                     FeedbackVectorSlotKind* ic_slot_kinds)
+  StaticFeedbackVectorSpec() : slots_(0), ic_slots_(0), ic_kinds_(NULL) {}
+  StaticFeedbackVectorSpec(int slots, int ic_slots,
+                           FeedbackVectorSlotKind* ic_slot_kinds)
       : slots_(slots), ic_slots_(ic_slots), ic_kinds_(ic_slot_kinds) {}
 
   int slots() const { return slots_; }
@@ -58,25 +56,70 @@ class FeedbackVectorSpec {
 };
 
 
-class ZoneFeedbackVectorSpec {
+class FeedbackVectorSpec {
  public:
-  explicit ZoneFeedbackVectorSpec(Zone* zone)
+  explicit FeedbackVectorSpec(Zone* zone)
       : slots_(0), ic_slots_(0), ic_slot_kinds_(zone) {}
 
-  ZoneFeedbackVectorSpec(Zone* zone, int slots, int ic_slots)
-      : slots_(slots), ic_slots_(ic_slots), ic_slot_kinds_(ic_slots, zone) {}
-
   int slots() const { return slots_; }
-  void increase_slots(int count) { slots_ += count; }
+  void increase_slots(int count) {
+    DCHECK_LT(0, count);
+    slots_ += count;
+  }
 
   int ic_slots() const { return ic_slots_; }
   void increase_ic_slots(int count) {
+    DCHECK_LT(0, count);
     ic_slots_ += count;
     ic_slot_kinds_.resize(ic_slots_);
   }
 
-  void SetKind(int ic_slot, FeedbackVectorSlotKind kind) {
-    ic_slot_kinds_[ic_slot] = static_cast<unsigned char>(kind);
+  FeedbackVectorICSlot AddSlot(FeedbackVectorSlotKind kind) {
+    int slot = ic_slots_;
+    increase_ic_slots(1);
+    ic_slot_kinds_[slot] = static_cast<unsigned char>(kind);
+    return FeedbackVectorICSlot(slot);
+  }
+
+  FeedbackVectorICSlot AddSlots(FeedbackVectorSlotKind kind, int count) {
+    int slot = ic_slots_;
+    increase_ic_slots(count);
+    for (int i = 0; i < count; i++) {
+      ic_slot_kinds_[slot + i] = static_cast<unsigned char>(kind);
+    }
+    return FeedbackVectorICSlot(slot);
+  }
+
+  FeedbackVectorICSlot AddCallICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::CALL_IC);
+  }
+
+  FeedbackVectorICSlot AddLoadICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
+  }
+
+  FeedbackVectorICSlot AddLoadICSlots(int count) {
+    return AddSlots(FeedbackVectorSlotKind::LOAD_IC, count);
+  }
+
+  FeedbackVectorICSlot AddKeyedLoadICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
+  }
+
+  FeedbackVectorICSlot AddStoreICSlots(int count) {
+    return AddSlots(FeedbackVectorSlotKind::STORE_IC, count);
+  }
+
+  FeedbackVectorSlot AddStubSlot() {
+    int slot = slots_;
+    increase_slots(1);
+    return FeedbackVectorSlot(slot);
+  }
+
+  FeedbackVectorSlot AddStubSlots(int count) {
+    int slot = slots_;
+    increase_slots(count);
+    return FeedbackVectorSlot(slot);
   }
 
   FeedbackVectorSlotKind GetKind(int ic_slot) const {
@@ -120,7 +163,7 @@ class TypeFeedbackVector : public FixedArray {
   inline void change_ic_generic_count(int delta);
   inline int ic_metadata_length() const;
 
-  bool SpecDiffersFrom(const ZoneFeedbackVectorSpec* other_spec) const;
+  bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
 
   inline int Slots() const;
   inline int ICSlots() const;
index 2808552..8716497 100644 (file)
@@ -394,7 +394,7 @@ TEST(PropertyLoads) {
 
   FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC,
                                        i::FeedbackVectorSlotKind::LOAD_IC};
-  FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
+  StaticFeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       helper.factory()->NewTypeFeedbackVector(&feedback_spec);
 
@@ -482,7 +482,7 @@ TEST(PropertyStores) {
 
   FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::STORE_IC,
                                        i::FeedbackVectorSlotKind::STORE_IC};
-  FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
+  StaticFeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       helper.factory()->NewTypeFeedbackVector(&feedback_spec);
 
@@ -588,7 +588,7 @@ TEST(PropertyCall) {
 
   FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC,
                                        i::FeedbackVectorSlotKind::LOAD_IC};
-  FeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
+  StaticFeedbackVectorSpec feedback_spec(0, 2, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       helper.factory()->NewTypeFeedbackVector(&feedback_spec);
 
index 7edf8d7..adac491 100644 (file)
@@ -553,7 +553,7 @@ TEST(InterpreterLoadNamedProperty) {
   i::Factory* factory = isolate->factory();
 
   i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC};
-  i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
+  i::StaticFeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       factory->NewTypeFeedbackVector(&feedback_spec);
 
@@ -608,7 +608,7 @@ TEST(InterpreterLoadKeyedProperty) {
 
   i::FeedbackVectorSlotKind ic_kinds[] = {
       i::FeedbackVectorSlotKind::KEYED_LOAD_IC};
-  i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
+  i::StaticFeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       factory->NewTypeFeedbackVector(&feedback_spec);
 
@@ -650,7 +650,7 @@ TEST(InterpreterStoreNamedProperty) {
   i::Factory* factory = isolate->factory();
 
   i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::STORE_IC};
-  i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
+  i::StaticFeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       factory->NewTypeFeedbackVector(&feedback_spec);
 
@@ -711,7 +711,7 @@ TEST(InterpreterStoreKeyedProperty) {
 
   i::FeedbackVectorSlotKind ic_kinds[] = {
       i::FeedbackVectorSlotKind::KEYED_STORE_IC};
-  i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
+  i::StaticFeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       factory->NewTypeFeedbackVector(&feedback_spec);
 
@@ -758,7 +758,7 @@ TEST(InterpreterCall) {
   i::Factory* factory = isolate->factory();
 
   i::FeedbackVectorSlotKind ic_kinds[] = {i::FeedbackVectorSlotKind::LOAD_IC};
-  i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
+  i::StaticFeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
   Handle<i::TypeFeedbackVector> vector =
       factory->NewTypeFeedbackVector(&feedback_spec);
 
index 71d0e81..d455ca0 100644 (file)
@@ -29,7 +29,7 @@ TEST(VectorStructure) {
   Zone* zone = isolate->runtime_zone();
 
   // Empty vectors are the empty fixed array.
-  FeedbackVectorSpec empty;
+  StaticFeedbackVectorSpec empty;
   Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&empty);
   CHECK(Handle<FixedArray>::cast(vector)
             .is_identical_to(factory->empty_fixed_array()));
@@ -39,19 +39,21 @@ TEST(VectorStructure) {
   CHECK_EQ(0, vector->Slots());
   CHECK_EQ(0, vector->ICSlots());
 
-  FeedbackVectorSpec one_slot(1);
+  FeedbackVectorSpec one_slot(zone);
+  one_slot.AddStubSlot();
   vector = factory->NewTypeFeedbackVector(&one_slot);
   CHECK_EQ(1, vector->Slots());
   CHECK_EQ(0, vector->ICSlots());
 
-  ZoneFeedbackVectorSpec one_icslot(zone, 0, 1);
-  one_icslot.SetKind(0, FeedbackVectorSlotKind::CALL_IC);
+  FeedbackVectorSpec one_icslot(zone);
+  one_icslot.AddSlot(FeedbackVectorSlotKind::CALL_IC);
   vector = factory->NewTypeFeedbackVector(&one_icslot);
   CHECK_EQ(0, vector->Slots());
   CHECK_EQ(1, vector->ICSlots());
 
-  ZoneFeedbackVectorSpec spec(zone, 3, 5);
-  for (int i = 0; i < 5; i++) spec.SetKind(i, FeedbackVectorSlotKind::CALL_IC);
+  FeedbackVectorSpec spec(zone);
+  spec.AddStubSlots(3);
+  spec.AddSlots(FeedbackVectorSlotKind::CALL_IC, 5);
   vector = factory->NewTypeFeedbackVector(&spec);
   CHECK_EQ(3, vector->Slots());
   CHECK_EQ(5, vector->ICSlots());
@@ -82,18 +84,21 @@ TEST(VectorICMetadata) {
   Factory* factory = isolate->factory();
   Zone* zone = isolate->runtime_zone();
 
-  ZoneFeedbackVectorSpec spec(zone, 10, 3 * 10);
+  FeedbackVectorSpec spec(zone);
   // Set metadata.
+  spec.AddStubSlots(10);
   for (int i = 0; i < 30; i++) {
-    FeedbackVectorSlotKind kind;
-    if (i % 3 == 0) {
-      kind = FeedbackVectorSlotKind::CALL_IC;
-    } else if (i % 3 == 1) {
-      kind = FeedbackVectorSlotKind::LOAD_IC;
-    } else {
-      kind = FeedbackVectorSlotKind::KEYED_LOAD_IC;
+    switch (i % 3) {
+      case 0:
+        spec.AddSlot(FeedbackVectorSlotKind::CALL_IC);
+        break;
+      case 1:
+        spec.AddSlot(FeedbackVectorSlotKind::LOAD_IC);
+        break;
+      case 2:
+        spec.AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
+        break;
     }
-    spec.SetKind(i, kind);
   }
 
   Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&spec);
@@ -125,11 +130,13 @@ TEST(VectorSlotClearing) {
   v8::HandleScope scope(context->GetIsolate());
   Isolate* isolate = CcTest::i_isolate();
   Factory* factory = isolate->factory();
+  Zone* zone = isolate->runtime_zone();
 
   // We only test clearing FeedbackVectorSlots, not FeedbackVectorICSlots.
   // The reason is that FeedbackVectorICSlots need a full code environment
   // to fully test (See VectorICProfilerStatistics test below).
-  FeedbackVectorSpec spec(5);
+  FeedbackVectorSpec spec(zone);
+  spec.AddStubSlots(5);
   Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(&spec);
 
   // Fill with information