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_
