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