LCOV - code coverage report
Current view: top level - src - feedback-vector.h (source / functions) Hit Total Coverage
Test: app.info Lines: 106 133 79.7 %
Date: 2017-04-26 Functions: 25 57 43.9 %

          Line data    Source code
       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_FEEDBACK_VECTOR_H_
       6             : #define V8_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/type-hints.h"
      14             : #include "src/zone/zone-containers.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : enum class FeedbackSlotKind {
      20             :   // This kind means that the slot points to the middle of other slot
      21             :   // which occupies more than one feedback vector element.
      22             :   // There must be no such slots in the system.
      23             :   kInvalid,
      24             : 
      25             :   kCall,
      26             :   kLoadProperty,
      27             :   kLoadGlobalNotInsideTypeof,
      28             :   kLoadGlobalInsideTypeof,
      29             :   kLoadKeyed,
      30             :   kStoreGlobalSloppy,
      31             :   kStoreGlobalStrict,
      32             :   kStoreNamedSloppy,
      33             :   kStoreNamedStrict,
      34             :   kStoreOwnNamed,
      35             :   kStoreKeyedSloppy,
      36             :   kStoreKeyedStrict,
      37             :   kBinaryOp,
      38             :   kCompareOp,
      39             :   kToBoolean,
      40             :   kStoreDataPropertyInLiteral,
      41             :   kTypeProfile,
      42             :   kCreateClosure,
      43             :   kLiteral,
      44             :   // This is a general purpose slot that occupies one feedback vector element.
      45             :   kGeneral,
      46             : 
      47             :   kKindsNumber  // Last value indicating number of kinds.
      48             : };
      49             : 
      50             : inline bool IsCallICKind(FeedbackSlotKind kind) {
      51             :   return kind == FeedbackSlotKind::kCall;
      52             : }
      53             : 
      54     4359778 : inline bool IsLoadICKind(FeedbackSlotKind kind) {
      55     4359778 :   return kind == FeedbackSlotKind::kLoadProperty;
      56             : }
      57             : 
      58         158 : inline bool IsLoadGlobalICKind(FeedbackSlotKind kind) {
      59    17996567 :   return kind == FeedbackSlotKind::kLoadGlobalNotInsideTypeof ||
      60         158 :          kind == FeedbackSlotKind::kLoadGlobalInsideTypeof;
      61             : }
      62             : 
      63             : inline bool IsKeyedLoadICKind(FeedbackSlotKind kind) {
      64             :   return kind == FeedbackSlotKind::kLoadKeyed;
      65             : }
      66             : 
      67     1690942 : inline bool IsStoreGlobalICKind(FeedbackSlotKind kind) {
      68     1715876 :   return kind == FeedbackSlotKind::kStoreGlobalSloppy ||
      69     1690942 :          kind == FeedbackSlotKind::kStoreGlobalStrict;
      70             : }
      71             : 
      72     5895934 : inline bool IsStoreICKind(FeedbackSlotKind kind) {
      73     6004692 :   return kind == FeedbackSlotKind::kStoreNamedSloppy ||
      74     5895934 :          kind == FeedbackSlotKind::kStoreNamedStrict;
      75             : }
      76             : 
      77     2341694 : inline bool IsStoreOwnICKind(FeedbackSlotKind kind) {
      78     2341694 :   return kind == FeedbackSlotKind::kStoreOwnNamed;
      79             : }
      80             : 
      81             : inline bool IsKeyedStoreICKind(FeedbackSlotKind kind) {
      82    12021925 :   return kind == FeedbackSlotKind::kStoreKeyedSloppy ||
      83             :          kind == FeedbackSlotKind::kStoreKeyedStrict;
      84             : }
      85             : 
      86             : inline bool IsTypeProfileKind(FeedbackSlotKind kind) {
      87             :   return kind == FeedbackSlotKind::kTypeProfile;
      88             : }
      89             : 
      90             : inline TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind) {
      91             :   DCHECK(IsLoadGlobalICKind(kind));
      92             :   return (kind == FeedbackSlotKind::kLoadGlobalInsideTypeof)
      93             :              ? INSIDE_TYPEOF
      94     1786888 :              : NOT_INSIDE_TYPEOF;
      95             : }
      96             : 
      97             : inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
      98             :   DCHECK(IsStoreICKind(kind) || IsStoreOwnICKind(kind) ||
      99             :          IsStoreGlobalICKind(kind) || IsKeyedStoreICKind(kind));
     100    20123702 :   return (kind == FeedbackSlotKind::kStoreNamedSloppy ||
     101    10061851 :           kind == FeedbackSlotKind::kStoreGlobalSloppy ||
     102             :           kind == FeedbackSlotKind::kStoreKeyedSloppy)
     103             :              ? SLOPPY
     104    10061851 :              : STRICT;
     105             : }
     106             : 
     107             : std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind);
     108             : 
     109             : template <typename Derived>
     110             : class FeedbackVectorSpecBase {
     111             :  public:
     112     4573643 :   FeedbackSlot AddCallICSlot() { return AddSlot(FeedbackSlotKind::kCall); }
     113             : 
     114             :   FeedbackSlot AddLoadICSlot() {
     115     6341436 :     return AddSlot(FeedbackSlotKind::kLoadProperty);
     116             :   }
     117             : 
     118             :   FeedbackSlot AddLoadGlobalICSlot(TypeofMode typeof_mode) {
     119             :     return AddSlot(typeof_mode == INSIDE_TYPEOF
     120             :                        ? FeedbackSlotKind::kLoadGlobalInsideTypeof
     121     3032345 :                        : FeedbackSlotKind::kLoadGlobalNotInsideTypeof);
     122             :   }
     123             : 
     124             :   FeedbackSlot AddCreateClosureSlot() {
     125     5461758 :     return AddSlot(FeedbackSlotKind::kCreateClosure);
     126             :   }
     127             : 
     128             :   FeedbackSlot AddKeyedLoadICSlot() {
     129      668064 :     return AddSlot(FeedbackSlotKind::kLoadKeyed);
     130             :   }
     131             : 
     132             :   FeedbackSlot AddStoreICSlot(LanguageMode language_mode) {
     133             :     STATIC_ASSERT(LANGUAGE_END == 2);
     134             :     return AddSlot(is_strict(language_mode)
     135             :                        ? FeedbackSlotKind::kStoreNamedStrict
     136     2558506 :                        : FeedbackSlotKind::kStoreNamedSloppy);
     137             :   }
     138             : 
     139             :   FeedbackSlot AddStoreOwnICSlot() {
     140      574804 :     return AddSlot(FeedbackSlotKind::kStoreOwnNamed);
     141             :   }
     142             : 
     143             :   FeedbackSlot AddStoreGlobalICSlot(LanguageMode language_mode) {
     144             :     STATIC_ASSERT(LANGUAGE_END == 2);
     145             :     return AddSlot(is_strict(language_mode)
     146             :                        ? FeedbackSlotKind::kStoreGlobalStrict
     147      998372 :                        : FeedbackSlotKind::kStoreGlobalSloppy);
     148             :   }
     149             : 
     150             :   FeedbackSlot AddKeyedStoreICSlot(LanguageMode language_mode) {
     151             :     STATIC_ASSERT(LANGUAGE_END == 2);
     152             :     return AddSlot(is_strict(language_mode)
     153             :                        ? FeedbackSlotKind::kStoreKeyedStrict
     154      292685 :                        : FeedbackSlotKind::kStoreKeyedSloppy);
     155             :   }
     156             : 
     157             :   FeedbackSlot AddInterpreterBinaryOpICSlot() {
     158     3050288 :     return AddSlot(FeedbackSlotKind::kBinaryOp);
     159             :   }
     160             : 
     161             :   FeedbackSlot AddInterpreterCompareICSlot() {
     162     2504962 :     return AddSlot(FeedbackSlotKind::kCompareOp);
     163             :   }
     164             : 
     165       11513 :   FeedbackSlot AddGeneralSlot() { return AddSlot(FeedbackSlotKind::kGeneral); }
     166             : 
     167     1145104 :   FeedbackSlot AddLiteralSlot() { return AddSlot(FeedbackSlotKind::kLiteral); }
     168             : 
     169             :   FeedbackSlot AddStoreDataPropertyInLiteralICSlot() {
     170      307523 :     return AddSlot(FeedbackSlotKind::kStoreDataPropertyInLiteral);
     171             :   }
     172             : 
     173             :   FeedbackSlot AddTypeProfileSlot();
     174             : 
     175             : #ifdef OBJECT_PRINT
     176             :   // For gdb debugging.
     177             :   void Print();
     178             : #endif  // OBJECT_PRINT
     179             : 
     180             :   DECLARE_PRINTER(FeedbackVectorSpec)
     181             : 
     182             :  private:
     183             :   inline FeedbackSlot AddSlot(FeedbackSlotKind kind);
     184             : 
     185             :   Derived* This() { return static_cast<Derived*>(this); }
     186             : };
     187             : 
     188             : class StaticFeedbackVectorSpec
     189             :     : public FeedbackVectorSpecBase<StaticFeedbackVectorSpec> {
     190             :  public:
     191    10654406 :   StaticFeedbackVectorSpec() : slot_count_(0) {}
     192             : 
     193             :   int slots() const { return slot_count_; }
     194             : 
     195             :   FeedbackSlotKind GetKind(FeedbackSlot slot) const {
     196             :     DCHECK(slot.ToInt() >= 0 && slot.ToInt() < slot_count_);
     197           0 :     return kinds_[slot.ToInt()];
     198             :   }
     199             : 
     200             :  private:
     201             :   friend class FeedbackVectorSpecBase<StaticFeedbackVectorSpec>;
     202             : 
     203             :   void append(FeedbackSlotKind kind) {
     204             :     DCHECK(slot_count_ < kMaxLength);
     205             :     kinds_[slot_count_++] = kind;
     206             :   }
     207             : 
     208             :   static const int kMaxLength = 12;
     209             : 
     210             :   int slot_count_;
     211             :   FeedbackSlotKind kinds_[kMaxLength];
     212             : };
     213             : 
     214             : class FeedbackVectorSpec : public FeedbackVectorSpecBase<FeedbackVectorSpec> {
     215             :  public:
     216             :   explicit FeedbackVectorSpec(Zone* zone) : slot_kinds_(zone) {
     217    13519498 :     slot_kinds_.reserve(16);
     218             :   }
     219             : 
     220    86598860 :   int slots() const { return static_cast<int>(slot_kinds_.size()); }
     221             : 
     222             :   FeedbackSlotKind GetKind(FeedbackSlot slot) const {
     223   171347991 :     return static_cast<FeedbackSlotKind>(slot_kinds_.at(slot.ToInt()));
     224             :   }
     225             : 
     226             :   bool HasTypeProfileSlot() const;
     227             : 
     228             :   // If used, the TypeProfileSlot is always added as the first slot and its
     229             :   // index is constant. If other slots are added before the TypeProfileSlot,
     230             :   // this number changes.
     231             :   static const int kTypeProfileSlotIndex = 2;
     232             : 
     233             :  private:
     234             :   friend class FeedbackVectorSpecBase<FeedbackVectorSpec>;
     235             : 
     236             :   void append(FeedbackSlotKind kind) {
     237   101736953 :     slot_kinds_.push_back(static_cast<unsigned char>(kind));
     238             :   }
     239             : 
     240             :   ZoneVector<unsigned char> slot_kinds_;
     241             : };
     242             : 
     243             : // The shape of the FeedbackMetadata is an array with:
     244             : // 0: slot_count
     245             : // 1: names table
     246             : // 2: parameters table
     247             : // 3..N: slot kinds packed into a bit vector
     248             : //
     249             : class FeedbackMetadata : public FixedArray {
     250             :  public:
     251             :   // Casting.
     252             :   static inline FeedbackMetadata* cast(Object* obj);
     253             : 
     254             :   static const int kSlotsCountIndex = 0;
     255             :   static const int kReservedIndexCount = 1;
     256             : 
     257             :   // Returns number of feedback vector elements used by given slot kind.
     258             :   static inline int GetSlotSize(FeedbackSlotKind kind);
     259             : 
     260             :   bool SpecDiffersFrom(const FeedbackVectorSpec* other_spec) const;
     261             : 
     262             :   inline bool is_empty() const;
     263             : 
     264             :   // Returns number of slots in the vector.
     265             :   inline int slot_count() const;
     266             : 
     267             :   // Returns slot kind for given slot.
     268             :   FeedbackSlotKind GetKind(FeedbackSlot slot) const;
     269             : 
     270             :   template <typename Spec>
     271    10654402 :   static Handle<FeedbackMetadata> New(Isolate* isolate, const Spec* spec);
     272             : 
     273             : #ifdef OBJECT_PRINT
     274             :   // For gdb debugging.
     275             :   void Print();
     276             : #endif  // OBJECT_PRINT
     277             : 
     278             :   DECLARE_PRINTER(FeedbackMetadata)
     279             : 
     280             :   static const char* Kind2String(FeedbackSlotKind kind);
     281             :   bool HasTypeProfileSlot() const;
     282             : 
     283             :  private:
     284             :   static const int kFeedbackSlotKindBits = 5;
     285             :   STATIC_ASSERT(static_cast<int>(FeedbackSlotKind::kKindsNumber) <
     286             :                 (1 << kFeedbackSlotKindBits));
     287             : 
     288             :   void SetKind(FeedbackSlot slot, FeedbackSlotKind kind);
     289             : 
     290             :   typedef BitSetComputer<FeedbackSlotKind, kFeedbackSlotKindBits, kSmiValueSize,
     291             :                          uint32_t>
     292             :       VectorICComputer;
     293             : 
     294             :   DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackMetadata);
     295             : };
     296             : 
     297             : // The shape of the FeedbackVector is an array with:
     298             : // 0: feedback metadata
     299             : // 1: invocation count
     300             : // 2: feedback slot #0
     301             : // ...
     302             : // 2 + slot_count - 1: feedback slot #(slot_count-1)
     303             : //
     304             : class FeedbackVector : public FixedArray {
     305             :  public:
     306             :   // Casting.
     307             :   static inline FeedbackVector* cast(Object* obj);
     308             : 
     309             :   static const int kSharedFunctionInfoIndex = 0;
     310             :   static const int kInvocationCountIndex = 1;
     311             :   static const int kReservedIndexCount = 2;
     312             : 
     313             :   inline void ComputeCounts(int* with_type_info, int* generic,
     314             :                             int* vector_ic_count, bool code_is_interpreted);
     315             : 
     316             :   inline bool is_empty() const;
     317             : 
     318             :   // Returns number of slots in the vector.
     319             :   inline int slot_count() const;
     320             : 
     321             :   inline FeedbackMetadata* metadata() const;
     322             :   inline SharedFunctionInfo* shared_function_info() const;
     323             :   inline int invocation_count() const;
     324             :   inline void clear_invocation_count();
     325             : 
     326             :   // Conversion from a slot to an integer index to the underlying array.
     327             :   static int GetIndex(FeedbackSlot slot) {
     328   157711349 :     return kReservedIndexCount + slot.ToInt();
     329             :   }
     330             : 
     331             :   // Conversion from an integer index to the underlying array to a slot.
     332             :   static inline FeedbackSlot ToSlot(int index);
     333             :   inline Object* Get(FeedbackSlot slot) const;
     334             :   inline void Set(FeedbackSlot slot, Object* value,
     335             :                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     336             : 
     337             :   // Returns slot kind for given slot.
     338             :   FeedbackSlotKind GetKind(FeedbackSlot slot) const;
     339             : 
     340             :   FeedbackSlot GetTypeProfileSlot() const;
     341             : 
     342             :   static Handle<FeedbackVector> New(Isolate* isolate,
     343             :                                     Handle<SharedFunctionInfo> shared);
     344             : 
     345             :   static Handle<FeedbackVector> Copy(Isolate* isolate,
     346             :                                      Handle<FeedbackVector> vector);
     347             : 
     348             : #define DEFINE_SLOT_KIND_PREDICATE(Name) \
     349             :   bool Name(FeedbackSlot slot) const { return Name##Kind(GetKind(slot)); }
     350             : 
     351             :   DEFINE_SLOT_KIND_PREDICATE(IsCallIC)
     352             :   DEFINE_SLOT_KIND_PREDICATE(IsLoadIC)
     353             :   DEFINE_SLOT_KIND_PREDICATE(IsLoadGlobalIC)
     354             :   DEFINE_SLOT_KIND_PREDICATE(IsKeyedLoadIC)
     355             :   DEFINE_SLOT_KIND_PREDICATE(IsStoreIC)
     356       64847 :   DEFINE_SLOT_KIND_PREDICATE(IsStoreOwnIC)
     357             :   DEFINE_SLOT_KIND_PREDICATE(IsStoreGlobalIC)
     358       75440 :   DEFINE_SLOT_KIND_PREDICATE(IsKeyedStoreIC)
     359             :   DEFINE_SLOT_KIND_PREDICATE(IsTypeProfile)
     360             : #undef DEFINE_SLOT_KIND_PREDICATE
     361             : 
     362             :   // Returns typeof mode encoded into kind of given slot.
     363             :   inline TypeofMode GetTypeofMode(FeedbackSlot slot) const {
     364             :     return GetTypeofModeFromSlotKind(GetKind(slot));
     365             :   }
     366             : 
     367             :   // Returns language mode encoded into kind of given slot.
     368     8275572 :   inline LanguageMode GetLanguageMode(FeedbackSlot slot) const {
     369    16551144 :     return GetLanguageModeFromSlotKind(GetKind(slot));
     370             :   }
     371             : 
     372             : #ifdef OBJECT_PRINT
     373             :   // For gdb debugging.
     374             :   void Print();
     375             : #endif  // OBJECT_PRINT
     376             : 
     377             :   DECLARE_PRINTER(FeedbackVector)
     378             : 
     379             :   // Clears the vector slots.
     380             :   void ClearSlots(JSFunction* host_function);
     381             : 
     382             :   // The object that indicates an uninitialized cache.
     383             :   static inline Handle<Symbol> UninitializedSentinel(Isolate* isolate);
     384             : 
     385             :   // The object that indicates a megamorphic state.
     386             :   static inline Handle<Symbol> MegamorphicSentinel(Isolate* isolate);
     387             : 
     388             :   // The object that indicates a premonomorphic state.
     389             :   static inline Handle<Symbol> PremonomorphicSentinel(Isolate* isolate);
     390             : 
     391             :   // A raw version of the uninitialized sentinel that's safe to read during
     392             :   // garbage collection (e.g., for patching the cache).
     393             :   static inline Symbol* RawUninitializedSentinel(Isolate* isolate);
     394             : 
     395             :  private:
     396             :   static void AddToCodeCoverageList(Isolate* isolate,
     397             :                                     Handle<FeedbackVector> vector);
     398             : 
     399             :   DISALLOW_IMPLICIT_CONSTRUCTORS(FeedbackVector);
     400             : };
     401             : 
     402             : // The following asserts protect an optimization in type feedback vector
     403             : // code that looks into the contents of a slot assuming to find a String,
     404             : // a Symbol, an AllocationSite, a WeakCell, or a FixedArray.
     405             : STATIC_ASSERT(WeakCell::kSize >= 2 * kPointerSize);
     406             : STATIC_ASSERT(WeakCell::kValueOffset == AllocationSite::kTransitionInfoOffset);
     407             : STATIC_ASSERT(WeakCell::kValueOffset == FixedArray::kLengthOffset);
     408             : STATIC_ASSERT(WeakCell::kValueOffset == Name::kHashFieldSlot);
     409             : // Verify that an empty hash field looks like a tagged object, but can't
     410             : // possibly be confused with a pointer.
     411             : STATIC_ASSERT((Name::kEmptyHashField & kHeapObjectTag) == kHeapObjectTag);
     412             : STATIC_ASSERT(Name::kEmptyHashField == 0x3);
     413             : // Verify that a set hash field will not look like a tagged object.
     414             : STATIC_ASSERT(Name::kHashNotComputedMask == kHeapObjectTag);
     415             : 
     416             : class FeedbackMetadataIterator {
     417             :  public:
     418             :   explicit FeedbackMetadataIterator(Handle<FeedbackMetadata> metadata)
     419             :       : metadata_handle_(metadata),
     420             :         next_slot_(FeedbackSlot(0)),
     421             :         slot_kind_(FeedbackSlotKind::kInvalid) {}
     422             : 
     423             :   explicit FeedbackMetadataIterator(FeedbackMetadata* metadata)
     424             :       : metadata_(metadata),
     425             :         next_slot_(FeedbackSlot(0)),
     426      543158 :         slot_kind_(FeedbackSlotKind::kInvalid) {}
     427             : 
     428             :   inline bool HasNext() const;
     429             : 
     430             :   inline FeedbackSlot Next();
     431             : 
     432             :   // Returns slot kind of the last slot returned by Next().
     433             :   FeedbackSlotKind kind() const {
     434             :     DCHECK_NE(FeedbackSlotKind::kInvalid, slot_kind_);
     435             :     DCHECK_NE(FeedbackSlotKind::kKindsNumber, slot_kind_);
     436             :     return slot_kind_;
     437             :   }
     438             : 
     439             :   // Returns entry size of the last slot returned by Next().
     440             :   inline int entry_size() const;
     441             : 
     442             :  private:
     443             :   FeedbackMetadata* metadata() const {
     444    11361658 :     return !metadata_handle_.is_null() ? *metadata_handle_ : metadata_;
     445             :   }
     446             : 
     447             :   // The reason for having a handle and a raw pointer to the meta data is
     448             :   // to have a single iterator implementation for both "handlified" and raw
     449             :   // pointer use cases.
     450             :   Handle<FeedbackMetadata> metadata_handle_;
     451             :   FeedbackMetadata* metadata_;
     452             :   FeedbackSlot cur_slot_;
     453             :   FeedbackSlot next_slot_;
     454             :   FeedbackSlotKind slot_kind_;
     455             : };
     456             : 
     457             : // A FeedbackNexus is the combination of a FeedbackVector and a slot.
     458             : // Derived classes customize the update and retrieval of feedback.
     459             : class FeedbackNexus {
     460             :  public:
     461             :   FeedbackNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     462    21649731 :       : vector_handle_(vector), vector_(NULL), slot_(slot) {}
     463             :   FeedbackNexus(FeedbackVector* vector, FeedbackSlot slot)
     464      322862 :       : vector_(vector), slot_(slot) {}
     465    16353456 :   virtual ~FeedbackNexus() {}
     466             : 
     467             :   Handle<FeedbackVector> vector_handle() const {
     468             :     DCHECK(vector_ == NULL);
     469             :     return vector_handle_;
     470             :   }
     471             :   FeedbackVector* vector() const {
     472   120885985 :     return vector_handle_.is_null() ? vector_ : *vector_handle_;
     473             :   }
     474             :   FeedbackSlot slot() const { return slot_; }
     475    27513468 :   FeedbackSlotKind kind() const { return vector()->GetKind(slot()); }
     476             : 
     477      911380 :   InlineCacheState ic_state() const { return StateFromFeedback(); }
     478     1232722 :   bool IsUninitialized() const { return StateFromFeedback() == UNINITIALIZED; }
     479      174318 :   Map* FindFirstMap() const {
     480             :     MapHandleList maps;
     481      174318 :     ExtractMaps(&maps);
     482      348038 :     if (maps.length() > 0) return *maps.at(0);
     483             :     return NULL;
     484             :   }
     485             : 
     486             :   // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
     487       15782 :   void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
     488             : 
     489             :   virtual InlineCacheState StateFromFeedback() const = 0;
     490             :   virtual int ExtractMaps(MapHandleList* maps) const;
     491             :   virtual MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const;
     492             :   virtual bool FindHandlers(List<Handle<Object>>* code_list,
     493             :                             int length = -1) const;
     494           0 :   virtual Name* FindFirstName() const { return NULL; }
     495             : 
     496             :   bool IsCleared() {
     497      161333 :     InlineCacheState state = StateFromFeedback();
     498      161333 :     return !FLAG_use_ic || state == UNINITIALIZED || state == PREMONOMORPHIC;
     499             :   }
     500             : 
     501       23015 :   virtual void Clear() { ConfigureUninitialized(); }
     502             :   virtual void ConfigureUninitialized();
     503             :   void ConfigurePremonomorphic();
     504             :   void ConfigureMegamorphic(IcCheckType property_type);
     505             : 
     506             :   inline Object* GetFeedback() const;
     507             :   inline Object* GetFeedbackExtra() const;
     508             : 
     509             :   inline Isolate* GetIsolate() const;
     510             : 
     511             :   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
     512             :                             Handle<Object> handler);
     513             : 
     514             :   void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps,
     515             :                             List<Handle<Object>>* handlers);
     516             : 
     517             :  protected:
     518             :   inline void SetFeedback(Object* feedback,
     519             :                           WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     520             :   inline void SetFeedbackExtra(Object* feedback_extra,
     521             :                                WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     522             : 
     523             :   Handle<FixedArray> EnsureArrayOfSize(int length);
     524             :   Handle<FixedArray> EnsureExtraArrayOfSize(int length);
     525             : 
     526             :  private:
     527             :   // The reason for having a vector handle and a raw pointer is that we can and
     528             :   // should use handles during IC miss, but not during GC when we clear ICs. If
     529             :   // you have a handle to the vector that is better because more operations can
     530             :   // be done, like allocation.
     531             :   Handle<FeedbackVector> vector_handle_;
     532             :   FeedbackVector* vector_;
     533             :   FeedbackSlot slot_;
     534             : };
     535             : 
     536       17456 : class CallICNexus final : public FeedbackNexus {
     537             :  public:
     538             :   CallICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     539     1041766 :       : FeedbackNexus(vector, slot) {
     540             :     DCHECK(vector->IsCallIC(slot));
     541             :   }
     542             :   CallICNexus(FeedbackVector* vector, FeedbackSlot slot)
     543       13602 :       : FeedbackNexus(vector, slot) {
     544             :     DCHECK(vector->IsCallIC(slot));
     545             :   }
     546             : 
     547             :   void ConfigureUninitialized() final;
     548             : 
     549             :   InlineCacheState StateFromFeedback() const final;
     550             : 
     551           0 :   int ExtractMaps(MapHandleList* maps) const final {
     552             :     // CallICs don't record map feedback.
     553           0 :     return 0;
     554             :   }
     555           0 :   MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
     556           0 :     return MaybeHandle<Code>();
     557             :   }
     558           0 :   bool FindHandlers(List<Handle<Object>>* code_list,
     559             :                     int length = -1) const final {
     560           0 :     return length == 0;
     561             :   }
     562             : 
     563             :   int ExtractCallCount();
     564             : 
     565             :   // Compute the call frequency based on the call count and the invocation
     566             :   // count (taken from the type feedback vector).
     567             :   float ComputeCallFrequency();
     568             : };
     569             : 
     570     8760777 : class LoadICNexus : public FeedbackNexus {
     571             :  public:
     572     4359620 :   LoadICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     573     5974906 :       : FeedbackNexus(vector, slot) {
     574             :     DCHECK(vector->IsLoadIC(slot));
     575     4359620 :   }
     576             :   LoadICNexus(FeedbackVector* vector, FeedbackSlot slot)
     577       41537 :       : FeedbackNexus(vector, slot) {
     578             :     DCHECK(vector->IsLoadIC(slot));
     579             :   }
     580             : 
     581        8137 :   void Clear() override { ConfigurePremonomorphic(); }
     582             : 
     583             :   InlineCacheState StateFromFeedback() const override;
     584             : };
     585             : 
     586     6201614 : class LoadGlobalICNexus : public FeedbackNexus {
     587             :  public:
     588     2094580 :   LoadGlobalICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     589     4096211 :       : FeedbackNexus(vector, slot) {
     590             :     DCHECK(vector->IsLoadGlobalIC(slot));
     591     2094580 :   }
     592             :   LoadGlobalICNexus(FeedbackVector* vector, FeedbackSlot slot)
     593       10823 :       : FeedbackNexus(vector, slot) {
     594             :     DCHECK(vector->IsLoadGlobalIC(slot));
     595             :   }
     596             : 
     597           0 :   int ExtractMaps(MapHandleList* maps) const final {
     598             :     // LoadGlobalICs don't record map feedback.
     599           0 :     return 0;
     600             :   }
     601         804 :   MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
     602         804 :     return MaybeHandle<Code>();
     603             :   }
     604           0 :   bool FindHandlers(List<Handle<Object>>* code_list,
     605             :                     int length = -1) const final {
     606           0 :     return length == 0;
     607             :   }
     608             : 
     609             :   void ConfigureUninitialized() override;
     610             :   void ConfigurePropertyCellMode(Handle<PropertyCell> cell);
     611             :   void ConfigureHandlerMode(Handle<Object> handler);
     612             : 
     613             :   InlineCacheState StateFromFeedback() const override;
     614             : };
     615             : 
     616     1495200 : class KeyedLoadICNexus : public FeedbackNexus {
     617             :  public:
     618      704068 :   KeyedLoadICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     619     1048744 :       : FeedbackNexus(vector, slot) {
     620             :     DCHECK(vector->IsKeyedLoadIC(slot));
     621      704068 :   }
     622             :   KeyedLoadICNexus(FeedbackVector* vector, FeedbackSlot slot)
     623        5858 :       : FeedbackNexus(vector, slot) {
     624             :     DCHECK(vector->IsKeyedLoadIC(slot));
     625             :   }
     626             : 
     627        5308 :   void Clear() override { ConfigurePremonomorphic(); }
     628             : 
     629             :   IcCheckType GetKeyType() const;
     630             :   InlineCacheState StateFromFeedback() const override;
     631             :   Name* FindFirstName() const override;
     632             : };
     633             : 
     634    11874816 : class StoreICNexus : public FeedbackNexus {
     635             :  public:
     636     5895933 :   StoreICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     637     6195868 :       : FeedbackNexus(vector, slot) {
     638             :     DCHECK(vector->IsStoreIC(slot) || vector->IsStoreOwnIC(slot) ||
     639             :            vector->IsStoreGlobalIC(slot));
     640     5895933 :   }
     641             :   StoreICNexus(FeedbackVector* vector, FeedbackSlot slot)
     642       82948 :       : FeedbackNexus(vector, slot) {
     643             :     DCHECK(vector->IsStoreIC(slot) || vector->IsStoreOwnIC(slot) ||
     644             :            vector->IsStoreGlobalIC(slot));
     645             :   }
     646             : 
     647       41140 :   void Clear() override { ConfigurePremonomorphic(); }
     648             : 
     649             :   InlineCacheState StateFromFeedback() const override;
     650             : };
     651             : 
     652             : // TODO(ishell): Currently we use StoreOwnIC only for storing properties that
     653             : // already exist in the boilerplate therefore we can use StoreIC.
     654             : typedef StoreICNexus StoreOwnICNexus;
     655             : 
     656     1424198 : class KeyedStoreICNexus : public FeedbackNexus {
     657             :  public:
     658      702538 :   KeyedStoreICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     659      824727 :       : FeedbackNexus(vector, slot) {
     660             :     DCHECK(vector->IsKeyedStoreIC(slot));
     661      702538 :   }
     662             :   KeyedStoreICNexus(FeedbackVector* vector, FeedbackSlot slot)
     663        6565 :       : FeedbackNexus(vector, slot) {
     664             :     DCHECK(vector->IsKeyedStoreIC(slot));
     665             :   }
     666             : 
     667        3685 :   void Clear() override { ConfigurePremonomorphic(); }
     668             : 
     669             :   KeyedAccessStoreMode GetKeyedAccessStoreMode() const;
     670             :   IcCheckType GetKeyType() const;
     671             : 
     672             :   InlineCacheState StateFromFeedback() const override;
     673             :   Name* FindFirstName() const override;
     674             : };
     675             : 
     676           0 : class BinaryOpICNexus final : public FeedbackNexus {
     677             :  public:
     678             :   BinaryOpICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     679     1183302 :       : FeedbackNexus(vector, slot) {
     680             :     DCHECK_EQ(FeedbackSlotKind::kBinaryOp, vector->GetKind(slot));
     681             :   }
     682             :   BinaryOpICNexus(FeedbackVector* vector, FeedbackSlot slot)
     683             :       : FeedbackNexus(vector, slot) {
     684             :     DCHECK_EQ(FeedbackSlotKind::kBinaryOp, vector->GetKind(slot));
     685             :   }
     686             : 
     687             :   InlineCacheState StateFromFeedback() const final;
     688             :   BinaryOperationHint GetBinaryOperationFeedback() const;
     689             : 
     690           0 :   int ExtractMaps(MapHandleList* maps) const final {
     691             :     // BinaryOpICs don't record map feedback.
     692           0 :     return 0;
     693             :   }
     694           0 :   MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
     695           0 :     return MaybeHandle<Code>();
     696             :   }
     697           0 :   bool FindHandlers(List<Handle<Object>>* code_list,
     698             :                     int length = -1) const final {
     699           0 :     return length == 0;
     700             :   }
     701             : };
     702             : 
     703           0 : class CompareICNexus final : public FeedbackNexus {
     704             :  public:
     705             :   CompareICNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     706      903968 :       : FeedbackNexus(vector, slot) {
     707             :     DCHECK_EQ(FeedbackSlotKind::kCompareOp, vector->GetKind(slot));
     708             :   }
     709             :   CompareICNexus(FeedbackVector* vector, FeedbackSlot slot)
     710             :       : FeedbackNexus(vector, slot) {
     711             :     DCHECK_EQ(FeedbackSlotKind::kCompareOp, vector->GetKind(slot));
     712             :   }
     713             : 
     714             :   InlineCacheState StateFromFeedback() const final;
     715             :   CompareOperationHint GetCompareOperationFeedback() const;
     716             : 
     717           0 :   int ExtractMaps(MapHandleList* maps) const final {
     718             :     // BinaryOpICs don't record map feedback.
     719           0 :     return 0;
     720             :   }
     721           0 :   MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const final {
     722           0 :     return MaybeHandle<Code>();
     723             :   }
     724           0 :   bool FindHandlers(List<Handle<Object>>* code_list,
     725             :                     int length = -1) const final {
     726           0 :     return length == 0;
     727             :   }
     728             : };
     729             : 
     730      668438 : class StoreDataPropertyInLiteralICNexus : public FeedbackNexus {
     731             :  public:
     732      334219 :   StoreDataPropertyInLiteralICNexus(Handle<FeedbackVector> vector,
     733             :                                     FeedbackSlot slot)
     734      378421 :       : FeedbackNexus(vector, slot) {
     735             :     DCHECK_EQ(FeedbackSlotKind::kStoreDataPropertyInLiteral,
     736             :               vector->GetKind(slot));
     737      334219 :   }
     738             :   StoreDataPropertyInLiteralICNexus(FeedbackVector* vector, FeedbackSlot slot)
     739           0 :       : FeedbackNexus(vector, slot) {
     740             :     DCHECK_EQ(FeedbackSlotKind::kStoreDataPropertyInLiteral,
     741             :               vector->GetKind(slot));
     742             :   }
     743             : 
     744             :   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map);
     745             : 
     746             :   InlineCacheState StateFromFeedback() const override;
     747             : };
     748             : 
     749             : // For each assignment, store the type of the value in the collection of types
     750             : // in the feedback vector.
     751        3832 : class CollectTypeProfileNexus : public FeedbackNexus {
     752             :  public:
     753        1818 :   CollectTypeProfileNexus(Handle<FeedbackVector> vector, FeedbackSlot slot)
     754        1818 :       : FeedbackNexus(vector, slot) {
     755             :     DCHECK_EQ(FeedbackSlotKind::kTypeProfile, vector->GetKind(slot));
     756        1818 :   }
     757          98 :   CollectTypeProfileNexus(FeedbackVector* vector, FeedbackSlot slot)
     758          98 :       : FeedbackNexus(vector, slot) {
     759             :     DCHECK_EQ(FeedbackSlotKind::kTypeProfile, vector->GetKind(slot));
     760          98 :   }
     761             : 
     762             :   // Add a type to the list of types for source position <position>.
     763             :   void Collect(Handle<String> type, int position);
     764             :   JSObject* GetTypeProfile() const;
     765             : 
     766             :   InlineCacheState StateFromFeedback() const override;
     767             : };
     768             : 
     769             : inline BinaryOperationHint BinaryOperationHintFromFeedback(int type_feedback);
     770             : inline CompareOperationHint CompareOperationHintFromFeedback(int type_feedback);
     771             : 
     772             : }  // namespace internal
     773             : }  // namespace v8
     774             : 
     775             : #endif  // V8_FEEDBACK_VECTOR_H_

Generated by: LCOV version 1.10