diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc
index c51d987..698f2a6 100644
--- a/src/type-feedback-vector.cc
+++ b/src/type-feedback-vector.cc
@@ -2,8 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
+#include "src/type-feedback-vector.h"
 
+#include "src/code-stubs.h"
 #include "src/ic/ic.h"
 #include "src/ic/ic-state.h"
 #include "src/objects.h"
@@ -12,111 +13,149 @@
 namespace v8 {
 namespace internal {
 
-// static
-TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind(
-    Code::Kind kind) {
-  switch (kind) {
-    case Code::CALL_IC:
-      return KindCallIC;
-    case Code::LOAD_IC:
-      return KindLoadIC;
-    case Code::KEYED_LOAD_IC:
-      return KindKeyedLoadIC;
-    default:
-      // Shouldn't get here.
-      UNREACHABLE();
-  }
 
-  return KindUnused;
+static bool IsPropertyNameFeedback(Object* feedback) {
+  return feedback->IsString() ||
+         (feedback->IsSymbol() && !Symbol::cast(feedback)->is_private());
 }
 
 
-// static
-Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
-  switch (kind) {
-    case KindCallIC:
-      return Code::CALL_IC;
-    case KindLoadIC:
-      return Code::LOAD_IC;
-    case KindKeyedLoadIC:
-      return Code::KEYED_LOAD_IC;
-    case KindUnused:
-      break;
-  }
-  // Sentinel for no information.
-  return Code::NUMBER_OF_KINDS;
+std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) {
+  return os << TypeFeedbackMetadata::Kind2String(kind);
 }
 
 
-Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
-  if (!FLAG_vector_ics) {
-    // We only have CALL_ICs
-    return Code::CALL_IC;
-  }
-
+FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind(
+    FeedbackVectorSlot slot) const {
   int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
   int data = Smi::cast(get(index))->value();
-  VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
-  return FromVectorICKind(b);
+  return VectorICComputer::decode(data, slot.ToInt());
 }
 
 
-void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
-  if (!FLAG_vector_ics) {
-    // Nothing to do if we only have CALL_ICs
-    return;
-  }
-
-  VectorICKind b = FromCodeKind(kind);
+void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot,
+                                   FeedbackVectorSlotKind kind) {
   int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
   int data = Smi::cast(get(index))->value();
-  int new_data = VectorICComputer::encode(data, slot.ToInt(), b);
+  int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
   set(index, Smi::FromInt(new_data));
 }
 
 
+template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
+    Isolate* isolate, const StaticFeedbackVectorSpec* spec);
+template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(
+    Isolate* isolate, const FeedbackVectorSpec* spec);
+
+
 // static
-Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
-    Isolate* isolate, const FeedbackVectorSpec& spec) {
-  const int slot_count = spec.slots();
-  const int ic_slot_count = spec.ic_slots();
-  const int index_count =
-      FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
-  const int length =
-      slot_count + ic_slot_count + index_count + kReservedIndexCount;
+template <typename Spec>
+Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate,
+                                                       const Spec* spec) {
+  const int slot_count = spec->slots();
+  const int slot_kinds_length = VectorICComputer::word_count(slot_count);
+  const int length = slot_kinds_length + kReservedIndexCount;
   if (length == kReservedIndexCount) {
-    return Handle<TypeFeedbackVector>::cast(
+    return Handle<TypeFeedbackMetadata>::cast(
         isolate->factory()->empty_fixed_array());
   }
+#ifdef DEBUG
+  for (int i = 0; i < slot_count;) {
+    FeedbackVectorSlotKind kind = spec->GetKind(i);
+    int entry_size = TypeFeedbackMetadata::GetSlotSize(kind);
+    for (int j = 1; j < entry_size; j++) {
+      FeedbackVectorSlotKind kind = spec->GetKind(i + j);
+      DCHECK_EQ(FeedbackVectorSlotKind::INVALID, kind);
+    }
+    i += entry_size;
+  }
+#endif
 
   Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
-  if (ic_slot_count > 0) {
-    array->set(kFirstICSlotIndex,
-               Smi::FromInt(slot_count + index_count + kReservedIndexCount));
-  } else {
-    array->set(kFirstICSlotIndex, Smi::FromInt(length));
-  }
-  array->set(kWithTypesIndex, Smi::FromInt(0));
-  array->set(kGenericCountIndex, Smi::FromInt(0));
-  // Fill the indexes with zeros.
-  for (int i = 0; i < index_count; i++) {
+  array->set(kSlotsCountIndex, Smi::FromInt(slot_count));
+  // Fill the bit-vector part with zeros.
+  for (int i = 0; i < slot_kinds_length; i++) {
     array->set(kReservedIndexCount + i, Smi::FromInt(0));
   }
 
+  Handle<TypeFeedbackMetadata> metadata =
+      Handle<TypeFeedbackMetadata>::cast(array);
+  for (int i = 0; i < slot_count; i++) {
+    metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i));
+  }
+  return metadata;
+}
+
+
+bool TypeFeedbackMetadata::SpecDiffersFrom(
+    const FeedbackVectorSpec* other_spec) const {
+  if (other_spec->slots() != slot_count()) {
+    return true;
+  }
+
+  int slots = slot_count();
+  for (int i = 0; i < slots; i++) {
+    if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) {
+  switch (kind) {
+    case FeedbackVectorSlotKind::INVALID:
+      return "INVALID";
+    case FeedbackVectorSlotKind::CALL_IC:
+      return "CALL_IC";
+    case FeedbackVectorSlotKind::LOAD_IC:
+      return "LOAD_IC";
+    case FeedbackVectorSlotKind::KEYED_LOAD_IC:
+      return "KEYED_LOAD_IC";
+    case FeedbackVectorSlotKind::STORE_IC:
+      return "STORE_IC";
+    case FeedbackVectorSlotKind::KEYED_STORE_IC:
+      return "KEYED_STORE_IC";
+    case FeedbackVectorSlotKind::GENERAL:
+      return "STUB";
+    case FeedbackVectorSlotKind::KINDS_NUMBER:
+      break;
+  }
+  UNREACHABLE();
+  return "?";
+}
+
+
+// static
+Handle<TypeFeedbackVector> TypeFeedbackVector::New(
+    Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) {
+  Factory* factory = isolate->factory();
+
+  const int slot_count = metadata->slot_count();
+  const int length = slot_count + kReservedIndexCount;
+  if (length == kReservedIndexCount) {
+    return Handle<TypeFeedbackVector>::cast(factory->empty_fixed_array());
+  }
+
+  Handle<FixedArray> array = factory->NewFixedArray(length, TENURED);
+  array->set(kMetadataIndex, *metadata);
+
   // Ensure we can skip the write barrier
   Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
-  DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
-  for (int i = kReservedIndexCount + index_count; i < length; i++) {
+  DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel);
+  for (int i = kReservedIndexCount; i < length; i++) {
     array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
   }
 
-  Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array);
-  if (FLAG_vector_ics) {
-    for (int i = 0; i < ic_slot_count; i++) {
-      vector->SetKind(FeedbackVectorICSlot(i), spec.GetKind(i));
-    }
-  }
-  return vector;
+  return Handle<TypeFeedbackVector>::cast(array);
+}
+
+
+// static
+int TypeFeedbackVector::GetIndexFromSpec(const FeedbackVectorSpec* spec,
+                                         FeedbackVectorSlot slot) {
+  return kReservedIndexCount + slot.ToInt();
 }
 
 
@@ -132,81 +171,114 @@
 
 // This logic is copied from
 // StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
-// TODO(mvstanton): with weak handling of all vector ics, this logic should
-// actually be completely eliminated and we no longer need to clear the
-// vector ICs.
-static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind,
-                       InlineCacheState state) {
-  if (FLAG_cleanup_code_caches_at_gc &&
-      (kind == Code::CALL_IC || heap->flush_monomorphic_ics() ||
-       // TODO(mvstanton): is this ic_age granular enough? it comes from
-       // the SharedFunctionInfo which may change on a different schedule
-       // than ic targets.
-       // ic_age != heap->global_ic_age() ||
-       // is_invalidated_weak_stub ||
-       heap->isolate()->serializer_enabled())) {
-    return true;
-  }
-  return false;
+static bool ClearLogic(Isolate* isolate) {
+  return FLAG_cleanup_code_caches_at_gc && isolate->serializer_enabled();
 }
 
 
-void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
-  int slots = Slots();
+void TypeFeedbackVector::ClearSlotsImpl(SharedFunctionInfo* shared,
+                                        bool force_clear) {
   Isolate* isolate = GetIsolate();
+
+  if (!force_clear && !ClearLogic(isolate)) return;
+
   Object* uninitialized_sentinel =
-      TypeFeedbackVector::RawUninitializedSentinel(isolate->heap());
+      TypeFeedbackVector::RawUninitializedSentinel(isolate);
 
-  for (int i = 0; i < slots; i++) {
-    FeedbackVectorSlot slot(i);
-    Object* obj = Get(slot);
-    if (obj->IsHeapObject()) {
-      InstanceType instance_type =
-          HeapObject::cast(obj)->map()->instance_type();
-      // AllocationSites are exempt from clearing. They don't store Maps
-      // or Code pointers which can cause memory leaks if not cleared
-      // regularly.
-      if (instance_type != ALLOCATION_SITE_TYPE) {
-        Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
-      }
-    }
-  }
+  TypeFeedbackMetadataIterator iter(metadata());
+  while (iter.HasNext()) {
+    FeedbackVectorSlot slot = iter.Next();
+    FeedbackVectorSlotKind kind = iter.kind();
 
-  slots = ICSlots();
-  if (slots == 0) return;
-
-  // Now clear vector-based ICs.
-  // Try and pass the containing code (the "host").
-  Heap* heap = isolate->heap();
-  Code* host = shared->code();
-  // I'm not sure yet if this ic age is the correct one.
-  int ic_age = shared->ic_age();
-  for (int i = 0; i < slots; i++) {
-    FeedbackVectorICSlot slot(i);
     Object* obj = Get(slot);
     if (obj != uninitialized_sentinel) {
-      Code::Kind kind = GetKind(slot);
-      if (kind == Code::CALL_IC) {
-        CallICNexus nexus(this, slot);
-        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
-          nexus.Clear(host);
+      switch (kind) {
+        case FeedbackVectorSlotKind::CALL_IC: {
+          CallICNexus nexus(this, slot);
+          nexus.Clear(shared->code());
+          break;
         }
-      } else if (kind == Code::LOAD_IC) {
-        LoadICNexus nexus(this, slot);
-        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
-          nexus.Clear(host);
+        case FeedbackVectorSlotKind::LOAD_IC: {
+          LoadICNexus nexus(this, slot);
+          nexus.Clear(shared->code());
+          break;
         }
-      } else if (kind == Code::KEYED_LOAD_IC) {
-        KeyedLoadICNexus nexus(this, slot);
-        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
-          nexus.Clear(host);
+        case FeedbackVectorSlotKind::KEYED_LOAD_IC: {
+          KeyedLoadICNexus nexus(this, slot);
+          nexus.Clear(shared->code());
+          break;
         }
+        case FeedbackVectorSlotKind::STORE_IC: {
+          StoreICNexus nexus(this, slot);
+          nexus.Clear(shared->code());
+          break;
+        }
+        case FeedbackVectorSlotKind::KEYED_STORE_IC: {
+          KeyedStoreICNexus nexus(this, slot);
+          nexus.Clear(shared->code());
+          break;
+        }
+        case FeedbackVectorSlotKind::GENERAL: {
+          if (obj->IsHeapObject()) {
+            InstanceType instance_type =
+                HeapObject::cast(obj)->map()->instance_type();
+            // AllocationSites are exempt from clearing. They don't store Maps
+            // or Code pointers which can cause memory leaks if not cleared
+            // regularly.
+            if (instance_type != ALLOCATION_SITE_TYPE) {
+              Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
+            }
+          }
+          break;
+        }
+        case FeedbackVectorSlotKind::INVALID:
+        case FeedbackVectorSlotKind::KINDS_NUMBER:
+          UNREACHABLE();
+          break;
       }
     }
   }
 }
 
 
+// static
+void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) {
+  SharedFunctionInfo::Iterator iterator(isolate);
+  SharedFunctionInfo* shared;
+  while ((shared = iterator.Next())) {
+    TypeFeedbackVector* vector = shared->feedback_vector();
+    vector->ClearKeyedStoreICs(shared);
+  }
+}
+
+
+void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) {
+  Isolate* isolate = GetIsolate();
+
+  Code* host = shared->code();
+  Object* uninitialized_sentinel =
+      TypeFeedbackVector::RawUninitializedSentinel(isolate);
+
+  TypeFeedbackMetadataIterator iter(metadata());
+  while (iter.HasNext()) {
+    FeedbackVectorSlot slot = iter.Next();
+    FeedbackVectorSlotKind kind = iter.kind();
+    if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue;
+    Object* obj = Get(slot);
+    if (obj != uninitialized_sentinel) {
+      KeyedStoreICNexus nexus(this, slot);
+      nexus.Clear(host);
+    }
+  }
+}
+
+
+// static
+Handle<TypeFeedbackVector> TypeFeedbackVector::DummyVector(Isolate* isolate) {
+  return isolate->factory()->dummy_vector();
+}
+
+
 Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
   Isolate* isolate = GetIsolate();
   Handle<Object> feedback = handle(GetFeedback(), isolate);
@@ -220,37 +292,74 @@
 }
 
 
-void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
-                                    CodeHandleList* handlers) {
+Handle<FixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
   Isolate* isolate = GetIsolate();
-  Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate);
-  int receiver_count = types->length();
-  for (int current = 0; current < receiver_count; ++current) {
-    Handle<HeapType> type = types->at(current);
-    Handle<Map> map = IC::TypeToMap(*type, isolate);
-    Handle<WeakCell> cell = Map::WeakCellForMap(map);
-    array->set(start_index + (current * 2), *cell);
-    array->set(start_index + (current * 2 + 1), *handlers->at(current));
+  Handle<Object> feedback_extra = handle(GetFeedbackExtra(), isolate);
+  if (!feedback_extra->IsFixedArray() ||
+      FixedArray::cast(*feedback_extra)->length() != length) {
+    Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
+    SetFeedbackExtra(*array);
+    return array;
   }
+  return Handle<FixedArray>::cast(feedback_extra);
+}
+
+
+void FeedbackNexus::InstallHandlers(Handle<FixedArray> array,
+                                    MapHandleList* maps,
+                                    CodeHandleList* handlers) {
+  int receiver_count = maps->length();
+  for (int current = 0; current < receiver_count; ++current) {
+    Handle<Map> map = maps->at(current);
+    Handle<WeakCell> cell = Map::WeakCellForMap(map);
+    array->set(current * 2, *cell);
+    array->set(current * 2 + 1, *handlers->at(current));
+  }
+}
+
+
+void FeedbackNexus::ConfigureUninitialized() {
+  SetFeedback(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+              SKIP_WRITE_BARRIER);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+                   SKIP_WRITE_BARRIER);
+}
+
+
+void FeedbackNexus::ConfigurePremonomorphic() {
+  SetFeedback(*TypeFeedbackVector::PremonomorphicSentinel(GetIsolate()),
+              SKIP_WRITE_BARRIER);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+                   SKIP_WRITE_BARRIER);
+}
+
+
+void FeedbackNexus::ConfigureMegamorphic() {
+  Isolate* isolate = GetIsolate();
+  SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(isolate),
+              SKIP_WRITE_BARRIER);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
+                   SKIP_WRITE_BARRIER);
 }
 
 
 InlineCacheState LoadICNexus::StateFromFeedback() const {
   Isolate* isolate = GetIsolate();
   Object* feedback = GetFeedback();
-  if (feedback == *vector()->UninitializedSentinel(isolate)) {
+
+  if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
     return UNINITIALIZED;
-  } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+  } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
     return MEGAMORPHIC;
-  } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+  } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
     return PREMONOMORPHIC;
   } else if (feedback->IsFixedArray()) {
     // Determine state purely by our structure, don't check if the maps are
     // cleared.
-    FixedArray* array = FixedArray::cast(feedback);
-    int length = array->length();
-    DCHECK(length >= 2);
-    return length == 2 ? MONOMORPHIC : POLYMORPHIC;
+    return POLYMORPHIC;
+  } else if (feedback->IsWeakCell()) {
+    // Don't check if the map is cleared.
+    return MONOMORPHIC;
   }
 
   return UNINITIALIZED;
@@ -260,19 +369,74 @@
 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
   Isolate* isolate = GetIsolate();
   Object* feedback = GetFeedback();
-  if (feedback == *vector()->UninitializedSentinel(isolate)) {
+
+  if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
     return UNINITIALIZED;
-  } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+  } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
     return PREMONOMORPHIC;
-  } else if (feedback == *vector()->GenericSentinel(isolate)) {
-    return GENERIC;
+  } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
+    return MEGAMORPHIC;
   } else if (feedback->IsFixedArray()) {
     // Determine state purely by our structure, don't check if the maps are
     // cleared.
-    FixedArray* array = FixedArray::cast(feedback);
-    int length = array->length();
-    DCHECK(length >= 3);
-    return length == 3 ? MONOMORPHIC : POLYMORPHIC;
+    return POLYMORPHIC;
+  } else if (feedback->IsWeakCell()) {
+    // Don't check if the map is cleared.
+    return MONOMORPHIC;
+  } else if (feedback->IsName()) {
+    Object* extra = GetFeedbackExtra();
+    FixedArray* extra_array = FixedArray::cast(extra);
+    return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
+  }
+
+  return UNINITIALIZED;
+}
+
+
+InlineCacheState StoreICNexus::StateFromFeedback() const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+
+  if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
+    return UNINITIALIZED;
+  } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
+    return MEGAMORPHIC;
+  } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
+    return PREMONOMORPHIC;
+  } else if (feedback->IsFixedArray()) {
+    // Determine state purely by our structure, don't check if the maps are
+    // cleared.
+    return POLYMORPHIC;
+  } else if (feedback->IsWeakCell()) {
+    // Don't check if the map is cleared.
+    return MONOMORPHIC;
+  }
+
+  return UNINITIALIZED;
+}
+
+
+InlineCacheState KeyedStoreICNexus::StateFromFeedback() const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+
+  if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) {
+    return UNINITIALIZED;
+  } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) {
+    return PREMONOMORPHIC;
+  } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
+    return MEGAMORPHIC;
+  } else if (feedback->IsFixedArray()) {
+    // Determine state purely by our structure, don't check if the maps are
+    // cleared.
+    return POLYMORPHIC;
+  } else if (feedback->IsWeakCell()) {
+    // Don't check if the map is cleared.
+    return MONOMORPHIC;
+  } else if (feedback->IsName()) {
+    Object* extra = GetFeedbackExtra();
+    FixedArray* extra_array = FixedArray::cast(extra);
+    return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
   }
 
   return UNINITIALIZED;
@@ -282,26 +446,34 @@
 InlineCacheState CallICNexus::StateFromFeedback() const {
   Isolate* isolate = GetIsolate();
   Object* feedback = GetFeedback();
+  DCHECK(GetFeedbackExtra() ==
+             *TypeFeedbackVector::UninitializedSentinel(isolate) ||
+         GetFeedbackExtra()->IsSmi());
 
-  if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+  if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) {
     return GENERIC;
-  } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
+  } else if (feedback->IsAllocationSite() || feedback->IsWeakCell()) {
     return MONOMORPHIC;
   }
 
-  CHECK(feedback == *vector()->UninitializedSentinel(isolate));
+  CHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate));
   return UNINITIALIZED;
 }
 
 
-void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
-
-
-void CallICNexus::ConfigureGeneric() {
-  SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+int CallICNexus::ExtractCallCount() {
+  Object* call_count = GetFeedbackExtra();
+  if (call_count->IsSmi()) {
+    int value = Smi::cast(call_count)->value() / 2;
+    return value;
+  }
+  return -1;
 }
 
 
+void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
+
+
 void CallICNexus::ConfigureMonomorphicArray() {
   Object* feedback = GetFeedback();
   if (!feedback->IsAllocationSite()) {
@@ -309,100 +481,182 @@
         GetIsolate()->factory()->NewAllocationSite();
     SetFeedback(*new_site);
   }
-}
-
-
-void CallICNexus::ConfigureUninitialized() {
-  SetFeedback(*vector()->UninitializedSentinel(GetIsolate()),
-              SKIP_WRITE_BARRIER);
+  SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER);
 }
 
 
 void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
-  SetFeedback(*function);
+  Handle<WeakCell> new_cell = GetIsolate()->factory()->NewWeakCell(function);
+  SetFeedback(*new_cell);
+  SetFeedbackExtra(Smi::FromInt(kCallCountIncrement), SKIP_WRITE_BARRIER);
 }
 
 
-void KeyedLoadICNexus::ConfigureGeneric() {
-  SetFeedback(*vector()->GenericSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+void CallICNexus::ConfigureMegamorphic() {
+  FeedbackNexus::ConfigureMegamorphic();
 }
 
 
-void LoadICNexus::ConfigureMegamorphic() {
-  SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
-}
-
-
-void LoadICNexus::ConfigurePremonomorphic() {
-  SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
+void CallICNexus::ConfigureMegamorphic(int call_count) {
+  SetFeedback(*TypeFeedbackVector::MegamorphicSentinel(GetIsolate()),
               SKIP_WRITE_BARRIER);
+  SetFeedbackExtra(Smi::FromInt(call_count * kCallCountIncrement),
+                   SKIP_WRITE_BARRIER);
 }
 
 
-void KeyedLoadICNexus::ConfigurePremonomorphic() {
-  SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
-              SKIP_WRITE_BARRIER);
-}
-
-
-void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
+void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
                                        Handle<Code> handler) {
-  Handle<FixedArray> array = EnsureArrayOfSize(2);
-  Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
   Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
-  array->set(0, *cell);
-  array->set(1, *handler);
+  SetFeedback(*cell);
+  SetFeedbackExtra(*handler);
 }
 
 
 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
-                                            Handle<HeapType> type,
+                                            Handle<Map> receiver_map,
                                             Handle<Code> handler) {
-  Handle<FixedArray> array = EnsureArrayOfSize(3);
-  Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
-  if (name.is_null()) {
-    array->set(0, Smi::FromInt(0));
-  } else {
-    array->set(0, *name);
-  }
   Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
-  array->set(1, *cell);
-  array->set(2, *handler);
+  if (name.is_null()) {
+    SetFeedback(*cell);
+    SetFeedbackExtra(*handler);
+  } else {
+    Handle<FixedArray> array = EnsureExtraArrayOfSize(2);
+    SetFeedback(*name);
+    array->set(0, *cell);
+    array->set(1, *handler);
+  }
 }
 
 
-void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types,
+void StoreICNexus::ConfigureMonomorphic(Handle<Map> receiver_map,
+                                        Handle<Code> handler) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+  SetFeedback(*cell);
+  SetFeedbackExtra(*handler);
+}
+
+
+void KeyedStoreICNexus::ConfigureMonomorphic(Handle<Name> name,
+                                             Handle<Map> receiver_map,
+                                             Handle<Code> handler) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+  if (name.is_null()) {
+    SetFeedback(*cell);
+    SetFeedbackExtra(*handler);
+  } else {
+    Handle<FixedArray> array = EnsureExtraArrayOfSize(2);
+    SetFeedback(*name);
+    array->set(0, *cell);
+    array->set(1, *handler);
+  }
+}
+
+
+void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps,
                                        CodeHandleList* handlers) {
-  int receiver_count = types->length();
-  EnsureArrayOfSize(receiver_count * 2);
-  InstallHandlers(0, types, handlers);
+  Isolate* isolate = GetIsolate();
+  int receiver_count = maps->length();
+  Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
+  InstallHandlers(array, maps, handlers);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
+                   SKIP_WRITE_BARRIER);
 }
 
 
 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
-                                            TypeHandleList* types,
+                                            MapHandleList* maps,
                                             CodeHandleList* handlers) {
-  int receiver_count = types->length();
-  Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2);
+  int receiver_count = maps->length();
+  DCHECK(receiver_count > 1);
+  Handle<FixedArray> array;
   if (name.is_null()) {
-    array->set(0, Smi::FromInt(0));
+    array = EnsureArrayOfSize(receiver_count * 2);
+    SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+                     SKIP_WRITE_BARRIER);
   } else {
-    array->set(0, *name);
+    array = EnsureExtraArrayOfSize(receiver_count * 2);
+    SetFeedback(*name);
   }
-  InstallHandlers(1, types, handlers);
+
+  InstallHandlers(array, maps, handlers);
 }
 
 
-int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
+void StoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
+                                        CodeHandleList* handlers) {
+  Isolate* isolate = GetIsolate();
+  int receiver_count = maps->length();
+  Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2);
+  InstallHandlers(array, maps, handlers);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate),
+                   SKIP_WRITE_BARRIER);
+}
+
+
+void KeyedStoreICNexus::ConfigurePolymorphic(Handle<Name> name,
+                                             MapHandleList* maps,
+                                             CodeHandleList* handlers) {
+  int receiver_count = maps->length();
+  DCHECK(receiver_count > 1);
+  Handle<FixedArray> array;
+  if (name.is_null()) {
+    array = EnsureArrayOfSize(receiver_count * 2);
+    SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+                     SKIP_WRITE_BARRIER);
+  } else {
+    array = EnsureExtraArrayOfSize(receiver_count * 2);
+    SetFeedback(*name);
+  }
+
+  InstallHandlers(array, maps, handlers);
+}
+
+
+void KeyedStoreICNexus::ConfigurePolymorphic(MapHandleList* maps,
+                                             MapHandleList* transitioned_maps,
+                                             CodeHandleList* handlers) {
+  int receiver_count = maps->length();
+  DCHECK(receiver_count > 1);
+  Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 3);
+  SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()),
+                   SKIP_WRITE_BARRIER);
+
+  Handle<Oddball> undefined_value = GetIsolate()->factory()->undefined_value();
+  for (int i = 0; i < receiver_count; ++i) {
+    Handle<Map> map = maps->at(i);
+    Handle<WeakCell> cell = Map::WeakCellForMap(map);
+    array->set(i * 3, *cell);
+    if (!transitioned_maps->at(i).is_null()) {
+      Handle<Map> transitioned_map = transitioned_maps->at(i);
+      cell = Map::WeakCellForMap(transitioned_map);
+      array->set((i * 3) + 1, *cell);
+    } else {
+      array->set((i * 3) + 1, *undefined_value);
+    }
+    array->set((i * 3) + 2, *handlers->at(i));
+  }
+}
+
+
+int FeedbackNexus::ExtractMaps(MapHandleList* maps) const {
   Isolate* isolate = GetIsolate();
   Object* feedback = GetFeedback();
-  if (feedback->IsFixedArray()) {
+  bool is_named_feedback = IsPropertyNameFeedback(feedback);
+  if (feedback->IsFixedArray() || is_named_feedback) {
     int found = 0;
+    if (is_named_feedback) {
+      feedback = GetFeedbackExtra();
+    }
     FixedArray* array = FixedArray::cast(feedback);
-    // The array should be of the form [<optional name>], then
-    // [map, handler, map, handler, ... ]
-    DCHECK(array->length() >= (2 + start_index));
-    for (int i = start_index; i < array->length(); i += 2) {
+    // The array should be of the form
+    // [map, handler, map, handler, ...]
+    // or
+    // [map, map, handler, map, map, handler, ...]
+    DCHECK(array->length() >= 2);
+    int increment = array->get(1)->IsCode() ? 2 : 3;
+    for (int i = 0; i < array->length(); i += increment) {
+      DCHECK(array->get(i)->IsWeakCell());
       WeakCell* cell = WeakCell::cast(array->get(i));
       if (!cell->cleared()) {
         Map* map = Map::cast(cell->value());
@@ -411,63 +665,96 @@
       }
     }
     return found;
+  } else if (feedback->IsWeakCell()) {
+    WeakCell* cell = WeakCell::cast(feedback);
+    if (!cell->cleared()) {
+      Map* map = Map::cast(cell->value());
+      maps->Add(handle(map, isolate));
+      return 1;
+    }
   }
 
   return 0;
 }
 
 
-MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index,
-                                                   Handle<Map> map) const {
+MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
   Object* feedback = GetFeedback();
-  if (feedback->IsFixedArray()) {
+  bool is_named_feedback = IsPropertyNameFeedback(feedback);
+  if (feedback->IsFixedArray() || is_named_feedback) {
+    if (is_named_feedback) {
+      feedback = GetFeedbackExtra();
+    }
     FixedArray* array = FixedArray::cast(feedback);
-    for (int i = start_index; i < array->length(); i += 2) {
+    DCHECK(array->length() >= 2);
+    int increment = array->get(1)->IsCode() ? 2 : 3;
+    for (int i = 0; i < array->length(); i += increment) {
+      DCHECK(array->get(i)->IsWeakCell());
       WeakCell* cell = WeakCell::cast(array->get(i));
       if (!cell->cleared()) {
         Map* array_map = Map::cast(cell->value());
         if (array_map == *map) {
-          Code* code = Code::cast(array->get(i + 1));
+          Code* code = Code::cast(array->get(i + increment - 1));
           DCHECK(code->kind() == Code::HANDLER);
           return handle(code);
         }
       }
     }
+  } else if (feedback->IsWeakCell()) {
+    WeakCell* cell = WeakCell::cast(feedback);
+    if (!cell->cleared()) {
+      Map* cell_map = Map::cast(cell->value());
+      if (cell_map == *map) {
+        Code* code = Code::cast(GetFeedbackExtra());
+        DCHECK(code->kind() == Code::HANDLER);
+        return handle(code);
+      }
+    }
   }
 
   return MaybeHandle<Code>();
 }
 
 
-bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
-                                 int length) const {
+bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const {
   Object* feedback = GetFeedback();
   int count = 0;
-  if (feedback->IsFixedArray()) {
+  bool is_named_feedback = IsPropertyNameFeedback(feedback);
+  if (feedback->IsFixedArray() || is_named_feedback) {
+    if (is_named_feedback) {
+      feedback = GetFeedbackExtra();
+    }
     FixedArray* array = FixedArray::cast(feedback);
-    // The array should be of the form [<optional name>], then
-    // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps
-    // have been cleared.
-    DCHECK(array->length() >= (2 + start_index));
-    for (int i = start_index; i < array->length(); i += 2) {
+    // The array should be of the form
+    // [map, handler, map, handler, ...]
+    // or
+    // [map, map, handler, map, map, handler, ...]
+    // Be sure to skip handlers whose maps have been cleared.
+    DCHECK(array->length() >= 2);
+    int increment = array->get(1)->IsCode() ? 2 : 3;
+    for (int i = 0; i < array->length(); i += increment) {
+      DCHECK(array->get(i)->IsWeakCell());
       WeakCell* cell = WeakCell::cast(array->get(i));
       if (!cell->cleared()) {
-        Code* code = Code::cast(array->get(i + 1));
+        Code* code = Code::cast(array->get(i + increment - 1));
         DCHECK(code->kind() == Code::HANDLER);
         code_list->Add(handle(code));
         count++;
       }
     }
+  } else if (feedback->IsWeakCell()) {
+    WeakCell* cell = WeakCell::cast(feedback);
+    if (!cell->cleared()) {
+      Code* code = Code::cast(GetFeedbackExtra());
+      DCHECK(code->kind() == Code::HANDLER);
+      code_list->Add(handle(code));
+      count++;
+    }
   }
   return count == length;
 }
 
 
-int LoadICNexus::ExtractMaps(MapHandleList* maps) const {
-  return FeedbackNexus::ExtractMaps(0, maps);
-}
-
-
 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); }
 
 
@@ -476,41 +763,66 @@
 }
 
 
-int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const {
-  return FeedbackNexus::ExtractMaps(1, maps);
-}
-
-
-MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const {
-  return FeedbackNexus::FindHandlerForMap(0, map);
-}
-
-
-MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const {
-  return FeedbackNexus::FindHandlerForMap(1, map);
-}
-
-
-bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const {
-  return FeedbackNexus::FindHandlers(0, code_list, length);
-}
-
-
-bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list,
-                                    int length) const {
-  return FeedbackNexus::FindHandlers(1, code_list, length);
-}
-
-
 Name* KeyedLoadICNexus::FindFirstName() const {
   Object* feedback = GetFeedback();
-  if (feedback->IsFixedArray()) {
-    FixedArray* array = FixedArray::cast(feedback);
-    DCHECK(array->length() >= 3);
-    Object* name = array->get(0);
-    if (name->IsName()) return Name::cast(name);
+  if (IsPropertyNameFeedback(feedback)) {
+    return Name::cast(feedback);
   }
   return NULL;
 }
+
+
+Name* KeyedStoreICNexus::FindFirstName() const {
+  Object* feedback = GetFeedback();
+  if (IsPropertyNameFeedback(feedback)) {
+    return Name::cast(feedback);
+  }
+  return NULL;
 }
-}  // namespace v8::internal
+
+
+void StoreICNexus::Clear(Code* host) {
+  StoreIC::Clear(GetIsolate(), host, this);
+}
+
+
+void KeyedStoreICNexus::Clear(Code* host) {
+  KeyedStoreIC::Clear(GetIsolate(), host, this);
+}
+
+
+KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const {
+  KeyedAccessStoreMode mode = STANDARD_STORE;
+  MapHandleList maps;
+  CodeHandleList handlers;
+
+  if (GetKeyType() == PROPERTY) return mode;
+
+  ExtractMaps(&maps);
+  FindHandlers(&handlers, maps.length());
+  for (int i = 0; i < handlers.length(); i++) {
+    // The first handler that isn't the slow handler will have the bits we need.
+    Handle<Code> handler = handlers.at(i);
+    CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key());
+    uint32_t minor_key = CodeStub::MinorKeyFromKey(handler->stub_key());
+    CHECK(major_key == CodeStub::KeyedStoreSloppyArguments ||
+          major_key == CodeStub::StoreFastElement ||
+          major_key == CodeStub::StoreElement ||
+          major_key == CodeStub::ElementsTransitionAndStore ||
+          major_key == CodeStub::NoCache);
+    if (major_key != CodeStub::NoCache) {
+      mode = CommonStoreModeBits::decode(minor_key);
+      break;
+    }
+  }
+
+  return mode;
+}
+
+
+IcCheckType KeyedStoreICNexus::GetKeyType() const {
+  // The structure of the vector slots tells us the type.
+  return GetFeedback()->IsName() ? PROPERTY : ELEMENT;
+}
+}  // namespace internal
+}  // namespace v8
