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