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); |