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 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ | 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ |
6 #define V8_TYPE_FEEDBACK_VECTOR_H_ | 6 #define V8_TYPE_FEEDBACK_VECTOR_H_ |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "src/checks.h" | 10 #include "src/checks.h" |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 friend class FeedbackVectorSpecBase<FeedbackVectorSpec>; | 114 friend class FeedbackVectorSpecBase<FeedbackVectorSpec>; |
115 | 115 |
116 void append(FeedbackVectorSlotKind kind) { | 116 void append(FeedbackVectorSlotKind kind) { |
117 slot_kinds_.push_back(static_cast<unsigned char>(kind)); | 117 slot_kinds_.push_back(static_cast<unsigned char>(kind)); |
118 } | 118 } |
119 | 119 |
120 ZoneVector<unsigned char> slot_kinds_; | 120 ZoneVector<unsigned char> slot_kinds_; |
121 }; | 121 }; |
122 | 122 |
123 | 123 |
| 124 // The shape of the TypeFeedbackMetadata is an array with: |
| 125 // 0: slot_count |
| 126 // 1..N: slot kinds packed into a bit vector |
| 127 // |
| 128 class TypeFeedbackMetadata : public FixedArray { |
| 129 public: |
| 130 // Casting. |
| 131 static inline TypeFeedbackMetadata* cast(Object* obj); |
| 132 |
| 133 static const int kSlotsCountIndex = 0; |
| 134 static const int kReservedIndexCount = 1; |
| 135 |
| 136 // Returns number of feedback vector elements used by given slot kind. |
| 137 static inline int GetSlotSize(FeedbackVectorSlotKind kind); |
| 138 |
| 139 bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const; |
| 140 |
| 141 // Returns number of slots in the vector. |
| 142 inline int slot_count() const; |
| 143 |
| 144 // Returns slot kind for given slot. |
| 145 FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const; |
| 146 |
| 147 template <typename Spec> |
| 148 static Handle<TypeFeedbackMetadata> New(Isolate* isolate, const Spec* spec); |
| 149 |
| 150 #ifdef OBJECT_PRINT |
| 151 // For gdb debugging. |
| 152 void Print(); |
| 153 #endif // OBJECT_PRINT |
| 154 |
| 155 DECLARE_PRINTER(TypeFeedbackMetadata) |
| 156 |
| 157 static const char* Kind2String(FeedbackVectorSlotKind kind); |
| 158 |
| 159 private: |
| 160 static const int kFeedbackVectorSlotKindBits = 3; |
| 161 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) < |
| 162 (1 << kFeedbackVectorSlotKindBits)); |
| 163 |
| 164 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind); |
| 165 |
| 166 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits, |
| 167 kSmiValueSize, uint32_t> VectorICComputer; |
| 168 |
| 169 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata); |
| 170 }; |
| 171 |
| 172 |
124 // The shape of the TypeFeedbackVector is an array with: | 173 // The shape of the TypeFeedbackVector is an array with: |
125 // 0: slot_count | 174 // 0: feedback metadata |
126 // 1: ics_with_types | 175 // 1: ics_with_types |
127 // 2: ics_with_generic_info | 176 // 2: ics_with_generic_info |
128 // 3: slots metadata (a bit vector of slot kinds) | 177 // 3: feedback slot #0 (N >= 3) |
129 // ... | |
130 // N: feedback slot #0 (N >= 3) | |
131 // ... | 178 // ... |
132 // N + slot_count - 1: feedback slot #(slot_count-1) | 179 // N + slot_count - 1: feedback slot #(slot_count-1) |
133 // | 180 // |
134 class TypeFeedbackVector : public FixedArray { | 181 class TypeFeedbackVector : public FixedArray { |
135 public: | 182 public: |
136 // Casting. | 183 // Casting. |
137 static inline TypeFeedbackVector* cast(Object* obj); | 184 static inline TypeFeedbackVector* cast(Object* obj); |
138 | 185 |
139 static const int kSlotsCountIndex = 0; | 186 static const int kMetadataIndex = 0; |
140 static const int kWithTypesIndex = 1; | 187 static const int kWithTypesIndex = 1; |
141 static const int kGenericCountIndex = 2; | 188 static const int kGenericCountIndex = 2; |
142 static const int kReservedIndexCount = 3; | 189 static const int kReservedIndexCount = 3; |
143 | 190 |
144 // Returns number of feedback vector elements used by given slot kind. | |
145 static inline int GetSlotSize(FeedbackVectorSlotKind kind); | |
146 | |
147 inline int ic_with_type_info_count(); | 191 inline int ic_with_type_info_count(); |
148 inline void change_ic_with_type_info_count(int delta); | 192 inline void change_ic_with_type_info_count(int delta); |
149 inline int ic_generic_count(); | 193 inline int ic_generic_count(); |
150 inline void change_ic_generic_count(int delta); | 194 inline void change_ic_generic_count(int delta); |
151 inline int ic_metadata_length() const; | |
152 | |
153 bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const; | |
154 | 195 |
155 inline bool is_empty() const; | 196 inline bool is_empty() const; |
156 | 197 |
157 // Returns number of slots in the vector. | 198 // Returns number of slots in the vector. |
158 inline int Slots() const; | 199 inline int slot_count() const; |
| 200 |
| 201 inline TypeFeedbackMetadata* metadata() const; |
159 | 202 |
160 // Conversion from a slot to an integer index to the underlying array. | 203 // Conversion from a slot to an integer index to the underlying array. |
161 inline int GetIndex(FeedbackVectorSlot slot) const; | 204 inline int GetIndex(FeedbackVectorSlot slot) const; |
162 static int GetIndexFromSpec(const FeedbackVectorSpec* spec, | 205 static int GetIndexFromSpec(const FeedbackVectorSpec* spec, |
163 FeedbackVectorSlot slot); | 206 FeedbackVectorSlot slot); |
164 | 207 |
165 // Conversion from an integer index to the underlying array to a slot. | 208 // Conversion from an integer index to the underlying array to a slot. |
166 inline FeedbackVectorSlot ToSlot(int index) const; | 209 inline FeedbackVectorSlot ToSlot(int index) const; |
167 inline Object* Get(FeedbackVectorSlot slot) const; | 210 inline Object* Get(FeedbackVectorSlot slot) const; |
168 inline void Set(FeedbackVectorSlot slot, Object* value, | 211 inline void Set(FeedbackVectorSlot slot, Object* value, |
169 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 212 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
170 | 213 |
171 // Returns slot kind for given slot. | 214 // Returns slot kind for given slot. |
172 FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const; | 215 inline FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const; |
173 | 216 |
174 template <typename Spec> | 217 static Handle<TypeFeedbackVector> New(Isolate* isolate, |
175 static Handle<TypeFeedbackVector> New(Isolate* isolate, const Spec* spec); | 218 Handle<TypeFeedbackMetadata> metadata); |
176 | 219 |
177 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, | 220 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, |
178 Handle<TypeFeedbackVector> vector); | 221 Handle<TypeFeedbackVector> vector); |
179 | 222 |
180 #ifdef OBJECT_PRINT | 223 #ifdef OBJECT_PRINT |
181 // For gdb debugging. | 224 // For gdb debugging. |
182 void Print(); | 225 void Print(); |
183 #endif // OBJECT_PRINT | 226 #endif // OBJECT_PRINT |
184 | 227 |
185 DECLARE_PRINTER(TypeFeedbackVector) | 228 DECLARE_PRINTER(TypeFeedbackVector) |
(...skipping 29 matching lines...) Expand all Loading... |
215 static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate); | 258 static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate); |
216 static FeedbackVectorSlot DummySlot(int dummyIndex) { | 259 static FeedbackVectorSlot DummySlot(int dummyIndex) { |
217 DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot); | 260 DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot); |
218 return FeedbackVectorSlot(dummyIndex); | 261 return FeedbackVectorSlot(dummyIndex); |
219 } | 262 } |
220 | 263 |
221 static int PushAppliedArgumentsIndex(); | 264 static int PushAppliedArgumentsIndex(); |
222 static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector( | 265 static Handle<TypeFeedbackVector> CreatePushAppliedArgumentsVector( |
223 Isolate* isolate); | 266 Isolate* isolate); |
224 | 267 |
225 static const char* Kind2String(FeedbackVectorSlotKind kind); | |
226 | |
227 private: | 268 private: |
228 static const int kFeedbackVectorSlotKindBits = 3; | |
229 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) < | |
230 (1 << kFeedbackVectorSlotKindBits)); | |
231 | |
232 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind); | |
233 | |
234 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits, | |
235 kSmiValueSize, uint32_t> VectorICComputer; | |
236 | |
237 void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear); | 269 void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear); |
238 | 270 |
239 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 271 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |
240 }; | 272 }; |
241 | 273 |
242 | 274 |
243 // The following asserts protect an optimization in type feedback vector | 275 // The following asserts protect an optimization in type feedback vector |
244 // code that looks into the contents of a slot assuming to find a String, | 276 // code that looks into the contents of a slot assuming to find a String, |
245 // a Symbol, an AllocationSite, a WeakCell, or a FixedArray. | 277 // a Symbol, an AllocationSite, a WeakCell, or a FixedArray. |
246 STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize); | 278 STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize); |
247 STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset); | 279 STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset); |
248 STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset); | 280 STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset); |
249 STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot); | 281 STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot); |
250 // Verify that an empty hash field looks like a tagged object, but can't | 282 // Verify that an empty hash field looks like a tagged object, but can't |
251 // possibly be confused with a pointer. | 283 // possibly be confused with a pointer. |
252 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag); | 284 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag); |
253 STATIC_ASSERT(Name::kEmptyHashField == 0x3); | 285 STATIC_ASSERT(Name::kEmptyHashField == 0x3); |
254 // Verify that a set hash field will not look like a tagged object. | 286 // Verify that a set hash field will not look like a tagged object. |
255 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag); | 287 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag); |
256 | 288 |
257 | 289 |
258 class TypeFeedbackMetadataIterator { | 290 class TypeFeedbackMetadataIterator { |
259 public: | 291 public: |
260 explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackVector> metadata) | 292 explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata) |
261 : metadata_handle_(metadata), | 293 : metadata_handle_(metadata), |
262 slot_(FeedbackVectorSlot(0)), | 294 slot_(FeedbackVectorSlot(0)), |
263 slot_kind_(FeedbackVectorSlotKind::INVALID) {} | 295 slot_kind_(FeedbackVectorSlotKind::INVALID) {} |
264 | 296 |
265 explicit TypeFeedbackMetadataIterator(TypeFeedbackVector* metadata) | 297 explicit TypeFeedbackMetadataIterator(TypeFeedbackMetadata* metadata) |
266 : metadata_(metadata), | 298 : metadata_(metadata), |
267 slot_(FeedbackVectorSlot(0)), | 299 slot_(FeedbackVectorSlot(0)), |
268 slot_kind_(FeedbackVectorSlotKind::INVALID) {} | 300 slot_kind_(FeedbackVectorSlotKind::INVALID) {} |
269 | 301 |
270 bool HasNext() const { return slot_.ToInt() < metadata()->Slots(); } | 302 bool HasNext() const { return slot_.ToInt() < metadata()->slot_count(); } |
271 | 303 |
272 FeedbackVectorSlot Next() { | 304 FeedbackVectorSlot Next() { |
273 DCHECK(HasNext()); | 305 DCHECK(HasNext()); |
274 FeedbackVectorSlot slot = slot_; | 306 FeedbackVectorSlot slot = slot_; |
275 slot_kind_ = metadata()->GetKind(slot); | 307 slot_kind_ = metadata()->GetKind(slot); |
276 slot_ = FeedbackVectorSlot(slot_.ToInt() + entry_size()); | 308 slot_ = FeedbackVectorSlot(slot_.ToInt() + entry_size()); |
277 return slot; | 309 return slot; |
278 } | 310 } |
279 | 311 |
280 // Returns slot kind of the last slot returned by Next(). | 312 // Returns slot kind of the last slot returned by Next(). |
281 FeedbackVectorSlotKind kind() const { | 313 FeedbackVectorSlotKind kind() const { |
282 DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_); | 314 DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_); |
283 DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_); | 315 DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_); |
284 return slot_kind_; | 316 return slot_kind_; |
285 } | 317 } |
286 | 318 |
287 // Returns entry size of the last slot returned by Next(). | 319 // Returns entry size of the last slot returned by Next(). |
288 int entry_size() const { return TypeFeedbackVector::GetSlotSize(kind()); } | 320 int entry_size() const { return TypeFeedbackMetadata::GetSlotSize(kind()); } |
289 | 321 |
290 private: | 322 private: |
291 TypeFeedbackVector* metadata() const { | 323 TypeFeedbackMetadata* metadata() const { |
292 return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_; | 324 return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_; |
293 } | 325 } |
294 | 326 |
295 // The reason for having a handle and a raw pointer to the meta data is | 327 // The reason for having a handle and a raw pointer to the meta data is |
296 // to have a single iterator implementation for both "handlified" and raw | 328 // to have a single iterator implementation for both "handlified" and raw |
297 // pointer use cases. | 329 // pointer use cases. |
298 Handle<TypeFeedbackVector> metadata_handle_; | 330 Handle<TypeFeedbackMetadata> metadata_handle_; |
299 TypeFeedbackVector* metadata_; | 331 TypeFeedbackMetadata* metadata_; |
300 FeedbackVectorSlot slot_; | 332 FeedbackVectorSlot slot_; |
301 FeedbackVectorSlotKind slot_kind_; | 333 FeedbackVectorSlotKind slot_kind_; |
302 }; | 334 }; |
303 | 335 |
304 | 336 |
305 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. | 337 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. |
306 // Derived classes customize the update and retrieval of feedback. | 338 // Derived classes customize the update and retrieval of feedback. |
307 class FeedbackNexus { | 339 class FeedbackNexus { |
308 public: | 340 public: |
309 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) | 341 FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 KeyedAccessStoreMode GetKeyedAccessStoreMode() const; | 543 KeyedAccessStoreMode GetKeyedAccessStoreMode() const; |
512 IcCheckType GetKeyType() const; | 544 IcCheckType GetKeyType() const; |
513 | 545 |
514 InlineCacheState StateFromFeedback() const override; | 546 InlineCacheState StateFromFeedback() const override; |
515 Name* FindFirstName() const override; | 547 Name* FindFirstName() const override; |
516 }; | 548 }; |
517 } // namespace internal | 549 } // namespace internal |
518 } // namespace v8 | 550 } // namespace v8 |
519 | 551 |
520 #endif // V8_TRANSITIONS_H_ | 552 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |