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> |
| 9 |
8 #include "src/checks.h" | 10 #include "src/checks.h" |
9 #include "src/elements-kind.h" | 11 #include "src/elements-kind.h" |
10 #include "src/heap/heap.h" | 12 #include "src/heap/heap.h" |
11 #include "src/isolate.h" | 13 #include "src/isolate.h" |
12 #include "src/objects.h" | 14 #include "src/objects.h" |
13 | 15 |
14 namespace v8 { | 16 namespace v8 { |
15 namespace internal { | 17 namespace internal { |
16 | 18 |
| 19 class FeedbackVectorSpec { |
| 20 public: |
| 21 FeedbackVectorSpec() : slots_(0), ic_slots_(0) {} |
| 22 FeedbackVectorSpec(int slots, int ic_slots) |
| 23 : slots_(slots), ic_slots_(ic_slots) { |
| 24 if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots); |
| 25 } |
| 26 |
| 27 int slots() const { return slots_; } |
| 28 void increase_slots(int count) { slots_ += count; } |
| 29 |
| 30 int ic_slots() const { return ic_slots_; } |
| 31 void increase_ic_slots(int count) { |
| 32 ic_slots_ += count; |
| 33 if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots_); |
| 34 } |
| 35 |
| 36 void SetKind(int ic_slot, Code::Kind kind) { |
| 37 DCHECK(FLAG_vector_ics); |
| 38 ic_slot_kinds_[ic_slot] = kind; |
| 39 } |
| 40 |
| 41 Code::Kind GetKind(int ic_slot) const { |
| 42 DCHECK(FLAG_vector_ics); |
| 43 return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot)); |
| 44 } |
| 45 |
| 46 private: |
| 47 int slots_; |
| 48 int ic_slots_; |
| 49 std::vector<unsigned char> ic_slot_kinds_; |
| 50 }; |
| 51 |
| 52 |
17 // The shape of the TypeFeedbackVector is an array with: | 53 // The shape of the TypeFeedbackVector is an array with: |
18 // 0: first_ic_slot_index (== length() if no ic slots are present) | 54 // 0: first_ic_slot_index (== length() if no ic slots are present) |
19 // 1: ics_with_types | 55 // 1: ics_with_types |
20 // 2: ics_with_generic_info | 56 // 2: ics_with_generic_info |
21 // 3: type information for ic slots, if any | 57 // 3: type information for ic slots, if any |
22 // ... | 58 // ... |
23 // N: first feedback slot (N >= 3) | 59 // N: first feedback slot (N >= 3) |
24 // ... | 60 // ... |
25 // [<first_ic_slot_index>: feedback slot] | 61 // [<first_ic_slot_index>: feedback slot] |
26 // ...to length() - 1 | 62 // ...to length() - 1 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 147 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
112 set(GetIndex(slot), value, mode); | 148 set(GetIndex(slot), value, mode); |
113 } | 149 } |
114 | 150 |
115 Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } | 151 Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } |
116 void Set(FeedbackVectorICSlot slot, Object* value, | 152 void Set(FeedbackVectorICSlot slot, Object* value, |
117 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 153 WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |
118 set(GetIndex(slot), value, mode); | 154 set(GetIndex(slot), value, mode); |
119 } | 155 } |
120 | 156 |
121 // IC slots need metadata to recognize the type of IC. Set a Kind for every | 157 // IC slots need metadata to recognize the type of IC. |
122 // slot. If GetKind() returns Code::NUMBER_OF_KINDS, then there is | |
123 // no kind associated with this slot. This may happen in the current design | |
124 // if a decision is made at compile time not to emit an IC that was planned | |
125 // for at parse time. This can be eliminated if we encode kind at parse | |
126 // time. | |
127 Code::Kind GetKind(FeedbackVectorICSlot slot) const; | 158 Code::Kind GetKind(FeedbackVectorICSlot slot) const; |
128 void SetKind(FeedbackVectorICSlot slot, Code::Kind kind); | |
129 | 159 |
130 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, | 160 static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, |
131 int ic_slot_count); | 161 const FeedbackVectorSpec& spec); |
132 | 162 |
133 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, | 163 static Handle<TypeFeedbackVector> Copy(Isolate* isolate, |
134 Handle<TypeFeedbackVector> vector); | 164 Handle<TypeFeedbackVector> vector); |
135 | 165 |
136 // Clears the vector slots and the vector ic slots. | 166 // Clears the vector slots and the vector ic slots. |
137 void ClearSlots(SharedFunctionInfo* shared); | 167 void ClearSlots(SharedFunctionInfo* shared); |
138 | 168 |
139 // The object that indicates an uninitialized cache. | 169 // The object that indicates an uninitialized cache. |
140 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); | 170 static inline Handle<Object> UninitializedSentinel(Isolate* isolate); |
141 | 171 |
(...skipping 19 matching lines...) Expand all Loading... |
161 enum VectorICKind { | 191 enum VectorICKind { |
162 KindUnused = 0x0, | 192 KindUnused = 0x0, |
163 KindCallIC = 0x1, | 193 KindCallIC = 0x1, |
164 KindLoadIC = 0x2, | 194 KindLoadIC = 0x2, |
165 KindKeyedLoadIC = 0x3 | 195 KindKeyedLoadIC = 0x3 |
166 }; | 196 }; |
167 | 197 |
168 static const int kVectorICKindBits = 2; | 198 static const int kVectorICKindBits = 2; |
169 static VectorICKind FromCodeKind(Code::Kind kind); | 199 static VectorICKind FromCodeKind(Code::Kind kind); |
170 static Code::Kind FromVectorICKind(VectorICKind kind); | 200 static Code::Kind FromVectorICKind(VectorICKind kind); |
| 201 void SetKind(FeedbackVectorICSlot slot, Code::Kind kind); |
| 202 |
171 typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, | 203 typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, |
172 uint32_t> VectorICComputer; | 204 uint32_t> VectorICComputer; |
173 | 205 |
174 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 206 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |
175 }; | 207 }; |
176 | 208 |
177 | 209 |
178 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. | 210 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot. |
179 // Derived classes customize the update and retrieval of feedback. | 211 // Derived classes customize the update and retrieval of feedback. |
180 class FeedbackNexus { | 212 class FeedbackNexus { |
(...skipping 14 matching lines...) Expand all Loading... |
195 FeedbackVectorICSlot slot() const { return slot_; } | 227 FeedbackVectorICSlot slot() const { return slot_; } |
196 | 228 |
197 InlineCacheState ic_state() const { return StateFromFeedback(); } | 229 InlineCacheState ic_state() const { return StateFromFeedback(); } |
198 Map* FindFirstMap() const { | 230 Map* FindFirstMap() const { |
199 MapHandleList maps; | 231 MapHandleList maps; |
200 ExtractMaps(&maps); | 232 ExtractMaps(&maps); |
201 if (maps.length() > 0) return *maps.at(0); | 233 if (maps.length() > 0) return *maps.at(0); |
202 return NULL; | 234 return NULL; |
203 } | 235 } |
204 | 236 |
| 237 // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review. |
| 238 void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); } |
| 239 |
205 virtual InlineCacheState StateFromFeedback() const = 0; | 240 virtual InlineCacheState StateFromFeedback() const = 0; |
206 virtual int ExtractMaps(MapHandleList* maps) const = 0; | 241 virtual int ExtractMaps(MapHandleList* maps) const = 0; |
207 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0; | 242 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0; |
208 virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const { | 243 virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const { |
209 return length == 0; | 244 return length == 0; |
210 } | 245 } |
211 virtual Name* FindFirstName() const { return NULL; } | 246 virtual Name* FindFirstName() const { return NULL; } |
212 | 247 |
213 Object* GetFeedback() const { return vector()->Get(slot()); } | 248 Object* GetFeedback() const { return vector()->Get(slot()); } |
214 | 249 |
(...skipping 28 matching lines...) Expand all Loading... |
243 public: | 278 public: |
244 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) | 279 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) |
245 : FeedbackNexus(vector, slot) { | 280 : FeedbackNexus(vector, slot) { |
246 DCHECK(vector->GetKind(slot) == Code::CALL_IC); | 281 DCHECK(vector->GetKind(slot) == Code::CALL_IC); |
247 } | 282 } |
248 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) | 283 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) |
249 : FeedbackNexus(vector, slot) { | 284 : FeedbackNexus(vector, slot) { |
250 DCHECK(vector->GetKind(slot) == Code::CALL_IC); | 285 DCHECK(vector->GetKind(slot) == Code::CALL_IC); |
251 } | 286 } |
252 | 287 |
| 288 void Clear(Code* host); |
| 289 |
253 void ConfigureUninitialized(); | 290 void ConfigureUninitialized(); |
254 void ConfigureGeneric(); | 291 void ConfigureGeneric(); |
255 void ConfigureMonomorphicArray(); | 292 void ConfigureMonomorphicArray(); |
256 void ConfigureMonomorphic(Handle<JSFunction> function); | 293 void ConfigureMonomorphic(Handle<JSFunction> function); |
257 | 294 |
258 virtual InlineCacheState StateFromFeedback() const OVERRIDE; | 295 virtual InlineCacheState StateFromFeedback() const OVERRIDE; |
259 | 296 |
260 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE { | 297 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE { |
261 // CallICs don't record map feedback. | 298 // CallICs don't record map feedback. |
262 return 0; | 299 return 0; |
263 } | 300 } |
264 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE { | 301 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE { |
265 return MaybeHandle<Code>(); | 302 return MaybeHandle<Code>(); |
266 } | 303 } |
267 virtual bool FindHandlers(CodeHandleList* code_list, | 304 virtual bool FindHandlers(CodeHandleList* code_list, |
268 int length = -1) const OVERRIDE { | 305 int length = -1) const OVERRIDE { |
269 return length == 0; | 306 return length == 0; |
270 } | 307 } |
271 }; | 308 }; |
| 309 |
| 310 |
| 311 class LoadICNexus : public FeedbackNexus { |
| 312 public: |
| 313 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) |
| 314 : FeedbackNexus(vector, slot) { |
| 315 DCHECK(vector->GetKind(slot) == Code::LOAD_IC); |
| 316 } |
| 317 LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) |
| 318 : FeedbackNexus(vector, slot) { |
| 319 DCHECK(vector->GetKind(slot) == Code::LOAD_IC); |
| 320 } |
| 321 |
| 322 void Clear(Code* host); |
| 323 |
| 324 void ConfigureMegamorphic(); |
| 325 void ConfigurePremonomorphic(); |
| 326 void ConfigureMonomorphic(Handle<HeapType> type, Handle<Code> handler); |
| 327 |
| 328 void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers); |
| 329 |
| 330 virtual InlineCacheState StateFromFeedback() const OVERRIDE; |
| 331 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE; |
| 332 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE; |
| 333 virtual bool FindHandlers(CodeHandleList* code_list, |
| 334 int length = -1) const OVERRIDE; |
| 335 }; |
| 336 |
| 337 |
| 338 class KeyedLoadICNexus : public FeedbackNexus { |
| 339 public: |
| 340 KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) |
| 341 : FeedbackNexus(vector, slot) { |
| 342 DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); |
| 343 } |
| 344 KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) |
| 345 : FeedbackNexus(vector, slot) { |
| 346 DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); |
| 347 } |
| 348 |
| 349 void Clear(Code* host); |
| 350 |
| 351 void ConfigureMegamorphic(); |
| 352 void ConfigureGeneric(); |
| 353 void ConfigurePremonomorphic(); |
| 354 // name can be a null handle for element loads. |
| 355 void ConfigureMonomorphic(Handle<Name> name, Handle<HeapType> type, |
| 356 Handle<Code> handler); |
| 357 // name can be null. |
| 358 void ConfigurePolymorphic(Handle<Name> name, TypeHandleList* types, |
| 359 CodeHandleList* handlers); |
| 360 |
| 361 virtual InlineCacheState StateFromFeedback() const OVERRIDE; |
| 362 virtual int ExtractMaps(MapHandleList* maps) const OVERRIDE; |
| 363 virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE; |
| 364 virtual bool FindHandlers(CodeHandleList* code_list, |
| 365 int length = -1) const OVERRIDE; |
| 366 virtual Name* FindFirstName() const OVERRIDE; |
| 367 }; |
272 } | 368 } |
273 } // namespace v8::internal | 369 } // namespace v8::internal |
274 | 370 |
275 #endif // V8_TRANSITIONS_H_ | 371 #endif // V8_TRANSITIONS_H_ |
OLD | NEW |