• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_
6 #define V8_TYPE_FEEDBACK_VECTOR_H_
7 
8 #include <vector>
9 
10 #include "src/base/logging.h"
11 #include "src/elements-kind.h"
12 #include "src/objects.h"
13 #include "src/zone-containers.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 enum class FeedbackVectorSlotKind {
19   // This kind means that the slot points to the middle of other slot
20   // which occupies more than one feedback vector element.
21   // There must be no such slots in the system.
22   INVALID,
23 
24   CALL_IC,
25   LOAD_IC,
26   LOAD_GLOBAL_IC,
27   KEYED_LOAD_IC,
28   STORE_IC,
29   KEYED_STORE_IC,
30 
31   // This is a general purpose slot that occupies one feedback vector element.
32   GENERAL,
33 
34   KINDS_NUMBER  // Last value indicating number of kinds.
35 };
36 
37 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
38 
39 
40 template <typename Derived>
41 class FeedbackVectorSpecBase {
42  public:
43   inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind);
44 
AddCallICSlot()45   FeedbackVectorSlot AddCallICSlot() {
46     return AddSlot(FeedbackVectorSlotKind::CALL_IC);
47   }
48 
AddLoadICSlot()49   FeedbackVectorSlot AddLoadICSlot() {
50     return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
51   }
52 
AddLoadGlobalICSlot(Handle<String> name)53   FeedbackVectorSlot AddLoadGlobalICSlot(Handle<String> name) {
54     This()->append_name(name);
55     return AddSlot(FeedbackVectorSlotKind::LOAD_GLOBAL_IC);
56   }
57 
AddKeyedLoadICSlot()58   FeedbackVectorSlot AddKeyedLoadICSlot() {
59     return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
60   }
61 
AddStoreICSlot()62   FeedbackVectorSlot AddStoreICSlot() {
63     return AddSlot(FeedbackVectorSlotKind::STORE_IC);
64   }
65 
AddKeyedStoreICSlot()66   FeedbackVectorSlot AddKeyedStoreICSlot() {
67     return AddSlot(FeedbackVectorSlotKind::KEYED_STORE_IC);
68   }
69 
AddGeneralSlot()70   FeedbackVectorSlot AddGeneralSlot() {
71     return AddSlot(FeedbackVectorSlotKind::GENERAL);
72   }
73 
74 #ifdef OBJECT_PRINT
75   // For gdb debugging.
76   void Print();
77 #endif  // OBJECT_PRINT
78 
DECLARE_PRINTER(FeedbackVectorSpec)79   DECLARE_PRINTER(FeedbackVectorSpec)
80 
81  private:
82   Derived* This() { return static_cast<Derived*>(this); }
83 };
84 
85 
86 class StaticFeedbackVectorSpec
87     : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
88  public:
StaticFeedbackVectorSpec()89   StaticFeedbackVectorSpec() : slot_count_(0), name_count_(0) {}
90 
slots()91   int slots() const { return slot_count_; }
92 
GetKind(int slot)93   FeedbackVectorSlotKind GetKind(int slot) const {
94     DCHECK(slot >= 0 && slot < slot_count_);
95     return kinds_[slot];
96   }
97 
name_count()98   int name_count() const { return name_count_; }
99 
GetName(int index)100   Handle<String> GetName(int index) const {
101     DCHECK(index >= 0 && index < name_count_);
102     return names_[index];
103   }
104 
105  private:
106   friend class FeedbackVectorSpecBase<StaticFeedbackVectorSpec>;
107 
append(FeedbackVectorSlotKind kind)108   void append(FeedbackVectorSlotKind kind) {
109     DCHECK(slot_count_ < kMaxLength);
110     kinds_[slot_count_++] = kind;
111   }
112 
append_name(Handle<String> name)113   void append_name(Handle<String> name) {
114     DCHECK(name_count_ < kMaxLength);
115     names_[name_count_++] = name;
116   }
117 
118   static const int kMaxLength = 12;
119 
120   int slot_count_;
121   FeedbackVectorSlotKind kinds_[kMaxLength];
122   int name_count_;
123   Handle<String> names_[kMaxLength];
124 };
125 
126 
127 class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
128  public:
FeedbackVectorSpec(Zone * zone)129   explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone), names_(zone) {
130     slot_kinds_.reserve(16);
131     names_.reserve(8);
132   }
133 
slots()134   int slots() const { return static_cast<int>(slot_kinds_.size()); }
135 
GetKind(int slot)136   FeedbackVectorSlotKind GetKind(int slot) const {
137     return static_cast<FeedbackVectorSlotKind>(slot_kinds_.at(slot));
138   }
139 
name_count()140   int name_count() const { return static_cast<int>(names_.size()); }
141 
GetName(int index)142   Handle<String> GetName(int index) const { return names_.at(index); }
143 
144  private:
145   friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
146 
append(FeedbackVectorSlotKind kind)147   void append(FeedbackVectorSlotKind kind) {
148     slot_kinds_.push_back(static_cast<unsigned char>(kind));
149   }
150 
append_name(Handle<String> name)151   void append_name(Handle<String> name) { names_.push_back(name); }
152 
153   ZoneVector<unsigned char> slot_kinds_;
154   ZoneVector<Handle<String>> names_;
155 };
156 
157 
158 // The shape of the TypeFeedbackMetadata is an array with:
159 // 0: slot_count
160 // 1: names table
161 // 2..N: slot kinds packed into a bit vector
162 //
163 class TypeFeedbackMetadata : public FixedArray {
164  public:
165   // Casting.
166   static inline TypeFeedbackMetadata* cast(Object* obj);
167 
168   static const int kSlotsCountIndex = 0;
169   static const int kNamesTableIndex = 1;
170   static const int kReservedIndexCount = 2;
171 
172   static const int kNameTableEntrySize = 2;
173   static const int kNameTableSlotIndex = 0;
174   static const int kNameTableNameIndex = 1;
175 
176   // Returns number of feedback vector elements used by given slot kind.
177   static inline int GetSlotSize(FeedbackVectorSlotKind kind);
178 
179   // Defines if slots of given kind require "name".
180   static inline bool SlotRequiresName(FeedbackVectorSlotKind kind);
181 
182   bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
183 
184   bool DiffersFrom(const TypeFeedbackMetadata* other_metadata) const;
185 
186   inline bool is_empty() const;
187 
188   // Returns number of slots in the vector.
189   inline int slot_count() const;
190 
191   // Returns slot kind for given slot.
192   FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
193 
194   // Returns name for given slot.
195   String* GetName(FeedbackVectorSlot slot) const;
196 
197   template <typename Spec>
198   static Handle<TypeFeedbackMetadata> New(Isolate* isolate, const Spec* spec);
199 
200 #ifdef OBJECT_PRINT
201   // For gdb debugging.
202   void Print();
203 #endif  // OBJECT_PRINT
204 
205   DECLARE_PRINTER(TypeFeedbackMetadata)
206 
207   static const char* Kind2String(FeedbackVectorSlotKind kind);
208 
209  private:
210   static const int kFeedbackVectorSlotKindBits = 4;
211   STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) <
212                 (1 << kFeedbackVectorSlotKindBits));
213 
214   void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind);
215 
216   typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits,
217                          kSmiValueSize, uint32_t> VectorICComputer;
218 
219   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata);
220 };
221 
222 
223 // The shape of the TypeFeedbackVector is an array with:
224 // 0: feedback metadata
225 // 1: ics_with_types
226 // 2: ics_with_generic_info
227 // 3: feedback slot #0
228 // ...
229 // 3 + slot_count - 1: feedback slot #(slot_count-1)
230 //
231 class TypeFeedbackVector : public FixedArray {
232  public:
233   // Casting.
234   static inline TypeFeedbackVector* cast(Object* obj);
235 
236   static const int kMetadataIndex = 0;
237   static const int kReservedIndexCount = 1;
238 
239   inline void ComputeCounts(int* with_type_info, int* generic);
240 
241   inline bool is_empty() const;
242 
243   // Returns number of slots in the vector.
244   inline int slot_count() const;
245 
246   inline TypeFeedbackMetadata* metadata() const;
247 
248   // Conversion from a slot to an integer index to the underlying array.
GetIndex(FeedbackVectorSlot slot)249   static int GetIndex(FeedbackVectorSlot slot) {
250     return kReservedIndexCount + slot.ToInt();
251   }
252   static int GetIndexFromSpec(const FeedbackVectorSpec* spec,
253                               FeedbackVectorSlot slot);
254 
255   // Conversion from an integer index to the underlying array to a slot.
256   static inline FeedbackVectorSlot ToSlot(int index);
257   inline Object* Get(FeedbackVectorSlot slot) const;
258   inline void Set(FeedbackVectorSlot slot, Object* value,
259                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
260 
261   // Returns slot kind for given slot.
262   FeedbackVectorSlotKind GetKind(FeedbackVectorSlot slot) const;
263   // Returns name corresponding to given slot or an empty string.
264   String* GetName(FeedbackVectorSlot slot) const;
265 
266   static Handle<TypeFeedbackVector> New(Isolate* isolate,
267                                         Handle<TypeFeedbackMetadata> metadata);
268 
269   static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
270                                          Handle<TypeFeedbackVector> vector);
271 
272 #ifdef OBJECT_PRINT
273   // For gdb debugging.
274   void Print();
275 #endif  // OBJECT_PRINT
276 
DECLARE_PRINTER(TypeFeedbackVector)277   DECLARE_PRINTER(TypeFeedbackVector)
278 
279   // Clears the vector slots.
280   void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); }
281 
ClearSlotsAtGCTime(SharedFunctionInfo * shared)282   void ClearSlotsAtGCTime(SharedFunctionInfo* shared) {
283     ClearSlotsImpl(shared, false);
284   }
285 
286   static void ClearAllKeyedStoreICs(Isolate* isolate);
287   void ClearKeyedStoreICs(SharedFunctionInfo* shared);
288 
289   // The object that indicates an uninitialized cache.
290   static inline Handle<Symbol> UninitializedSentinel(Isolate* isolate);
291 
292   // The object that indicates a megamorphic state.
293   static inline Handle<Symbol> MegamorphicSentinel(Isolate* isolate);
294 
295   // The object that indicates a premonomorphic state.
296   static inline Handle<Symbol> PremonomorphicSentinel(Isolate* isolate);
297 
298   // A raw version of the uninitialized sentinel that's safe to read during
299   // garbage collection (e.g., for patching the cache).
300   static inline Symbol* RawUninitializedSentinel(Isolate* isolate);
301 
302   static const int kDummyLoadICSlot = 0;
303   static const int kDummyKeyedLoadICSlot = 2;
304   static const int kDummyStoreICSlot = 4;
305   static const int kDummyKeyedStoreICSlot = 6;
306 
307   static Handle<TypeFeedbackVector> DummyVector(Isolate* isolate);
DummySlot(int dummyIndex)308   static FeedbackVectorSlot DummySlot(int dummyIndex) {
309     DCHECK(dummyIndex >= 0 && dummyIndex <= kDummyKeyedStoreICSlot);
310     return FeedbackVectorSlot(dummyIndex);
311   }
312 
313  private:
314   void ClearSlotsImpl(SharedFunctionInfo* shared, bool force_clear);
315 
316   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
317 };
318 
319 
320 // The following asserts protect an optimization in type feedback vector
321 // code that looks into the contents of a slot assuming to find a String,
322 // a Symbol, an AllocationSite, a WeakCell, or a FixedArray.
323 STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
324 STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
325 STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
326 STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot);
327 // Verify that an empty hash field looks like a tagged object, but can't
328 // possibly be confused with a pointer.
329 STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
330 STATIC_ASSERT(Name::kEmptyHashField == 0x3);
331 // Verify that a set hash field will not look like a tagged object.
332 STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
333 
334 
335 class TypeFeedbackMetadataIterator {
336  public:
TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)337   explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)
338       : metadata_handle_(metadata),
339         next_slot_(FeedbackVectorSlot(0)),
340         slot_kind_(FeedbackVectorSlotKind::INVALID) {}
341 
TypeFeedbackMetadataIterator(TypeFeedbackMetadata * metadata)342   explicit TypeFeedbackMetadataIterator(TypeFeedbackMetadata* metadata)
343       : metadata_(metadata),
344         next_slot_(FeedbackVectorSlot(0)),
345         slot_kind_(FeedbackVectorSlotKind::INVALID) {}
346 
347   inline bool HasNext() const;
348 
349   inline FeedbackVectorSlot Next();
350 
351   // Returns slot kind of the last slot returned by Next().
kind()352   FeedbackVectorSlotKind kind() const {
353     DCHECK_NE(FeedbackVectorSlotKind::INVALID, slot_kind_);
354     DCHECK_NE(FeedbackVectorSlotKind::KINDS_NUMBER, slot_kind_);
355     return slot_kind_;
356   }
357 
358   // Returns entry size of the last slot returned by Next().
359   inline int entry_size() const;
360 
name()361   String* name() const {
362     DCHECK(TypeFeedbackMetadata::SlotRequiresName(kind()));
363     return metadata()->GetName(cur_slot_);
364   }
365 
366  private:
metadata()367   TypeFeedbackMetadata* metadata() const {
368     return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
369   }
370 
371   // The reason for having a handle and a raw pointer to the meta data is
372   // to have a single iterator implementation for both "handlified" and raw
373   // pointer use cases.
374   Handle<TypeFeedbackMetadata> metadata_handle_;
375   TypeFeedbackMetadata* metadata_;
376   FeedbackVectorSlot cur_slot_;
377   FeedbackVectorSlot next_slot_;
378   FeedbackVectorSlotKind slot_kind_;
379 };
380 
381 
382 // A FeedbackNexus is the combination of a TypeFeedbackVector and a slot.
383 // Derived classes customize the update and retrieval of feedback.
384 class FeedbackNexus {
385  public:
FeedbackNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)386   FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
387       : vector_handle_(vector), vector_(NULL), slot_(slot) {}
FeedbackNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)388   FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
389       : vector_(vector), slot_(slot) {}
~FeedbackNexus()390   virtual ~FeedbackNexus() {}
391 
vector_handle()392   Handle<TypeFeedbackVector> vector_handle() const {
393     DCHECK(vector_ == NULL);
394     return vector_handle_;
395   }
vector()396   TypeFeedbackVector* vector() const {
397     return vector_handle_.is_null() ? vector_ : *vector_handle_;
398   }
slot()399   FeedbackVectorSlot slot() const { return slot_; }
400 
ic_state()401   InlineCacheState ic_state() const { return StateFromFeedback(); }
IsUninitialized()402   bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
FindFirstMap()403   Map* FindFirstMap() const {
404     MapHandleList maps;
405     ExtractMaps(&maps);
406     if (maps.length() > 0) return *maps.at(0);
407     return NULL;
408   }
409 
410   // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
FindAllMaps(MapHandleList * maps)411   void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
412 
413   virtual InlineCacheState StateFromFeedback() const = 0;
414   virtual int ExtractMaps(MapHandleList* maps) const;
415   virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const;
416   virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const;
FindFirstName()417   virtual Name* FindFirstName() const { return NULL; }
418 
419   virtual void ConfigureUninitialized();
420   virtual void ConfigurePremonomorphic();
421   virtual void ConfigureMegamorphic();
422 
423   inline Object* GetFeedback() const;
424   inline Object* GetFeedbackExtra() const;
425 
426   inline Isolate* GetIsolate() const;
427 
428  protected:
429   inline void SetFeedback(Object* feedback,
430                           WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
431   inline void SetFeedbackExtra(Object* feedback_extra,
432                                WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
433 
434   Handle<FixedArray> EnsureArrayOfSize(int length);
435   Handle<FixedArray> EnsureExtraArrayOfSize(int length);
436   void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps,
437                        CodeHandleList* handlers);
438 
439  private:
440   // The reason for having a vector handle and a raw pointer is that we can and
441   // should use handles during IC miss, but not during GC when we clear ICs. If
442   // you have a handle to the vector that is better because more operations can
443   // be done, like allocation.
444   Handle<TypeFeedbackVector> vector_handle_;
445   TypeFeedbackVector* vector_;
446   FeedbackVectorSlot slot_;
447 };
448 
449 
450 class CallICNexus final : public FeedbackNexus {
451  public:
CallICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)452   CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
453       : FeedbackNexus(vector, slot) {
454     DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
455   }
CallICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)456   CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
457       : FeedbackNexus(vector, slot) {
458     DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
459   }
460 
461   void Clear(Code* host);
462 
463   void ConfigureMonomorphicArray();
464   void ConfigureMonomorphic(Handle<JSFunction> function);
465   void ConfigureMegamorphic() final;
466   void ConfigureMegamorphic(int call_count);
467 
468   InlineCacheState StateFromFeedback() const final;
469 
ExtractMaps(MapHandleList * maps)470   int ExtractMaps(MapHandleList* maps) const final {
471     // CallICs don't record map feedback.
472     return 0;
473   }
FindHandlerForMap(Handle<Map> map)474   MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final {
475     return MaybeHandle<Code>();
476   }
477   bool FindHandlers(CodeHandleList* code_list, int length = -1) const final {
478     return length == 0;
479   }
480 
481   int ExtractCallCount();
482 };
483 
484 
485 class LoadICNexus : public FeedbackNexus {
486  public:
LoadICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)487   LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
488       : FeedbackNexus(vector, slot) {
489     DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
490   }
LoadICNexus(Isolate * isolate)491   explicit LoadICNexus(Isolate* isolate)
492       : FeedbackNexus(
493             TypeFeedbackVector::DummyVector(isolate),
494             FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
LoadICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)495   LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
496       : FeedbackNexus(vector, slot) {
497     DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
498   }
499 
500   void Clear(Code* host);
501 
502   void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
503 
504   void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
505 
506   InlineCacheState StateFromFeedback() const override;
507 };
508 
509 class LoadGlobalICNexus : public FeedbackNexus {
510  public:
LoadGlobalICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)511   LoadGlobalICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
512       : FeedbackNexus(vector, slot) {
513     DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
514   }
LoadGlobalICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)515   LoadGlobalICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
516       : FeedbackNexus(vector, slot) {
517     DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
518   }
519 
ExtractMaps(MapHandleList * maps)520   int ExtractMaps(MapHandleList* maps) const final {
521     // LoadGlobalICs don't record map feedback.
522     return 0;
523   }
FindHandlerForMap(Handle<Map> map)524   MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final {
525     return MaybeHandle<Code>();
526   }
527   bool FindHandlers(CodeHandleList* code_list, int length = -1) const final {
528     return length == 0;
529   }
530 
ConfigureMegamorphic()531   void ConfigureMegamorphic() override { UNREACHABLE(); }
532   void Clear(Code* host);
533 
534   void ConfigureUninitialized() override;
535   void ConfigurePropertyCellMode(Handle<PropertyCell> cell);
536   void ConfigureHandlerMode(Handle<Code> handler);
537 
538   InlineCacheState StateFromFeedback() const override;
539 };
540 
541 class KeyedLoadICNexus : public FeedbackNexus {
542  public:
KeyedLoadICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)543   KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
544       : FeedbackNexus(vector, slot) {
545     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
546   }
KeyedLoadICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)547   KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
548       : FeedbackNexus(vector, slot) {
549     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
550   }
551 
552   void Clear(Code* host);
553 
554   // name can be a null handle for element loads.
555   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
556                             Handle<Code> handler);
557   // name can be null.
558   void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
559                             CodeHandleList* handlers);
560 
561   void ConfigureMegamorphicKeyed(IcCheckType property_type);
562 
563   IcCheckType GetKeyType() const;
564   InlineCacheState StateFromFeedback() const override;
565   Name* FindFirstName() const override;
566 };
567 
568 
569 class StoreICNexus : public FeedbackNexus {
570  public:
StoreICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)571   StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
572       : FeedbackNexus(vector, slot) {
573     DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
574   }
StoreICNexus(Isolate * isolate)575   explicit StoreICNexus(Isolate* isolate)
576       : FeedbackNexus(
577             TypeFeedbackVector::DummyVector(isolate),
578             FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
StoreICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)579   StoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
580       : FeedbackNexus(vector, slot) {
581     DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
582   }
583 
584   void Clear(Code* host);
585 
586   void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler);
587 
588   void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers);
589 
590   InlineCacheState StateFromFeedback() const override;
591 };
592 
593 
594 class KeyedStoreICNexus : public FeedbackNexus {
595  public:
KeyedStoreICNexus(Handle<TypeFeedbackVector> vector,FeedbackVectorSlot slot)596   KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
597       : FeedbackNexus(vector, slot) {
598     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
599   }
KeyedStoreICNexus(Isolate * isolate)600   explicit KeyedStoreICNexus(Isolate* isolate)
601       : FeedbackNexus(
602             TypeFeedbackVector::DummyVector(isolate),
603             FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
KeyedStoreICNexus(TypeFeedbackVector * vector,FeedbackVectorSlot slot)604   KeyedStoreICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
605       : FeedbackNexus(vector, slot) {
606     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
607   }
608 
609   void Clear(Code* host);
610 
611   // name can be a null handle for element loads.
612   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
613                             Handle<Code> handler);
614   // name can be null.
615   void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
616                             CodeHandleList* handlers);
617   void ConfigurePolymorphic(MapHandleList* maps,
618                             MapHandleList* transitioned_maps,
619                             CodeHandleList* handlers);
620   void ConfigureMegamorphicKeyed(IcCheckType property_type);
621 
622   KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
623   IcCheckType GetKeyType() const;
624 
625   InlineCacheState StateFromFeedback() const override;
626   Name* FindFirstName() const override;
627 };
628 }  // namespace internal
629 }  // namespace v8
630 
631 #endif  // V8_TRANSITIONS_H_
632