| 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 "src/checks.h" |    8 #include "src/checks.h" | 
|    9 #include "src/elements-kind.h" |    9 #include "src/elements-kind.h" | 
|   10 #include "src/heap/heap.h" |   10 #include "src/heap/heap.h" | 
|   11 #include "src/isolate.h" |   11 #include "src/isolate.h" | 
|   12 #include "src/objects.h" |   12 #include "src/objects.h" | 
|   13  |   13  | 
|   14 namespace v8 { |   14 namespace v8 { | 
|   15 namespace internal { |   15 namespace internal { | 
|   16  |   16  | 
|   17 // The shape of the TypeFeedbackVector is an array with: |   17 // The shape of the TypeFeedbackVector is an array with: | 
|   18 // 0: first_ic_slot_index (== length() if no ic slots are present) |   18 // 0: first_ic_slot_index (== length() if no ic slots are present) | 
|   19 // 1: ics_with_types |   19 // 1: ics_with_types | 
|   20 // 2: ics_with_generic_info |   20 // 2: ics_with_generic_info | 
|   21 // 3: first feedback slot |   21 // 3: type information for ic slots, if any | 
 |   22 // ... | 
 |   23 // N: first feedback slot (N >= 3) | 
|   22 // ... |   24 // ... | 
|   23 // [<first_ic_slot_index>: feedback slot] |   25 // [<first_ic_slot_index>: feedback slot] | 
|   24 // ...to length() - 1 |   26 // ...to length() - 1 | 
|   25 // |   27 // | 
|   26 class TypeFeedbackVector : public FixedArray { |   28 class TypeFeedbackVector : public FixedArray { | 
|   27  public: |   29  public: | 
|   28   // Casting. |   30   // Casting. | 
|   29   static TypeFeedbackVector* cast(Object* obj) { |   31   static TypeFeedbackVector* cast(Object* obj) { | 
|   30     DCHECK(obj->IsTypeFeedbackVector()); |   32     DCHECK(obj->IsTypeFeedbackVector()); | 
|   31     return reinterpret_cast<TypeFeedbackVector*>(obj); |   33     return reinterpret_cast<TypeFeedbackVector*>(obj); | 
|   32   } |   34   } | 
|   33  |   35  | 
|   34   static const int kReservedIndexCount = 3; |   36   static const int kReservedIndexCount = 3; | 
|   35   static const int kFirstICSlotIndex = 0; |   37   static const int kFirstICSlotIndex = 0; | 
|   36   static const int kWithTypesIndex = 1; |   38   static const int kWithTypesIndex = 1; | 
|   37   static const int kGenericCountIndex = 2; |   39   static const int kGenericCountIndex = 2; | 
|   38  |   40  | 
|   39   int first_ic_slot_index() { |   41   int first_ic_slot_index() const { | 
|   40     DCHECK(length() >= kReservedIndexCount); |   42     DCHECK(length() >= kReservedIndexCount); | 
|   41     return Smi::cast(get(kFirstICSlotIndex))->value(); |   43     return Smi::cast(get(kFirstICSlotIndex))->value(); | 
|   42   } |   44   } | 
|   43  |   45  | 
|   44   int ic_with_type_info_count() { |   46   int ic_with_type_info_count() { | 
|   45     return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; |   47     return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 
|   46   } |   48   } | 
|   47  |   49  | 
|   48   void change_ic_with_type_info_count(int delta) { |   50   void change_ic_with_type_info_count(int delta) { | 
|   49     if (delta == 0) return; |   51     if (delta == 0) return; | 
|   50     int value = ic_with_type_info_count() + delta; |   52     int value = ic_with_type_info_count() + delta; | 
|   51     // Could go negative because of the debugger. |   53     // Could go negative because of the debugger. | 
|   52     if (value >= 0) { |   54     if (value >= 0) { | 
|   53       set(kWithTypesIndex, Smi::FromInt(value)); |   55       set(kWithTypesIndex, Smi::FromInt(value)); | 
|   54     } |   56     } | 
|   55   } |   57   } | 
|   56  |   58  | 
|   57   int ic_generic_count() { |   59   int ic_generic_count() { | 
|   58     return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; |   60     return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0; | 
|   59   } |   61   } | 
|   60  |   62  | 
|   61   void change_ic_generic_count(int delta) { |   63   void change_ic_generic_count(int delta) { | 
|   62     if (delta == 0) return; |   64     if (delta == 0) return; | 
|   63     int value = ic_generic_count() + delta; |   65     int value = ic_generic_count() + delta; | 
|   64     if (value >= 0) { |   66     if (value >= 0) { | 
|   65       set(kGenericCountIndex, Smi::FromInt(value)); |   67       set(kGenericCountIndex, Smi::FromInt(value)); | 
|   66     } |   68     } | 
|   67   } |   69   } | 
|   68  |   70  | 
|   69   int Slots() { |   71   inline int ic_metadata_length() const; | 
 |   72  | 
 |   73   int Slots() const { | 
|   70     if (length() == 0) return 0; |   74     if (length() == 0) return 0; | 
|   71     return Max(0, first_ic_slot_index() - kReservedIndexCount); |   75     return Max( | 
 |   76         0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount); | 
|   72   } |   77   } | 
|   73  |   78  | 
|   74   int ICSlots() { |   79   int ICSlots() const { | 
|   75     if (length() == 0) return 0; |   80     if (length() == 0) return 0; | 
|   76     return length() - first_ic_slot_index(); |   81     return length() - first_ic_slot_index(); | 
|   77   } |   82   } | 
|   78  |   83  | 
|   79   // Conversion from a slot or ic slot to an integer index to the underlying |   84   // Conversion from a slot or ic slot to an integer index to the underlying | 
|   80   // array. |   85   // array. | 
|   81   int GetIndex(FeedbackVectorSlot slot) { |   86   int GetIndex(FeedbackVectorSlot slot) const { | 
|   82     return kReservedIndexCount + slot.ToInt(); |   87     return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); | 
|   83   } |   88   } | 
|   84  |   89  | 
|   85   int GetIndex(FeedbackVectorICSlot slot) { |   90   int GetIndex(FeedbackVectorICSlot slot) const { | 
|   86     int first_ic_slot = first_ic_slot_index(); |   91     int first_ic_slot = first_ic_slot_index(); | 
|   87     DCHECK(slot.ToInt() < ICSlots()); |   92     DCHECK(slot.ToInt() < ICSlots()); | 
|   88     return first_ic_slot + slot.ToInt(); |   93     return first_ic_slot + slot.ToInt(); | 
|   89   } |   94   } | 
|   90  |   95  | 
|   91  |  | 
|   92   // Conversion from an integer index to either a slot or an ic slot. The caller |   96   // Conversion from an integer index to either a slot or an ic slot. The caller | 
|   93   // should know what kind she expects. |   97   // should know what kind she expects. | 
|   94   FeedbackVectorSlot ToSlot(int index) { |   98   FeedbackVectorSlot ToSlot(int index) const { | 
|   95     DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); |   99     DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); | 
|   96     return FeedbackVectorSlot(index - kReservedIndexCount); |  100     return FeedbackVectorSlot(index - ic_metadata_length() - | 
 |  101                               kReservedIndexCount); | 
|   97   } |  102   } | 
|   98  |  103  | 
|   99   FeedbackVectorICSlot ToICSlot(int index) { |  104   FeedbackVectorICSlot ToICSlot(int index) const { | 
|  100     DCHECK(index >= first_ic_slot_index() && index < length()); |  105     DCHECK(index >= first_ic_slot_index() && index < length()); | 
|  101     return FeedbackVectorICSlot(index - first_ic_slot_index()); |  106     return FeedbackVectorICSlot(index - first_ic_slot_index()); | 
|  102   } |  107   } | 
|  103  |  108  | 
|  104   Object* Get(FeedbackVectorSlot slot) { return get(GetIndex(slot)); } |  109   Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); } | 
|  105   void Set(FeedbackVectorSlot slot, Object* value, |  110   void Set(FeedbackVectorSlot slot, Object* value, | 
|  106            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |  111            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 
|  107     set(GetIndex(slot), value, mode); |  112     set(GetIndex(slot), value, mode); | 
|  108   } |  113   } | 
|  109  |  114  | 
|  110   Object* Get(FeedbackVectorICSlot slot) { return get(GetIndex(slot)); } |  115   Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } | 
|  111   void Set(FeedbackVectorICSlot slot, Object* value, |  116   void Set(FeedbackVectorICSlot slot, Object* value, | 
|  112            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { |  117            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 
|  113     set(GetIndex(slot), value, mode); |  118     set(GetIndex(slot), value, mode); | 
|  114   } |  119   } | 
|  115  |  120  | 
 |  121   // IC slots need metadata to recognize the type of IC. Set a Kind for every | 
 |  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; | 
 |  128   void SetKind(FeedbackVectorICSlot slot, Code::Kind kind); | 
|  116  |  129  | 
|  117   static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, |  130   static Handle<TypeFeedbackVector> Allocate(Isolate* isolate, int slot_count, | 
|  118                                              int ic_slot_count); |  131                                              int ic_slot_count); | 
|  119  |  132  | 
|  120   static Handle<TypeFeedbackVector> Copy(Isolate* isolate, |  133   static Handle<TypeFeedbackVector> Copy(Isolate* isolate, | 
|  121                                          Handle<TypeFeedbackVector> vector); |  134                                          Handle<TypeFeedbackVector> vector); | 
|  122  |  135  | 
|  123   // Clears the vector slots and the vector ic slots. |  136   // Clears the vector slots and the vector ic slots. | 
|  124   void ClearSlots(SharedFunctionInfo* shared); |  137   void ClearSlots(SharedFunctionInfo* shared); | 
|  125  |  138  | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  138   // The object that indicates a monomorphic state of Array with |  151   // The object that indicates a monomorphic state of Array with | 
|  139   // ElementsKind |  152   // ElementsKind | 
|  140   static inline Handle<Object> MonomorphicArraySentinel( |  153   static inline Handle<Object> MonomorphicArraySentinel( | 
|  141       Isolate* isolate, ElementsKind elements_kind); |  154       Isolate* isolate, ElementsKind elements_kind); | 
|  142  |  155  | 
|  143   // A raw version of the uninitialized sentinel that's safe to read during |  156   // A raw version of the uninitialized sentinel that's safe to read during | 
|  144   // garbage collection (e.g., for patching the cache). |  157   // garbage collection (e.g., for patching the cache). | 
|  145   static inline Object* RawUninitializedSentinel(Heap* heap); |  158   static inline Object* RawUninitializedSentinel(Heap* heap); | 
|  146  |  159  | 
|  147  private: |  160  private: | 
 |  161   enum VectorICKind { | 
 |  162     KindUnused = 0x0, | 
 |  163     KindCallIC = 0x1, | 
 |  164     KindLoadIC = 0x2, | 
 |  165     KindKeyedLoadIC = 0x3 | 
 |  166   }; | 
 |  167  | 
 |  168   static const int kVectorICKindBits = 2; | 
 |  169   static VectorICKind FromCodeKind(Code::Kind kind); | 
 |  170   static Code::Kind FromVectorICKind(VectorICKind kind); | 
 |  171   typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize, | 
 |  172                          uint32_t> VectorICComputer; | 
 |  173  | 
|  148   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); |  174   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector); | 
|  149 }; |  175 }; | 
|  150 } |  176 } | 
|  151 }  // namespace v8::internal |  177 }  // namespace v8::internal | 
|  152  |  178  | 
|  153 #endif  // V8_TRANSITIONS_H_ |  179 #endif  // V8_TRANSITIONS_H_ | 
| OLD | NEW |