| Index: src/type-feedback-vector.cc | 
| diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc | 
| index 1984e25315aae146dd68a0f76be842d86a6af098..bc2f1c288bce149d7c9bb705fe74a714d5a07671 100644 | 
| --- a/src/type-feedback-vector.cc | 
| +++ b/src/type-feedback-vector.cc | 
| @@ -37,6 +37,23 @@ FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( | 
| return VectorICComputer::decode(data, slot.ToInt()); | 
| } | 
|  | 
| +String* TypeFeedbackMetadata::GetName(FeedbackVectorSlot slot) const { | 
| +  DCHECK(SlotRequiresName(GetKind(slot))); | 
| +  FixedArray* names = FixedArray::cast(get(kNamesTableIndex)); | 
| +  // TODO(ishell): consider using binary search here or even Dictionary when we | 
| +  // have more ICs with names. | 
| +  Smi* key = Smi::FromInt(slot.ToInt()); | 
| +  for (int entry = 0; entry < names->length(); entry += kNameTableEntrySize) { | 
| +    Object* current_key = names->get(entry + kNameTableSlotIndex); | 
| +    if (current_key == key) { | 
| +      Object* name = names->get(entry + kNameTableNameIndex); | 
| +      DCHECK(name->IsString()); | 
| +      return String::cast(name); | 
| +    } | 
| +  } | 
| +  UNREACHABLE(); | 
| +  return nullptr; | 
| +} | 
|  | 
| void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, | 
| FeedbackVectorSlotKind kind) { | 
| @@ -57,12 +74,13 @@ template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( | 
| template <typename Spec> | 
| Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, | 
| const Spec* spec) { | 
| +  Factory* factory = isolate->factory(); | 
| + | 
| 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<TypeFeedbackMetadata>::cast( | 
| -        isolate->factory()->empty_fixed_array()); | 
| +    return Handle<TypeFeedbackMetadata>::cast(factory->empty_fixed_array()); | 
| } | 
| #ifdef DEBUG | 
| for (int i = 0; i < slot_count;) { | 
| @@ -76,7 +94,7 @@ Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, | 
| } | 
| #endif | 
|  | 
| -  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED); | 
| +  Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); | 
| array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); | 
| // Fill the bit-vector part with zeros. | 
| for (int i = 0; i < slot_kinds_length; i++) { | 
| @@ -85,9 +103,29 @@ Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, | 
|  | 
| Handle<TypeFeedbackMetadata> metadata = | 
| Handle<TypeFeedbackMetadata>::cast(array); | 
| + | 
| +  // Add names to NamesTable. | 
| +  const int name_count = spec->name_count(); | 
| + | 
| +  Handle<FixedArray> names = | 
| +      name_count == 0 | 
| +          ? factory->empty_fixed_array() | 
| +          : factory->NewFixedArray(name_count * kNameTableEntrySize); | 
| +  int name_index = 0; | 
| for (int i = 0; i < slot_count; i++) { | 
| -    metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); | 
| +    FeedbackVectorSlotKind kind = spec->GetKind(i); | 
| +    metadata->SetKind(FeedbackVectorSlot(i), kind); | 
| +    if (SlotRequiresName(kind)) { | 
| +      Handle<String> name = spec->GetName(name_index); | 
| +      DCHECK(!name.is_null()); | 
| +      int entry = name_index * kNameTableEntrySize; | 
| +      names->set(entry + kNameTableSlotIndex, Smi::FromInt(i)); | 
| +      names->set(entry + kNameTableNameIndex, *name); | 
| +      name_index++; | 
| +    } | 
| } | 
| +  DCHECK_EQ(name_count, name_index); | 
| +  metadata->set(kNamesTableIndex, *names); | 
|  | 
| // It's important that the TypeFeedbackMetadata have a COW map, since it's | 
| // pointed to by both a SharedFunctionInfo and indirectly by closures through | 
| @@ -107,10 +145,24 @@ bool TypeFeedbackMetadata::SpecDiffersFrom( | 
| } | 
|  | 
| int slots = slot_count(); | 
| -  for (int i = 0; i < slots; i++) { | 
| -    if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { | 
| +  int name_index = 0; | 
| +  for (int i = 0; i < slots;) { | 
| +    FeedbackVectorSlot slot(i); | 
| +    FeedbackVectorSlotKind kind = GetKind(slot); | 
| +    int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 
| + | 
| +    if (kind != other_spec->GetKind(i)) { | 
| return true; | 
| } | 
| +    if (SlotRequiresName(kind)) { | 
| +      String* name = GetName(slot); | 
| +      DCHECK(name != GetHeap()->empty_string()); | 
| +      String* other_name = *other_spec->GetName(name_index++); | 
| +      if (name != other_name) { | 
| +        return true; | 
| +      } | 
| +    } | 
| +    i += entry_size; | 
| } | 
| return false; | 
| } | 
| @@ -122,11 +174,19 @@ bool TypeFeedbackMetadata::DiffersFrom( | 
| } | 
|  | 
| int slots = slot_count(); | 
| -  for (int i = 0; i < slots; i++) { | 
| +  for (int i = 0; i < slots;) { | 
| FeedbackVectorSlot slot(i); | 
| +    FeedbackVectorSlotKind kind = GetKind(slot); | 
| +    int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 
| if (GetKind(slot) != other_metadata->GetKind(slot)) { | 
| return true; | 
| } | 
| +    if (SlotRequiresName(kind)) { | 
| +      if (GetName(slot) != other_metadata->GetName(slot)) { | 
| +        return true; | 
| +      } | 
| +    } | 
| +    i += entry_size; | 
| } | 
| return false; | 
| } | 
| @@ -162,6 +222,11 @@ FeedbackVectorSlotKind TypeFeedbackVector::GetKind( | 
| return metadata()->GetKind(slot); | 
| } | 
|  | 
| +String* TypeFeedbackVector::GetName(FeedbackVectorSlot slot) const { | 
| +  DCHECK(!is_empty()); | 
| +  return metadata()->GetName(slot); | 
| +} | 
| + | 
| // static | 
| Handle<TypeFeedbackVector> TypeFeedbackVector::New( | 
| Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { | 
| @@ -176,6 +241,8 @@ Handle<TypeFeedbackVector> TypeFeedbackVector::New( | 
| Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); | 
| array->set(kMetadataIndex, *metadata); | 
|  | 
| +  DisallowHeapAllocation no_gc; | 
| + | 
| // Ensure we can skip the write barrier | 
| Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate); | 
| DCHECK_EQ(*factory->uninitialized_symbol(), *uninitialized_sentinel); | 
|  |