Chromium Code Reviews| Index: src/type-feedback-vector.cc |
| diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc |
| index 1984e25315aae146dd68a0f76be842d86a6af098..a3883c7b1b1b7355b041f49cb7981d4c12de4289 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)); |
| + const int kEntrySize = 2; |
| + for (int i = 0; i < names->length(); i += kEntrySize) { |
| + int current_slot = Smi::cast(names->get(i))->value(); |
| + if (current_slot == slot.ToInt()) { |
| + Object* name = names->get(i + 1); |
| + if (!name->IsSmi()) { |
| + return String::cast(name); |
| + } else { |
| + break; |
| + } |
| + } |
| + } |
| + return GetHeap()->empty_string(); |
| +} |
| 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,36 @@ Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New(Isolate* isolate, |
| Handle<TypeFeedbackMetadata> metadata = |
| Handle<TypeFeedbackMetadata>::cast(array); |
| + |
| + // Add names to NamesTable. |
| + const int kEntrySize = 2; |
| + Handle<FixedArray> names = factory->empty_fixed_array(); |
| + |
| + 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); |
| + |
| + // Add entry to names. |
| + int length = names->length(); |
| + if (length < (name_index + 1) * kEntrySize) { |
| + Handle<FixedArray> tmp = |
|
mvstanton
2016/06/24 10:04:11
maybe call this newNames.
Igor Sheludko
2016/06/24 13:30:50
Done.
|
| + factory->NewFixedArray(length == 0 ? 16 : length * 2); |
|
mvstanton
2016/06/24 10:04:12
Did you do anything like figure out average # of g
Igor Sheludko
2016/06/24 13:30:50
Good point! Although we don't waste space in the e
|
| + names->CopyTo(0, *tmp, 0, length); |
| + names = tmp; |
| + } |
| + names->set(name_index * 2, Smi::FromInt(i)); |
| + names->set(name_index * 2 + 1, |
| + !name.is_null() ? Object::cast(*name) : Smi::FromInt(0)); |
| + name_index++; |
| + } |
| + } |
| + if (name_index > 0) { |
| + names->Shrink(name_index * 2); |
| } |
| + 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 +152,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 +181,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 +229,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 +248,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); |