| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ | 5 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_ | 
| 6 #define V8_TYPE_FEEDBACK_VECTOR_H_ | 6 #define V8_TYPE_FEEDBACK_VECTOR_H_ | 
| 7 | 7 | 
| 8 #include <vector> | 8 #include <vector> | 
| 9 | 9 | 
| 10 #include "src/checks.h" | 10 #include "src/checks.h" | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 67   static TypeFeedbackVector* cast(Object* obj) { | 67   static TypeFeedbackVector* cast(Object* obj) { | 
| 68     DCHECK(obj->IsTypeFeedbackVector()); | 68     DCHECK(obj->IsTypeFeedbackVector()); | 
| 69     return reinterpret_cast<TypeFeedbackVector*>(obj); | 69     return reinterpret_cast<TypeFeedbackVector*>(obj); | 
| 70   } | 70   } | 
| 71 | 71 | 
| 72   static const int kReservedIndexCount = 3; | 72   static const int kReservedIndexCount = 3; | 
| 73   static const int kFirstICSlotIndex = 0; | 73   static const int kFirstICSlotIndex = 0; | 
| 74   static const int kWithTypesIndex = 1; | 74   static const int kWithTypesIndex = 1; | 
| 75   static const int kGenericCountIndex = 2; | 75   static const int kGenericCountIndex = 2; | 
| 76 | 76 | 
|  | 77   static int elements_per_ic_slot() { return FLAG_vector_ics ? 2 : 1; } | 
|  | 78 | 
| 77   int first_ic_slot_index() const { | 79   int first_ic_slot_index() const { | 
| 78     DCHECK(length() >= kReservedIndexCount); | 80     DCHECK(length() >= kReservedIndexCount); | 
| 79     return Smi::cast(get(kFirstICSlotIndex))->value(); | 81     return Smi::cast(get(kFirstICSlotIndex))->value(); | 
| 80   } | 82   } | 
| 81 | 83 | 
| 82   int ic_with_type_info_count() { | 84   int ic_with_type_info_count() { | 
| 83     return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 85     return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0; | 
| 84   } | 86   } | 
| 85 | 87 | 
| 86   void change_ic_with_type_info_count(int delta) { | 88   void change_ic_with_type_info_count(int delta) { | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 107   inline int ic_metadata_length() const; | 109   inline int ic_metadata_length() const; | 
| 108 | 110 | 
| 109   int Slots() const { | 111   int Slots() const { | 
| 110     if (length() == 0) return 0; | 112     if (length() == 0) return 0; | 
| 111     return Max( | 113     return Max( | 
| 112         0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount); | 114         0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount); | 
| 113   } | 115   } | 
| 114 | 116 | 
| 115   int ICSlots() const { | 117   int ICSlots() const { | 
| 116     if (length() == 0) return 0; | 118     if (length() == 0) return 0; | 
| 117     return length() - first_ic_slot_index(); | 119     return (length() - first_ic_slot_index()) / elements_per_ic_slot(); | 
| 118   } | 120   } | 
| 119 | 121 | 
| 120   // Conversion from a slot or ic slot to an integer index to the underlying | 122   // Conversion from a slot or ic slot to an integer index to the underlying | 
| 121   // array. | 123   // array. | 
| 122   int GetIndex(FeedbackVectorSlot slot) const { | 124   int GetIndex(FeedbackVectorSlot slot) const { | 
| 123     DCHECK(slot.ToInt() < first_ic_slot_index()); | 125     DCHECK(slot.ToInt() < first_ic_slot_index()); | 
| 124     return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); | 126     return kReservedIndexCount + ic_metadata_length() + slot.ToInt(); | 
| 125   } | 127   } | 
| 126 | 128 | 
| 127   int GetIndex(FeedbackVectorICSlot slot) const { | 129   int GetIndex(FeedbackVectorICSlot slot) const { | 
| 128     int first_ic_slot = first_ic_slot_index(); | 130     int first_ic_slot = first_ic_slot_index(); | 
| 129     DCHECK(slot.ToInt() < ICSlots()); | 131     DCHECK(slot.ToInt() < ICSlots()); | 
| 130     return first_ic_slot + slot.ToInt(); | 132     return first_ic_slot + slot.ToInt() * elements_per_ic_slot(); | 
| 131   } | 133   } | 
| 132 | 134 | 
| 133   // Conversion from an integer index to either a slot or an ic slot. The caller | 135   // Conversion from an integer index to either a slot or an ic slot. The caller | 
| 134   // should know what kind she expects. | 136   // should know what kind she expects. | 
| 135   FeedbackVectorSlot ToSlot(int index) const { | 137   FeedbackVectorSlot ToSlot(int index) const { | 
| 136     DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); | 138     DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index()); | 
| 137     return FeedbackVectorSlot(index - ic_metadata_length() - | 139     return FeedbackVectorSlot(index - ic_metadata_length() - | 
| 138                               kReservedIndexCount); | 140                               kReservedIndexCount); | 
| 139   } | 141   } | 
| 140 | 142 | 
| 141   FeedbackVectorICSlot ToICSlot(int index) const { | 143   FeedbackVectorICSlot ToICSlot(int index) const { | 
| 142     DCHECK(index >= first_ic_slot_index() && index < length()); | 144     DCHECK(index >= first_ic_slot_index() && index < length()); | 
| 143     return FeedbackVectorICSlot(index - first_ic_slot_index()); | 145     int ic_slot = (index - first_ic_slot_index()) / elements_per_ic_slot(); | 
|  | 146     return FeedbackVectorICSlot(ic_slot); | 
| 144   } | 147   } | 
| 145 | 148 | 
| 146   Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); } | 149   Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); } | 
| 147   void Set(FeedbackVectorSlot slot, Object* value, | 150   void Set(FeedbackVectorSlot slot, Object* value, | 
| 148            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 151            WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 
| 149     set(GetIndex(slot), value, mode); | 152     set(GetIndex(slot), value, mode); | 
| 150   } | 153   } | 
| 151 | 154 | 
| 152   Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } | 155   Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); } | 
| 153   void Set(FeedbackVectorICSlot slot, Object* value, | 156   void Set(FeedbackVectorICSlot slot, Object* value, | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 237     MapHandleList maps; | 240     MapHandleList maps; | 
| 238     ExtractMaps(&maps); | 241     ExtractMaps(&maps); | 
| 239     if (maps.length() > 0) return *maps.at(0); | 242     if (maps.length() > 0) return *maps.at(0); | 
| 240     return NULL; | 243     return NULL; | 
| 241   } | 244   } | 
| 242 | 245 | 
| 243   // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review. | 246   // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review. | 
| 244   void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); } | 247   void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); } | 
| 245 | 248 | 
| 246   virtual InlineCacheState StateFromFeedback() const = 0; | 249   virtual InlineCacheState StateFromFeedback() const = 0; | 
| 247   virtual int ExtractMaps(MapHandleList* maps) const = 0; | 250   virtual int ExtractMaps(MapHandleList* maps) const; | 
| 248   virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0; | 251   virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const; | 
| 249   virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const { | 252   virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const; | 
| 250     return length == 0; |  | 
| 251   } |  | 
| 252   virtual Name* FindFirstName() const { return NULL; } | 253   virtual Name* FindFirstName() const { return NULL; } | 
| 253 | 254 | 
| 254   Object* GetFeedback() const { return vector()->Get(slot()); } | 255   Object* GetFeedback() const { return vector()->Get(slot()); } | 
|  | 256   Object* GetFeedbackExtra() const { | 
|  | 257     DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1); | 
|  | 258     int extra_index = vector()->GetIndex(slot()) + 1; | 
|  | 259     return vector()->get(extra_index); | 
|  | 260   } | 
| 255 | 261 | 
| 256  protected: | 262  protected: | 
| 257   Isolate* GetIsolate() const { return vector()->GetIsolate(); } | 263   Isolate* GetIsolate() const { return vector()->GetIsolate(); } | 
| 258 | 264 | 
| 259   void SetFeedback(Object* feedback, | 265   void SetFeedback(Object* feedback, | 
| 260                    WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 266                    WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 
| 261     vector()->Set(slot(), feedback, mode); | 267     vector()->Set(slot(), feedback, mode); | 
| 262   } | 268   } | 
| 263 | 269 | 
|  | 270   void SetFeedbackExtra(Object* feedback_extra, | 
|  | 271                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER) { | 
|  | 272     DCHECK(TypeFeedbackVector::elements_per_ic_slot() > 1); | 
|  | 273     int index = vector()->GetIndex(slot()) + 1; | 
|  | 274     vector()->set(index, feedback_extra, mode); | 
|  | 275   } | 
|  | 276 | 
| 264   Handle<FixedArray> EnsureArrayOfSize(int length); | 277   Handle<FixedArray> EnsureArrayOfSize(int length); | 
| 265   void InstallHandlers(int start_index, MapHandleList* maps, | 278   Handle<FixedArray> EnsureExtraArrayOfSize(int length); | 
|  | 279   void InstallHandlers(Handle<FixedArray> array, MapHandleList* maps, | 
| 266                        CodeHandleList* handlers); | 280                        CodeHandleList* handlers); | 
| 267   int ExtractMaps(int start_index, MapHandleList* maps) const; |  | 
| 268   MaybeHandle<Code> FindHandlerForMap(int start_index, Handle<Map> map) const; |  | 
| 269   bool FindHandlers(int start_index, CodeHandleList* code_list, |  | 
| 270                     int length) const; |  | 
| 271 | 281 | 
| 272  private: | 282  private: | 
| 273   // The reason for having a vector handle and a raw pointer is that we can and | 283   // The reason for having a vector handle and a raw pointer is that we can and | 
| 274   // should use handles during IC miss, but not during GC when we clear ICs. If | 284   // should use handles during IC miss, but not during GC when we clear ICs. If | 
| 275   // you have a handle to the vector that is better because more operations can | 285   // you have a handle to the vector that is better because more operations can | 
| 276   // be done, like allocation. | 286   // be done, like allocation. | 
| 277   Handle<TypeFeedbackVector> vector_handle_; | 287   Handle<TypeFeedbackVector> vector_handle_; | 
| 278   TypeFeedbackVector* vector_; | 288   TypeFeedbackVector* vector_; | 
| 279   FeedbackVectorICSlot slot_; | 289   FeedbackVectorICSlot slot_; | 
| 280 }; | 290 }; | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 327 | 337 | 
| 328   void Clear(Code* host); | 338   void Clear(Code* host); | 
| 329 | 339 | 
| 330   void ConfigureMegamorphic(); | 340   void ConfigureMegamorphic(); | 
| 331   void ConfigurePremonomorphic(); | 341   void ConfigurePremonomorphic(); | 
| 332   void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); | 342   void ConfigureMonomorphic(Handle<Map> receiver_map, Handle<Code> handler); | 
| 333 | 343 | 
| 334   void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); | 344   void ConfigurePolymorphic(MapHandleList* maps, CodeHandleList* handlers); | 
| 335 | 345 | 
| 336   InlineCacheState StateFromFeedback() const OVERRIDE; | 346   InlineCacheState StateFromFeedback() const OVERRIDE; | 
| 337   int ExtractMaps(MapHandleList* maps) const OVERRIDE; |  | 
| 338   MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE; |  | 
| 339   virtual bool FindHandlers(CodeHandleList* code_list, |  | 
| 340                             int length = -1) const OVERRIDE; |  | 
| 341 }; | 347 }; | 
| 342 | 348 | 
| 343 | 349 | 
| 344 class KeyedLoadICNexus : public FeedbackNexus { | 350 class KeyedLoadICNexus : public FeedbackNexus { | 
| 345  public: | 351  public: | 
| 346   KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) | 352   KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot) | 
| 347       : FeedbackNexus(vector, slot) { | 353       : FeedbackNexus(vector, slot) { | 
| 348     DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); | 354     DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); | 
| 349   } | 355   } | 
| 350   KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) | 356   KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot) | 
| 351       : FeedbackNexus(vector, slot) { | 357       : FeedbackNexus(vector, slot) { | 
| 352     DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); | 358     DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); | 
| 353   } | 359   } | 
| 354 | 360 | 
| 355   void Clear(Code* host); | 361   void Clear(Code* host); | 
| 356 | 362 | 
| 357   void ConfigureMegamorphic(); | 363   void ConfigureMegamorphic(); | 
| 358   void ConfigurePremonomorphic(); | 364   void ConfigurePremonomorphic(); | 
| 359   // name can be a null handle for element loads. | 365   // name can be a null handle for element loads. | 
| 360   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, | 366   void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, | 
| 361                             Handle<Code> handler); | 367                             Handle<Code> handler); | 
| 362   // name can be null. | 368   // name can be null. | 
| 363   void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, | 369   void ConfigurePolymorphic(Handle<Name> name, MapHandleList* maps, | 
| 364                             CodeHandleList* handlers); | 370                             CodeHandleList* handlers); | 
| 365 | 371 | 
| 366   InlineCacheState StateFromFeedback() const OVERRIDE; | 372   InlineCacheState StateFromFeedback() const OVERRIDE; | 
| 367   int ExtractMaps(MapHandleList* maps) const OVERRIDE; |  | 
| 368   MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE; |  | 
| 369   virtual bool FindHandlers(CodeHandleList* code_list, |  | 
| 370                             int length = -1) const OVERRIDE; |  | 
| 371   Name* FindFirstName() const OVERRIDE; | 373   Name* FindFirstName() const OVERRIDE; | 
| 372 }; | 374 }; | 
| 373 } | 375 } | 
| 374 }  // namespace v8::internal | 376 }  // namespace v8::internal | 
| 375 | 377 | 
| 376 #endif  // V8_TRANSITIONS_H_ | 378 #endif  // V8_TRANSITIONS_H_ | 
| OLD | NEW | 
|---|