| 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.h" | 8 #include "src/ic/ic.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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 // Fill the bit-vector part with zeros. | 81 // Fill the bit-vector part with zeros. |
| 82 for (int i = 0; i < slot_kinds_length; i++) { | 82 for (int i = 0; i < slot_kinds_length; i++) { |
| 83 array->set(kReservedIndexCount + i, Smi::FromInt(0)); | 83 array->set(kReservedIndexCount + i, Smi::FromInt(0)); |
| 84 } | 84 } |
| 85 | 85 |
| 86 Handle<TypeFeedbackMetadata> metadata = | 86 Handle<TypeFeedbackMetadata> metadata = |
| 87 Handle<TypeFeedbackMetadata>::cast(array); | 87 Handle<TypeFeedbackMetadata>::cast(array); |
| 88 for (int i = 0; i < slot_count; i++) { | 88 for (int i = 0; i < slot_count; i++) { |
| 89 metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); | 89 metadata->SetKind(FeedbackVectorSlot(i), spec->GetKind(i)); |
| 90 } | 90 } |
| 91 |
| 92 // It's important that the TypeFeedbackMetadata have a COW map, since it's |
| 93 // pointed to by both a SharedFunctionInfo and indirectly by closures through |
| 94 // the TypeFeedbackVector. The serializer uses the COW map type to decide |
| 95 // this object belongs in the startup snapshot and not the partial |
| 96 // snapshot(s). |
| 97 metadata->set_map(isolate->heap()->fixed_cow_array_map()); |
| 98 |
| 91 return metadata; | 99 return metadata; |
| 92 } | 100 } |
| 93 | 101 |
| 94 | 102 |
| 95 bool TypeFeedbackMetadata::SpecDiffersFrom( | 103 bool TypeFeedbackMetadata::SpecDiffersFrom( |
| 96 const FeedbackVectorSpec* other_spec) const { | 104 const FeedbackVectorSpec* other_spec) const { |
| 97 if (other_spec->slots() != slot_count()) { | 105 if (other_spec->slots() != slot_count()) { |
| 98 return true; | 106 return true; |
| 99 } | 107 } |
| 100 | 108 |
| 101 int slots = slot_count(); | 109 int slots = slot_count(); |
| 102 for (int i = 0; i < slots; i++) { | 110 for (int i = 0; i < slots; i++) { |
| 103 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { | 111 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
| 104 return true; | 112 return true; |
| 105 } | 113 } |
| 106 } | 114 } |
| 107 return false; | 115 return false; |
| 108 } | 116 } |
| 109 | 117 |
| 118 bool TypeFeedbackMetadata::DiffersFrom( |
| 119 const TypeFeedbackMetadata* other_metadata) const { |
| 120 if (other_metadata->slot_count() != slot_count()) { |
| 121 return true; |
| 122 } |
| 123 |
| 124 int slots = slot_count(); |
| 125 for (int i = 0; i < slots; i++) { |
| 126 FeedbackVectorSlot slot(i); |
| 127 if (GetKind(slot) != other_metadata->GetKind(slot)) { |
| 128 return true; |
| 129 } |
| 130 } |
| 131 return false; |
| 132 } |
| 110 | 133 |
| 111 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { | 134 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
| 112 switch (kind) { | 135 switch (kind) { |
| 113 case FeedbackVectorSlotKind::INVALID: | 136 case FeedbackVectorSlotKind::INVALID: |
| 114 return "INVALID"; | 137 return "INVALID"; |
| 115 case FeedbackVectorSlotKind::CALL_IC: | 138 case FeedbackVectorSlotKind::CALL_IC: |
| 116 return "CALL_IC"; | 139 return "CALL_IC"; |
| 117 case FeedbackVectorSlotKind::LOAD_IC: | 140 case FeedbackVectorSlotKind::LOAD_IC: |
| 118 return "LOAD_IC"; | 141 return "LOAD_IC"; |
| 119 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 142 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 } | 267 } |
| 245 } | 268 } |
| 246 } | 269 } |
| 247 | 270 |
| 248 | 271 |
| 249 // static | 272 // static |
| 250 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { | 273 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { |
| 251 SharedFunctionInfo::Iterator iterator(isolate); | 274 SharedFunctionInfo::Iterator iterator(isolate); |
| 252 SharedFunctionInfo* shared; | 275 SharedFunctionInfo* shared; |
| 253 while ((shared = iterator.Next())) { | 276 while ((shared = iterator.Next())) { |
| 254 TypeFeedbackVector* vector = shared->feedback_vector(); | 277 if (!shared->OptimizedCodeMapIsCleared()) { |
| 255 vector->ClearKeyedStoreICs(shared); | 278 FixedArray* optimized_code_map = shared->optimized_code_map(); |
| 279 int length = optimized_code_map->length(); |
| 280 for (int i = SharedFunctionInfo::kEntriesStart; i < length; |
| 281 i += SharedFunctionInfo::kEntryLength) { |
| 282 WeakCell* cell = WeakCell::cast( |
| 283 optimized_code_map->get(i + SharedFunctionInfo::kLiteralsOffset)); |
| 284 if (cell->value()->IsLiteralsArray()) { |
| 285 TypeFeedbackVector* vector = |
| 286 LiteralsArray::cast(cell->value())->feedback_vector(); |
| 287 vector->ClearKeyedStoreICs(shared); |
| 288 } |
| 289 } |
| 290 } |
| 256 } | 291 } |
| 257 } | 292 } |
| 258 | 293 |
| 259 | 294 |
| 260 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { | 295 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
| 261 Isolate* isolate = GetIsolate(); | 296 Isolate* isolate = GetIsolate(); |
| 262 | 297 |
| 263 Code* host = shared->code(); | 298 Code* host = shared->code(); |
| 264 Object* uninitialized_sentinel = | 299 Object* uninitialized_sentinel = |
| 265 TypeFeedbackVector::RawUninitializedSentinel(isolate); | 300 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 | 888 |
| 854 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 889 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
| 855 Object* feedback = GetFeedback(); | 890 Object* feedback = GetFeedback(); |
| 856 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { | 891 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { |
| 857 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); | 892 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); |
| 858 } | 893 } |
| 859 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; | 894 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; |
| 860 } | 895 } |
| 861 } // namespace internal | 896 } // namespace internal |
| 862 } // namespace v8 | 897 } // namespace v8 |
| OLD | NEW |