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
15namespace v8 {
16namespace internal {
17
18enum 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
37std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind);
38
39
40template <typename Derived>
41class FeedbackVectorSpecBase {
42 public:
43  inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind);
44
45  FeedbackVectorSlot AddCallICSlot() {
46    return AddSlot(FeedbackVectorSlotKind::CALL_IC);
47  }
48
49  FeedbackVectorSlot AddLoadICSlot() {
50    return AddSlot(FeedbackVectorSlotKind::LOAD_IC);
51  }
52
53  FeedbackVectorSlot AddLoadGlobalICSlot(Handle<String> name) {
54    This()->append_name(name);
55    return AddSlot(FeedbackVectorSlotKind::LOAD_GLOBAL_IC);
56  }
57
58  FeedbackVectorSlot AddKeyedLoadICSlot() {
59    return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC);
60  }
61
62  FeedbackVectorSlot AddStoreICSlot() {
63    return AddSlot(FeedbackVectorSlotKind::STORE_IC);
64  }
65
66  FeedbackVectorSlot AddKeyedStoreICSlot() {
67    return AddSlot(FeedbackVectorSlotKind::KEYED_STORE_IC);
68  }
69
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
79  DECLARE_PRINTER(FeedbackVectorSpec)
80
81 private:
82  Derived* This() { return static_cast<Derived*>(this); }
83};
84
85
86class StaticFeedbackVectorSpec
87    : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
88 public:
89  StaticFeedbackVectorSpec() : slot_count_(0), name_count_(0) {}
90
91  int slots() const { return slot_count_; }
92
93  FeedbackVectorSlotKind GetKind(int slot) const {
94    DCHECK(slot >= 0 && slot < slot_count_);
95    return kinds_[slot];
96  }
97
98  int name_count() const { return name_count_; }
99
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
108  void append(FeedbackVectorSlotKind kind) {
109    DCHECK(slot_count_ < kMaxLength);
110    kinds_[slot_count_++] = kind;
111  }
112
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
127class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
128 public:
129  explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone), names_(zone) {
130    slot_kinds_.reserve(16);
131    names_.reserve(8);
132  }
133
134  int slots() const { return static_cast<int>(slot_kinds_.size()); }
135
136  FeedbackVectorSlotKind GetKind(int slot) const {
137    return static_cast<FeedbackVectorSlotKind>(slot_kinds_.at(slot));
138  }
139
140  int name_count() const { return static_cast<int>(names_.size()); }
141
142  Handle<String> GetName(int index) const { return names_.at(index); }
143
144 private:
145  friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
146
147  void append(FeedbackVectorSlotKind kind) {
148    slot_kinds_.push_back(static_cast<unsigned char>(kind));
149  }
150
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//
163class 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//
231class 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.
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
277  DECLARE_PRINTER(TypeFeedbackVector)
278
279  // Clears the vector slots.
280  void ClearSlots(SharedFunctionInfo* shared) { ClearSlotsImpl(shared, true); }
281
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);
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.
323STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
324STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
325STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
326STATIC_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.
329STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
330STATIC_ASSERT(Name::kEmptyHashField == 0x3);
331// Verify that a set hash field will not look like a tagged object.
332STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
333
334
335class TypeFeedbackMetadataIterator {
336 public:
337  explicit TypeFeedbackMetadataIterator(Handle<TypeFeedbackMetadata> metadata)
338      : metadata_handle_(metadata),
339        next_slot_(FeedbackVectorSlot(0)),
340        slot_kind_(FeedbackVectorSlotKind::INVALID) {}
341
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().
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
361  String* name() const {
362    DCHECK(TypeFeedbackMetadata::SlotRequiresName(kind()));
363    return metadata()->GetName(cur_slot_);
364  }
365
366 private:
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.
384class FeedbackNexus {
385 public:
386  FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
387      : vector_handle_(vector), vector_(NULL), slot_(slot) {}
388  FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
389      : vector_(vector), slot_(slot) {}
390  virtual ~FeedbackNexus() {}
391
392  Handle<TypeFeedbackVector> vector_handle() const {
393    DCHECK(vector_ == NULL);
394    return vector_handle_;
395  }
396  TypeFeedbackVector* vector() const {
397    return vector_handle_.is_null() ? vector_ : *vector_handle_;
398  }
399  FeedbackVectorSlot slot() const { return slot_; }
400
401  InlineCacheState ic_state() const { return StateFromFeedback(); }
402  bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
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.
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;
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
450class CallICNexus final : public FeedbackNexus {
451 public:
452  CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
453      : FeedbackNexus(vector, slot) {
454    DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot));
455  }
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
470  int ExtractMaps(MapHandleList* maps) const final {
471    // CallICs don't record map feedback.
472    return 0;
473  }
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
485class LoadICNexus : public FeedbackNexus {
486 public:
487  LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
488      : FeedbackNexus(vector, slot) {
489    DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot));
490  }
491  explicit LoadICNexus(Isolate* isolate)
492      : FeedbackNexus(
493            TypeFeedbackVector::DummyVector(isolate),
494            FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {}
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
509class LoadGlobalICNexus : public FeedbackNexus {
510 public:
511  LoadGlobalICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
512      : FeedbackNexus(vector, slot) {
513    DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
514  }
515  LoadGlobalICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot)
516      : FeedbackNexus(vector, slot) {
517    DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, vector->GetKind(slot));
518  }
519
520  int ExtractMaps(MapHandleList* maps) const final {
521    // LoadGlobalICs don't record map feedback.
522    return 0;
523  }
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
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
541class KeyedLoadICNexus : public FeedbackNexus {
542 public:
543  KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
544      : FeedbackNexus(vector, slot) {
545    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, vector->GetKind(slot));
546  }
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
569class StoreICNexus : public FeedbackNexus {
570 public:
571  StoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
572      : FeedbackNexus(vector, slot) {
573    DCHECK_EQ(FeedbackVectorSlotKind::STORE_IC, vector->GetKind(slot));
574  }
575  explicit StoreICNexus(Isolate* isolate)
576      : FeedbackNexus(
577            TypeFeedbackVector::DummyVector(isolate),
578            FeedbackVectorSlot(TypeFeedbackVector::kDummyStoreICSlot)) {}
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
594class KeyedStoreICNexus : public FeedbackNexus {
595 public:
596  KeyedStoreICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
597      : FeedbackNexus(vector, slot) {
598    DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC, vector->GetKind(slot));
599  }
600  explicit KeyedStoreICNexus(Isolate* isolate)
601      : FeedbackNexus(
602            TypeFeedbackVector::DummyVector(isolate),
603            FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)) {}
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