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