Upgrade V8 to version 4.9.385.28

https://chromium.googlesource.com/v8/v8/+/4.9.385.28

FPIIM-449

Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h
index 864f336..d83b77f 100644
--- a/src/type-feedback-vector.h
+++ b/src/type-feedback-vector.h
@@ -7,164 +7,228 @@
 
 #include <vector>
 
-#include "src/checks.h"
+#include "src/base/logging.h"
 #include "src/elements-kind.h"
-#include "src/heap/heap.h"
-#include "src/isolate.h"
 #include "src/objects.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 
-class FeedbackVectorSpec {
+
+enum class FeedbackVectorSlotKind {
+  // This kind means that the slot points to the middle of other slot
+  // which occupies more than one feedback vector element.
+  // There must be no such slots in the system.
+  INVALID,
+
+  CALL_IC,
+  LOAD_IC,
+  KEYED_LOAD_IC,
+  STORE_IC,
+  KEYED_STORE_IC,
+
+  // This is a general purpose slot that occupies one feedback vector element.
+  GENERAL,
+
+  KINDS_NUMBER  // Last value indicating number of kinds.
+};
+
+
+std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
+
+
+template <typename Derived>
+class FeedbackVectorSpecBase {
  public:
-  FeedbackVectorSpec() : slots_(0), ic_slots_(0) {}
-  FeedbackVectorSpec(int slots, int ic_slots)
-      : slots_(slots), ic_slots_(ic_slots) {
-    if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots);
+  inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind);
+
+  FeedbackVectorSlot AddCallICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::CALL_IC);
   }
 
+  FeedbackVectorSlot AddLoadICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
+  }
+
+  FeedbackVectorSlot AddKeyedLoadICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
+  }
+
+  FeedbackVectorSlot AddStoreICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::STORE_IC);
+  }
+
+  FeedbackVectorSlot AddKeyedStoreICSlot() {
+    return AddSlot(FeedbackVectorSlotKind::KEYED_STORE_IC);
+  }
+
+  FeedbackVectorSlot AddGeneralSlot() {
+    return AddSlot(FeedbackVectorSlotKind::GENERAL);
+  }
+};
+
+
+class StaticFeedbackVectorSpec
+    : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
+ public:
+  StaticFeedbackVectorSpec() : slots_(0) {}
+
   int slots() const { return slots_; }
-  void increase_slots(int count) { slots_ += count; }
 
-  int ic_slots() const { return ic_slots_; }
-  void increase_ic_slots(int count) {
-    ic_slots_ += count;
-    if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots_);
-  }
-
-  void SetKind(int ic_slot, Code::Kind kind) {
-    DCHECK(FLAG_vector_ics);
-    ic_slot_kinds_[ic_slot] = kind;
-  }
-
-  Code::Kind GetKind(int ic_slot) const {
-    DCHECK(FLAG_vector_ics);
-    return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot));
+  FeedbackVectorSlotKind GetKind(int slot) const {
+    DCHECK(slot >= 0 && slot < slots_);
+    return kinds_[slot];
   }
 
  private:
+  friend class FeedbackVectorSpecBase<StaticFeedbackVectorSpec>;
+
+  void append(FeedbackVectorSlotKind kind) {
+    DCHECK(slots_ < kMaxLength);
+    kinds_[slots_++] = kind;
+  }
+
+  static const int kMaxLength = 12;
+
   int slots_;
-  int ic_slots_;
-  std::vector<unsigned char> ic_slot_kinds_;
+  FeedbackVectorSlotKind kinds_[kMaxLength];
+};
+
+
+class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
+ public:
+  explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone) {
+    slot_kinds_.reserve(16);
+  }
+
+  int slots() const { return static_cast<int>(slot_kinds_.size()); }
+
+  FeedbackVectorSlotKind GetKind(int slot) const {
+    return static_cast<FeedbackVectorSlotKind>(slot_kinds_.at(slot));
+  }
+
+ private:
+  friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
+
+  void append(FeedbackVectorSlotKind kind) {
+    slot_kinds_.push_back(static_cast<unsigned char>(kind));
+  }
+
+  ZoneVector<unsigned char> slot_kinds_;
+};
+
+
+// The shape of the TypeFeedbackMetadata is an array with:
+// 0: slot_count
+// 1..N: slot kinds packed into a bit vector
+//
+class TypeFeedbackMetadata : public FixedArray {
+ public:
+  // Casting.
+  static inline TypeFeedbackMetadata* cast(Object* obj);
+
+  static const int kSlotsCountIndex = 0;
+  static const int kReservedIndexCount = 1;
+
+  // Returns number of feedback vector elements used by given slot kind.
+  static inline int GetSlotSize(FeedbackVectorSlotKind kind);
+
+  bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
+
+  // Returns number of slots in the vector.
+  inline int slot_count() const;
+
+  // Returns slot kind for given slot.
+  FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
+
+  template <typename Spec>
+  static Handle<TypeFeedbackMetadata> New(Isolate* isolate, const Spec* spec);
+
+#ifdef OBJECT_PRINT
+  // For gdb debugging.
+  void Print();
+#endif  // OBJECT_PRINT
+
+  DECLARE_PRINTER(TypeFeedbackMetadata)
+
+  static const char* Kind2String(FeedbackVectorSlotKind kind);
+
+ private:
+  static const int kFeedbackVectorSlotKindBits = 3;
+  STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
+                (1 << kFeedbackVectorSlotKindBits));
+
+  void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
+
+  typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
+                         kSmiValueSize, uint32_t> VectorICComputer;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata);
 };
 
 
 // The shape of the TypeFeedbackVector is an array with:
-// 0: first_ic_slot_index (== length() if no ic slots are present)
+// 0: feedback metadata
 // 1: ics_with_types
 // 2: ics_with_generic_info
-// 3: type information for ic slots, if any
+// 3: feedback slot #0 (N >= 3)
 // ...
-// N: first feedback slot (N >= 3)
-// ...
-// [<first_ic_slot_index>: feedback slot]
-// ...to length() - 1
+// N + slot_count - 1: feedback slot #(slot_count-1)
 //
 class TypeFeedbackVector : public FixedArray {
  public:
   // Casting.
-  static TypeFeedbackVector* cast(Object* obj) {
-    DCHECK(obj->IsTypeFeedbackVector());
-    return reinterpret_cast<TypeFeedbackVector*>(obj);
-  }
+  static inline TypeFeedbackVector* cast(Object* obj);
 
-  static const int kReservedIndexCount = 3;
-  static const int kFirstICSlotIndex = 0;
-  static const int kWithTypesIndex = 1;
-  static const int kGenericCountIndex = 2;
+  static const int kMetadataIndex = 0;
+  static const int kReservedIndexCount = 1;
 
-  int first_ic_slot_index() const {
-    DCHECK(length() >= kReservedIndexCount);
-    return Smi::cast(get(kFirstICSlotIndex))->value();
-  }
+  inline void ComputeCounts(int* with_type_info, int* generic);
 
-  int ic_with_type_info_count() {
-    return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0;
-  }
+  inline bool is_empty() const;
 
-  void change_ic_with_type_info_count(int delta) {
-    if (delta == 0) return;
-    int value = ic_with_type_info_count() + delta;
-    // Could go negative because of the debugger.
-    if (value >= 0) {
-      set(kWithTypesIndex, Smi::FromInt(value));
-    }
-  }
+  // Returns number of slots in the vector.
+  inline int slot_count() const;
 
-  int ic_generic_count() {
-    return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0;
-  }
+  inline TypeFeedbackMetadata* metadata() const;
 
-  void change_ic_generic_count(int delta) {
-    if (delta == 0) return;
-    int value = ic_generic_count() + delta;
-    if (value >= 0) {
-      set(kGenericCountIndex, Smi::FromInt(value));
-    }
-  }
+  // Conversion from a slot to an integer index to the underlying array.
+  inline int GetIndex(FeedbackVectorSlot slot) const;
+  static int GetIndexFromSpec(const FeedbackVectorSpec* spec,
+                              FeedbackVectorSlot slot);
 
-  inline int ic_metadata_length() const;
+  // Conversion from an integer index to the underlying array to a slot.
+  inline FeedbackVectorSlot ToSlot(int index) const;
+  inline Object* Get(FeedbackVectorSlot slot) const;
+  inline void Set(FeedbackVectorSlot slot, Object* value,
+                  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
 
-  int Slots() const {
-    if (length() == 0) return 0;
-    return Max(
-        0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount);
-  }
+  // Returns slot kind for given slot.
+  inline FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
 
-  int ICSlots() const {
-    if (length() == 0) return 0;
-    return length() - first_ic_slot_index();
-  }
-
-  // Conversion from a slot or ic slot to an integer index to the underlying
-  // array.
-  int GetIndex(FeedbackVectorSlot slot) const {
-    return kReservedIndexCount + ic_metadata_length() + slot.ToInt();
-  }
-
-  int GetIndex(FeedbackVectorICSlot slot) const {
-    int first_ic_slot = first_ic_slot_index();
-    DCHECK(slot.ToInt() < ICSlots());
-    return first_ic_slot + slot.ToInt();
-  }
-
-  // Conversion from an integer index to either a slot or an ic slot. The caller
-  // should know what kind she expects.
-  FeedbackVectorSlot ToSlot(int index) const {
-    DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index());
-    return FeedbackVectorSlot(index - ic_metadata_length() -
-                              kReservedIndexCount);
-  }
-
-  FeedbackVectorICSlot ToICSlot(int index) const {
-    DCHECK(index >= first_ic_slot_index() && index < length());
-    return FeedbackVectorICSlot(index - first_ic_slot_index());
-  }
-
-  Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); }
-  void Set(FeedbackVectorSlot slot, Object* value,
-           WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
-    set(GetIndex(slot), value, mode);
-  }
-
-  Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); }
-  void Set(FeedbackVectorICSlot slot, Object* value,
-           WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
-    set(GetIndex(slot), value, mode);
-  }
-
-  // IC slots need metadata to recognize the type of IC.
-  Code::Kind GetKind(FeedbackVectorICSlot slot) const;
-
-  static Handle<TypeFeedbackVector> Allocate(Isolate* isolate,
-                                             const FeedbackVectorSpec& spec);
+  static Handle<TypeFeedbackVector> New(Isolate* isolate,
+                                        Handle<TypeFeedbackMetadata> metadata);
 
   static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
                                          Handle<TypeFeedbackVector> vector);
 
-  // Clears the vector slots and the vector ic slots.
-  void ClearSlots(SharedFunctionInfo* shared);
+#ifdef OBJECT_PRINT
+  // For gdb debugging.
+  void Print();
+#endif  // OBJECT_PRINT
+
+  DECLARE_PRINTER(TypeFeedbackVector)
+
+  // Clears the vector slots.
+  void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); }
+
+  void ClearSlotsAtGCTime(SharedFunctionInfo* shared) {
+    ClearSlotsImpl(shared, false);
+  }
+
+  static void ClearAllKeyedStoreICs(Isolate* isolate);
+  void ClearKeyedStoreICs(SharedFunctionInfo* shared);
 
   // The object that indicates an uninitialized cache.
   static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
@@ -175,45 +239,97 @@
   // The object that indicates a premonomorphic state.
   static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate);
 
-  // The object that indicates a generic state.
-  static inline Handle<Object> GenericSentinel(Isolate* isolate);
-
-  // The object that indicates a monomorphic state of Array with
-  // ElementsKind
-  static inline Handle<Object> MonomorphicArraySentinel(
-      Isolate* isolate, ElementsKind elements_kind);
-
   // A raw version of the uninitialized sentinel that's safe to read during
   // garbage collection (e.g., for patching the cache).
-  static inline Object* RawUninitializedSentinel(Heap* heap);
+  static inline Object* RawUninitializedSentinel(Isolate* isolate);
+
+  static const int kDummyLoadICSlot = 0;
+  static const int kDummyKeyedLoadICSlot = 2;
+  static const int kDummyStoreICSlot = 4;
+  static const int kDummyKeyedStoreICSlot = 6;
+
+  static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate);
+  static FeedbackVectorSlot DummySlot(int dummyIndex) {
+    DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot);
+    return FeedbackVectorSlot(dummyIndex);
+  }
 
  private:
-  enum VectorICKind {
-    KindUnused = 0x0,
-    KindCallIC = 0x1,
-    KindLoadIC = 0x2,
-    KindKeyedLoadIC = 0x3
-  };
-
-  static const int kVectorICKindBits = 2;
-  static VectorICKind FromCodeKind(Code::Kind kind);
-  static Code::Kind FromVectorICKind(VectorICKind kind);
-  void SetKind(FeedbackVectorICSlot slot, Code::Kind kind);
-
-  typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize,
-                         uint32_t> VectorICComputer;
+  void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
 };
 
 
+// The following asserts protect an optimization in type feedback vector
+// code that looks into the contents of a slot assuming to find a String,
+// a Symbol, an AllocationSite, a WeakCell, or a FixedArray.
+STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
+STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
+STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
+STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot);
+// Verify that an empty hash field looks like a tagged object, but can't
+// possibly be confused with a pointer.
+STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
+STATIC_ASSERT(Name::kEmptyHashField == 0x3);
+// Verify that a set hash field will not look like a tagged object.
+STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
+
+
+class TypeFeedbackMetadataIterator {
+ public:
+  explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)
+      : metadata_handle_(metadata),
+        slot_(FeedbackVectorSlot(0)),
+        slot_kind_(FeedbackVectorSlotKind::INVALID) {}
+
+  explicit TypeFeedbackMetadataIterator(TypeFeedbackMetadata* metadata)
+      : metadata_(metadata),
+        slot_(FeedbackVectorSlot(0)),
+        slot_kind_(FeedbackVectorSlotKind::INVALID) {}
+
+  bool HasNext() const { return slot_.ToInt() < metadata()->slot_count(); }
+
+  FeedbackVectorSlot Next() {
+    DCHECK(HasNext());
+    FeedbackVectorSlot slot = slot_;
+    slot_kind_ = metadata()->GetKind(slot);
+    slot_ = FeedbackVectorSlot(slot_.ToInt() + entry_size());
+    return slot;
+  }
+
+  // Returns slot kind of the last slot returned by Next().
+  FeedbackVectorSlotKind kind() const {
+    DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_);
+    DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_);
+    return slot_kind_;
+  }
+
+  // Returns entry size of the last slot returned by Next().
+  int entry_size() const { return TypeFeedbackMetadata::GetSlotSize(kind()); }
+
+ private:
+  TypeFeedbackMetadata* metadata() const {
+    return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
+  }
+
+  // The reason for having a handle and a raw pointer to the meta data is
+  // to have a single iterator implementation for both "handlified" and raw
+  // pointer use cases.
+  Handle<TypeFeedbackMetadata> metadata_handle_;
+  TypeFeedbackMetadata* metadata_;
+  FeedbackVectorSlot slot_;
+  FeedbackVectorSlotKind slot_kind_;
+};
+
+
 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot.
 // Derived classes customize the update and retrieval of feedback.
 class FeedbackNexus {
  public:
-  FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+  FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
       : vector_handle_(vector), vector_(NULL), slot_(slot) {}
-  FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+  FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
       : vector_(vector), slot_(slot) {}
   virtual ~FeedbackNexus() {}
 
@@ -224,7 +340,7 @@
   TypeFeedbackVector* vector() const {
     return vector_handle_.is_null() ? vector_ : *vector_handle_;
   }
-  FeedbackVectorICSlot slot() const { return slot_; }
+  FeedbackVectorSlot slot() const { return slot_; }
 
   InlineCacheState ic_state() const { return StateFromFeedback(); }
   Map* FindFirstMap() const {
@@ -238,30 +354,30 @@
   void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
 
   virtual InlineCacheState StateFromFeedback() const = 0;
-  virtual int ExtractMaps(MapHandleList* maps) const = 0;
-  virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0;
-  virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const {
-    return length == 0;
-  }
+  virtual int ExtractMaps(MapHandleList* maps) const;
+  virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const;
+  virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const;
   virtual Name* FindFirstName() const { return NULL; }
 
-  Object* GetFeedback() const { return vector()->Get(slot()); }
+  virtual void ConfigureUninitialized();
+  virtual void ConfigurePremonomorphic();
+  virtual void ConfigureMegamorphic();
+
+  inline Object* GetFeedback() const;
+  inline Object* GetFeedbackExtra() const;
+
+  inline Isolate* GetIsolate() const;
 
  protected:
-  Isolate* GetIsolate() const { return vector()->GetIsolate(); }
-
-  void SetFeedback(Object* feedback,
-                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
-    vector()->Set(slot(), feedback, mode);
-  }
+  inline void SetFeedback(Object* feedback,
+                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+  inline void SetFeedbackExtra(Object* feedback_extra,
+                               WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
 
   Handle<FixedArray> EnsureArrayOfSize(int length);
-  void InstallHandlers(int start_index, TypeHandleList* types,
+  Handle<FixedArray> EnsureExtraArrayOfSize(int length);
+  void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
                        CodeHandleList* handlers);
-  int ExtractMaps(int start_index, MapHandleList* maps) const;
-  MaybeHandle<Code> FindHandlerForMap(int start_index, Handle<Map> map) const;
-  bool FindHandlers(int start_index, CodeHandleList* code_list,
-                    int length) const;
 
  private:
   // The reason for having a vector handle and a raw pointer is that we can and
@@ -270,101 +386,158 @@
   // be done, like allocation.
   Handle<TypeFeedbackVector> vector_handle_;
   TypeFeedbackVector* vector_;
-  FeedbackVectorICSlot slot_;
+  FeedbackVectorSlot slot_;
 };
 
 
-class CallICNexus : public FeedbackNexus {
+class CallICNexus final : public FeedbackNexus {
  public:
-  CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+  // Monomorphic call ics store call counts. Platform code needs to increment
+  // the count appropriately (ie, by 2).
+  static const int kCallCountIncrement = 2;
+
+  CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::CALL_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
   }
-  CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+  CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::CALL_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
   }
 
   void Clear(Code* host);
 
-  void ConfigureUninitialized();
-  void ConfigureGeneric();
   void ConfigureMonomorphicArray();
   void ConfigureMonomorphic(Handle<JSFunction> function);
+  void ConfigureMegamorphic() final;
+  void ConfigureMegamorphic(int call_count);
 
-  InlineCacheState StateFromFeedback() const OVERRIDE;
+  InlineCacheState StateFromFeedback() const final;
 
-  int ExtractMaps(MapHandleList* maps) const OVERRIDE {
+  int ExtractMaps(MapHandleList* maps) const final {
     // CallICs don't record map feedback.
     return 0;
   }
-  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE {
+  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final {
     return MaybeHandle<Code>();
   }
-  virtual bool FindHandlers(CodeHandleList* code_list,
-                            int length = -1) const OVERRIDE {
+  bool FindHandlers(CodeHandleList* code_list, int length = -1) const final {
     return length == 0;
   }
+
+  int ExtractCallCount();
 };
 
 
 class LoadICNexus : public FeedbackNexus {
  public:
-  LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+  LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
   }
-  LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+  explicit LoadICNexus(Isolate* isolate)
+      : FeedbackNexus(
+            TypeFeedbackVector::DummyVector(isolate),
+            FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
+  LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
   }
 
   void Clear(Code* host);
 
-  void ConfigureMegamorphic();
-  void ConfigurePremonomorphic();
-  void ConfigureMonomorphic(Handle<HeapType> type, Handle<Code> handler);
+  void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
 
-  void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers);
+  void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
 
-  InlineCacheState StateFromFeedback() const OVERRIDE;
-  int ExtractMaps(MapHandleList* maps) const OVERRIDE;
-  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
-  virtual bool FindHandlers(CodeHandleList* code_list,
-                            int length = -1) const OVERRIDE;
+  InlineCacheState StateFromFeedback() const override;
 };
 
 
 class KeyedLoadICNexus : public FeedbackNexus {
  public:
-  KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+  KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
   }
-  KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+  KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
       : FeedbackNexus(vector, slot) {
-    DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
+    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
   }
 
   void Clear(Code* host);
 
-  void ConfigureGeneric();
-  void ConfigurePremonomorphic();
   // name can be a null handle for element loads.
-  void ConfigureMonomorphic(Handle<Name> name, Handle<HeapType> type,
+  void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
                             Handle<Code> handler);
   // name can be null.
-  void ConfigurePolymorphic(Handle<Name> name, TypeHandleList* types,
+  void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
                             CodeHandleList* handlers);
 
-  InlineCacheState StateFromFeedback() const OVERRIDE;
-  int ExtractMaps(MapHandleList* maps) const OVERRIDE;
-  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
-  virtual bool FindHandlers(CodeHandleList* code_list,
-                            int length = -1) const OVERRIDE;
-  Name* FindFirstName() const OVERRIDE;
+  InlineCacheState StateFromFeedback() const override;
+  Name* FindFirstName() const override;
 };
-}
-}  // namespace v8::internal
+
+
+class StoreICNexus : public FeedbackNexus {
+ public:
+  StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
+  }
+  explicit StoreICNexus(Isolate* isolate)
+      : FeedbackNexus(
+            TypeFeedbackVector::DummyVector(isolate),
+            FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
+  StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
+  }
+
+  void Clear(Code* host);
+
+  void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
+
+  void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
+
+  InlineCacheState StateFromFeedback() const override;
+};
+
+
+class KeyedStoreICNexus : public FeedbackNexus {
+ public:
+  KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
+  }
+  explicit KeyedStoreICNexus(Isolate* isolate)
+      : FeedbackNexus(
+            TypeFeedbackVector::DummyVector(isolate),
+            FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
+  KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
+  }
+
+  void Clear(Code* host);
+
+  // name can be a null handle for element loads.
+  void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
+                            Handle<Code> handler);
+  // name can be null.
+  void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
+                            CodeHandleList* handlers);
+  void ConfigurePolymorphic(MapHandleList* maps,
+                            MapHandleList* transitioned_maps,
+                            CodeHandleList* handlers);
+
+  KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
+  IcCheckType GetKeyType() const;
+
+  InlineCacheState StateFromFeedback() const override;
+  Name* FindFirstName() const override;
+};
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_TRANSITIONS_H_