| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/type-feedback-vector.h" | 5 #include "src/type-feedback-vector.h" |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/ic/ic-inl.h" | 8 #include "src/ic/ic-inl.h" |
| 9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( | 33 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( |
| 34 FeedbackVectorSlot slot) const { | 34 FeedbackVectorSlot slot) const { |
| 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 35 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 36 int data = Smi::cast(get(index))->value(); | 36 int data = Smi::cast(get(index))->value(); |
| 37 return VectorICComputer::decode(data, slot.ToInt()); | 37 return VectorICComputer::decode(data, slot.ToInt()); |
| 38 } | 38 } |
| 39 | 39 |
| 40 String* TypeFeedbackMetadata::GetName(FeedbackVectorSlot slot) const { | |
| 41 DCHECK(SlotRequiresName(GetKind(slot))); | |
| 42 UnseededNumberDictionary* names = | |
| 43 UnseededNumberDictionary::cast(get(kNamesTableIndex)); | |
| 44 int entry = names->FindEntry(GetIsolate(), slot.ToInt()); | |
| 45 CHECK_NE(UnseededNumberDictionary::kNotFound, entry); | |
| 46 Object* name = names->ValueAt(entry); | |
| 47 DCHECK(name->IsString()); | |
| 48 return String::cast(name); | |
| 49 } | |
| 50 | |
| 51 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, | 40 void TypeFeedbackMetadata::SetKind(FeedbackVectorSlot slot, |
| 52 FeedbackVectorSlotKind kind) { | 41 FeedbackVectorSlotKind kind) { |
| 53 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 42 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 54 int data = Smi::cast(get(index))->value(); | 43 int data = Smi::cast(get(index))->value(); |
| 55 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); | 44 int new_data = VectorICComputer::encode(data, slot.ToInt(), kind); |
| 56 set(index, Smi::FromInt(new_data)); | 45 set(index, Smi::FromInt(new_data)); |
| 57 } | 46 } |
| 58 | 47 |
| 59 | 48 |
| 60 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( | 49 template Handle<TypeFeedbackMetadata> TypeFeedbackMetadata::New( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 90 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); | 79 Handle<FixedArray> array = factory->NewFixedArray(length, TENURED); |
| 91 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); | 80 array->set(kSlotsCountIndex, Smi::FromInt(slot_count)); |
| 92 // Fill the bit-vector part with zeros. | 81 // Fill the bit-vector part with zeros. |
| 93 for (int i = 0; i < slot_kinds_length; i++) { | 82 for (int i = 0; i < slot_kinds_length; i++) { |
| 94 array->set(kReservedIndexCount + i, Smi::kZero); | 83 array->set(kReservedIndexCount + i, Smi::kZero); |
| 95 } | 84 } |
| 96 | 85 |
| 97 Handle<TypeFeedbackMetadata> metadata = | 86 Handle<TypeFeedbackMetadata> metadata = |
| 98 Handle<TypeFeedbackMetadata>::cast(array); | 87 Handle<TypeFeedbackMetadata>::cast(array); |
| 99 | 88 |
| 100 // Add names to NamesTable. | |
| 101 const int name_count = spec->name_count(); | |
| 102 | |
| 103 Handle<UnseededNumberDictionary> names; | |
| 104 if (name_count) { | |
| 105 names = UnseededNumberDictionary::New(isolate, name_count, TENURED); | |
| 106 } | |
| 107 | |
| 108 int name_index = 0; | |
| 109 for (int i = 0; i < slot_count; i++) { | 89 for (int i = 0; i < slot_count; i++) { |
| 110 FeedbackVectorSlotKind kind = spec->GetKind(i); | 90 FeedbackVectorSlotKind kind = spec->GetKind(i); |
| 111 metadata->SetKind(FeedbackVectorSlot(i), kind); | 91 metadata->SetKind(FeedbackVectorSlot(i), kind); |
| 112 if (SlotRequiresName(kind)) { | |
| 113 Handle<String> name = spec->GetName(name_index); | |
| 114 DCHECK(!name.is_null()); | |
| 115 Handle<UnseededNumberDictionary> new_names = | |
| 116 UnseededNumberDictionary::AtNumberPut(names, i, name); | |
| 117 DCHECK_EQ(*new_names, *names); | |
| 118 names = new_names; | |
| 119 name_index++; | |
| 120 } | |
| 121 } | 92 } |
| 122 DCHECK_EQ(name_count, name_index); | |
| 123 metadata->set(kNamesTableIndex, | |
| 124 name_count ? static_cast<Object*>(*names) : Smi::kZero); | |
| 125 | 93 |
| 126 // It's important that the TypeFeedbackMetadata have a COW map, since it's | 94 // It's important that the TypeFeedbackMetadata have a COW map, since it's |
| 127 // pointed to by both a SharedFunctionInfo and indirectly by closures through | 95 // pointed to by both a SharedFunctionInfo and indirectly by closures through |
| 128 // the TypeFeedbackVector. The serializer uses the COW map type to decide | 96 // the TypeFeedbackVector. The serializer uses the COW map type to decide |
| 129 // this object belongs in the startup snapshot and not the partial | 97 // this object belongs in the startup snapshot and not the partial |
| 130 // snapshot(s). | 98 // snapshot(s). |
| 131 metadata->set_map(isolate->heap()->fixed_cow_array_map()); | 99 metadata->set_map(isolate->heap()->fixed_cow_array_map()); |
| 132 | 100 |
| 133 return metadata; | 101 return metadata; |
| 134 } | 102 } |
| 135 | 103 |
| 136 | 104 |
| 137 bool TypeFeedbackMetadata::SpecDiffersFrom( | 105 bool TypeFeedbackMetadata::SpecDiffersFrom( |
| 138 const FeedbackVectorSpec* other_spec) const { | 106 const FeedbackVectorSpec* other_spec) const { |
| 139 if (other_spec->slots() != slot_count()) { | 107 if (other_spec->slots() != slot_count()) { |
| 140 return true; | 108 return true; |
| 141 } | 109 } |
| 142 | 110 |
| 143 int slots = slot_count(); | 111 int slots = slot_count(); |
| 144 int name_index = 0; | |
| 145 for (int i = 0; i < slots;) { | 112 for (int i = 0; i < slots;) { |
| 146 FeedbackVectorSlot slot(i); | 113 FeedbackVectorSlot slot(i); |
| 147 FeedbackVectorSlotKind kind = GetKind(slot); | 114 FeedbackVectorSlotKind kind = GetKind(slot); |
| 148 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 115 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 149 | 116 |
| 150 if (kind != other_spec->GetKind(i)) { | 117 if (kind != other_spec->GetKind(i)) { |
| 151 return true; | 118 return true; |
| 152 } | 119 } |
| 153 if (SlotRequiresName(kind)) { | |
| 154 String* name = GetName(slot); | |
| 155 DCHECK(name != GetHeap()->empty_string()); | |
| 156 String* other_name = *other_spec->GetName(name_index++); | |
| 157 if (name != other_name) { | |
| 158 return true; | |
| 159 } | |
| 160 } | |
| 161 i += entry_size; | 120 i += entry_size; |
| 162 } | 121 } |
| 163 return false; | 122 return false; |
| 164 } | 123 } |
| 165 | 124 |
| 166 bool TypeFeedbackMetadata::DiffersFrom( | 125 bool TypeFeedbackMetadata::DiffersFrom( |
| 167 const TypeFeedbackMetadata* other_metadata) const { | 126 const TypeFeedbackMetadata* other_metadata) const { |
| 168 if (other_metadata->slot_count() != slot_count()) { | 127 if (other_metadata->slot_count() != slot_count()) { |
| 169 return true; | 128 return true; |
| 170 } | 129 } |
| 171 | 130 |
| 172 int slots = slot_count(); | 131 int slots = slot_count(); |
| 173 for (int i = 0; i < slots;) { | 132 for (int i = 0; i < slots;) { |
| 174 FeedbackVectorSlot slot(i); | 133 FeedbackVectorSlot slot(i); |
| 175 FeedbackVectorSlotKind kind = GetKind(slot); | 134 FeedbackVectorSlotKind kind = GetKind(slot); |
| 176 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); | 135 int entry_size = TypeFeedbackMetadata::GetSlotSize(kind); |
| 177 if (GetKind(slot) != other_metadata->GetKind(slot)) { | 136 if (GetKind(slot) != other_metadata->GetKind(slot)) { |
| 178 return true; | 137 return true; |
| 179 } | 138 } |
| 180 if (SlotRequiresName(kind)) { | |
| 181 if (GetName(slot) != other_metadata->GetName(slot)) { | |
| 182 return true; | |
| 183 } | |
| 184 } | |
| 185 i += entry_size; | 139 i += entry_size; |
| 186 } | 140 } |
| 187 return false; | 141 return false; |
| 188 } | 142 } |
| 189 | 143 |
| 190 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { | 144 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
| 191 switch (kind) { | 145 switch (kind) { |
| 192 case FeedbackVectorSlotKind::INVALID: | 146 case FeedbackVectorSlotKind::INVALID: |
| 193 return "INVALID"; | 147 return "INVALID"; |
| 194 case FeedbackVectorSlotKind::CALL_IC: | 148 case FeedbackVectorSlotKind::CALL_IC: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 215 UNREACHABLE(); | 169 UNREACHABLE(); |
| 216 return "?"; | 170 return "?"; |
| 217 } | 171 } |
| 218 | 172 |
| 219 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( | 173 FeedbackVectorSlotKind TypeFeedbackVector::GetKind( |
| 220 FeedbackVectorSlot slot) const { | 174 FeedbackVectorSlot slot) const { |
| 221 DCHECK(!is_empty()); | 175 DCHECK(!is_empty()); |
| 222 return metadata()->GetKind(slot); | 176 return metadata()->GetKind(slot); |
| 223 } | 177 } |
| 224 | 178 |
| 225 String* TypeFeedbackVector::GetName(FeedbackVectorSlot slot) const { | |
| 226 DCHECK(!is_empty()); | |
| 227 return metadata()->GetName(slot); | |
| 228 } | |
| 229 | |
| 230 // static | 179 // static |
| 231 Handle<TypeFeedbackVector> TypeFeedbackVector::New( | 180 Handle<TypeFeedbackVector> TypeFeedbackVector::New( |
| 232 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { | 181 Isolate* isolate, Handle<TypeFeedbackMetadata> metadata) { |
| 233 Factory* factory = isolate->factory(); | 182 Factory* factory = isolate->factory(); |
| 234 | 183 |
| 235 const int slot_count = metadata->slot_count(); | 184 const int slot_count = metadata->slot_count(); |
| 236 const int length = slot_count + kReservedIndexCount; | 185 const int length = slot_count + kReservedIndexCount; |
| 237 if (length == kReservedIndexCount) { | 186 if (length == kReservedIndexCount) { |
| 238 return Handle<TypeFeedbackVector>::cast( | 187 return Handle<TypeFeedbackVector>::cast( |
| 239 factory->empty_type_feedback_vector()); | 188 factory->empty_type_feedback_vector()); |
| (...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 return BinaryOperationHintFromFeedback(feedback); | 1020 return BinaryOperationHintFromFeedback(feedback); |
| 1072 } | 1021 } |
| 1073 | 1022 |
| 1074 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { | 1023 CompareOperationHint CompareICNexus::GetCompareOperationFeedback() const { |
| 1075 int feedback = Smi::cast(GetFeedback())->value(); | 1024 int feedback = Smi::cast(GetFeedback())->value(); |
| 1076 return CompareOperationHintFromFeedback(feedback); | 1025 return CompareOperationHintFromFeedback(feedback); |
| 1077 } | 1026 } |
| 1078 | 1027 |
| 1079 } // namespace internal | 1028 } // namespace internal |
| 1080 } // namespace v8 | 1029 } // namespace v8 |
| OLD | NEW |