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 |
86 return metadata; | 94 return metadata; |
87 } | 95 } |
88 | 96 |
89 | 97 |
90 bool TypeFeedbackMetadata::SpecDiffersFrom( | 98 bool TypeFeedbackMetadata::SpecDiffersFrom( |
91 const FeedbackVectorSpec* other_spec) const { | 99 const FeedbackVectorSpec* other_spec) const { |
92 if (other_spec->slots() != slot_count()) { | 100 if (other_spec->slots() != slot_count()) { |
93 return true; | 101 return true; |
94 } | 102 } |
95 | 103 |
96 int slots = slot_count(); | 104 int slots = slot_count(); |
97 for (int i = 0; i < slots; i++) { | 105 for (int i = 0; i < slots; i++) { |
98 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { | 106 if (GetKind(FeedbackVectorSlot(i)) != other_spec->GetKind(i)) { |
99 return true; | 107 return true; |
100 } | 108 } |
101 } | 109 } |
102 return false; | 110 return false; |
103 } | 111 } |
104 | 112 |
| 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 } |
105 | 128 |
106 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { | 129 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
107 switch (kind) { | 130 switch (kind) { |
108 case FeedbackVectorSlotKind::INVALID: | 131 case FeedbackVectorSlotKind::INVALID: |
109 return "INVALID"; | 132 return "INVALID"; |
110 case FeedbackVectorSlotKind::CALL_IC: | 133 case FeedbackVectorSlotKind::CALL_IC: |
111 return "CALL_IC"; | 134 return "CALL_IC"; |
112 case FeedbackVectorSlotKind::LOAD_IC: | 135 case FeedbackVectorSlotKind::LOAD_IC: |
113 return "LOAD_IC"; | 136 return "LOAD_IC"; |
114 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 137 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 } | 262 } |
240 } | 263 } |
241 } | 264 } |
242 | 265 |
243 | 266 |
244 // static | 267 // static |
245 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { | 268 void TypeFeedbackVector::ClearAllKeyedStoreICs(Isolate* isolate) { |
246 SharedFunctionInfo::Iterator iterator(isolate); | 269 SharedFunctionInfo::Iterator iterator(isolate); |
247 SharedFunctionInfo* shared; | 270 SharedFunctionInfo* shared; |
248 while ((shared = iterator.Next())) { | 271 while ((shared = iterator.Next())) { |
249 TypeFeedbackVector* vector = shared->feedback_vector(); | 272 if (!shared->OptimizedCodeMapIsCleared()) { |
250 vector->ClearKeyedStoreICs(shared); | 273 FixedArray* optimized_code_map = shared->optimized_code_map(); |
| 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 } |
251 } | 286 } |
252 } | 287 } |
253 | 288 |
254 | 289 |
255 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { | 290 void TypeFeedbackVector::ClearKeyedStoreICs(SharedFunctionInfo* shared) { |
256 Isolate* isolate = GetIsolate(); | 291 Isolate* isolate = GetIsolate(); |
257 | |
258 Code* host = shared->code(); | 292 Code* host = shared->code(); |
259 Object* uninitialized_sentinel = | 293 Object* uninitialized_sentinel = |
260 TypeFeedbackVector::RawUninitializedSentinel(isolate); | 294 TypeFeedbackVector::RawUninitializedSentinel(isolate); |
261 | 295 |
262 TypeFeedbackMetadataIterator iter(metadata()); | 296 TypeFeedbackMetadataIterator iter(metadata()); |
263 while (iter.HasNext()) { | 297 while (iter.HasNext()) { |
264 FeedbackVectorSlot slot = iter.Next(); | 298 FeedbackVectorSlot slot = iter.Next(); |
265 FeedbackVectorSlotKind kind = iter.kind(); | 299 FeedbackVectorSlotKind kind = iter.kind(); |
266 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; | 300 if (kind != FeedbackVectorSlotKind::KEYED_STORE_IC) continue; |
267 Object* obj = Get(slot); | 301 Object* obj = Get(slot); |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 return mode; | 853 return mode; |
820 } | 854 } |
821 | 855 |
822 | 856 |
823 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 857 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
824 // The structure of the vector slots tells us the type. | 858 // The structure of the vector slots tells us the type. |
825 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; | 859 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; |
826 } | 860 } |
827 } // namespace internal | 861 } // namespace internal |
828 } // namespace v8 | 862 } // namespace v8 |
OLD | NEW |