| 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/base/logging.h" | 10 #include "src/base/logging.h" |
| 11 #include "src/elements-kind.h" | 11 #include "src/elements-kind.h" |
| 12 #include "src/objects.h" | 12 #include "src/objects.h" |
| 13 #include "src/zone-containers.h" | 13 #include "src/zone-containers.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 | 17 |
| 18 | 18 |
| 19 enum class FeedbackVectorSlotKind { | 19 enum class FeedbackVectorSlotKind { |
| 20 // This kind means that the slot points to the middle of other slot | 20 // This kind means that the slot points to the middle of other slot |
| 21 // which occupies more than one feedback vector element. | 21 // which occupies more than one feedback vector element. |
| 22 // There must be no such slots in the system. | 22 // There must be no such slots in the system. |
| 23 INVALID, | 23 INVALID, |
| 24 | 24 |
| 25 CALL_IC, | 25 CALL_IC, |
| 26 CONSTRUCT_IC, |
| 26 LOAD_IC, | 27 LOAD_IC, |
| 27 KEYED_LOAD_IC, | 28 KEYED_LOAD_IC, |
| 28 STORE_IC, | 29 STORE_IC, |
| 29 KEYED_STORE_IC, | 30 KEYED_STORE_IC, |
| 30 | 31 |
| 31 // This is a general purpose slot that occupies one feedback vector element. | 32 // This is a general purpose slot that occupies one feedback vector element. |
| 32 GENERAL, | 33 GENERAL, |
| 33 | 34 |
| 34 KINDS_NUMBER // Last value indicating number of kinds. | 35 KINDS_NUMBER // Last value indicating number of kinds. |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 | 38 |
| 38 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind); | 39 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind); |
| 39 | 40 |
| 40 | 41 |
| 41 template <typename Derived> | 42 template <typename Derived> |
| 42 class FeedbackVectorSpecBase { | 43 class FeedbackVectorSpecBase { |
| 43 public: | 44 public: |
| 44 inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind); | 45 inline FeedbackVectorSlot AddSlot(FeedbackVectorSlotKind kind); |
| 45 | 46 |
| 46 FeedbackVectorSlot AddCallICSlot() { | 47 FeedbackVectorSlot AddCallICSlot() { |
| 47 return AddSlot(FeedbackVectorSlotKind::CALL_IC); | 48 return AddSlot(FeedbackVectorSlotKind::CALL_IC); |
| 48 } | 49 } |
| 49 | 50 |
| 51 FeedbackVectorSlot AddConstructICSlot() { |
| 52 return AddSlot(FeedbackVectorSlotKind::CONSTRUCT_IC); |
| 53 } |
| 54 |
| 50 FeedbackVectorSlot AddLoadICSlot() { | 55 FeedbackVectorSlot AddLoadICSlot() { |
| 51 return AddSlot(FeedbackVectorSlotKind::LOAD_IC); | 56 return AddSlot(FeedbackVectorSlotKind::LOAD_IC); |
| 52 } | 57 } |
| 53 | 58 |
| 54 FeedbackVectorSlot AddKeyedLoadICSlot() { | 59 FeedbackVectorSlot AddKeyedLoadICSlot() { |
| 55 return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC); | 60 return AddSlot(FeedbackVectorSlotKind::KEYED_LOAD_IC); |
| 56 } | 61 } |
| 57 | 62 |
| 58 FeedbackVectorSlot AddStoreICSlot() { | 63 FeedbackVectorSlot AddStoreICSlot() { |
| 59 return AddSlot(FeedbackVectorSlotKind::STORE_IC); | 64 return AddSlot(FeedbackVectorSlotKind::STORE_IC); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 #ifdef OBJECT_PRINT | 153 #ifdef OBJECT_PRINT |
| 149 // For gdb debugging. | 154 // For gdb debugging. |
| 150 void Print(); | 155 void Print(); |
| 151 #endif // OBJECT_PRINT | 156 #endif // OBJECT_PRINT |
| 152 | 157 |
| 153 DECLARE_PRINTER(TypeFeedbackMetadata) | 158 DECLARE_PRINTER(TypeFeedbackMetadata) |
| 154 | 159 |
| 155 static const char* Kind2String(FeedbackVectorSlotKind kind); | 160 static const char* Kind2String(FeedbackVectorSlotKind kind); |
| 156 | 161 |
| 157 private: | 162 private: |
| 158 static const int kFeedbackVectorSlotKindBits = 3; | 163 static const int kFeedbackVectorSlotKindBits = 4; |
| 159 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) < | 164 STATIC_ASSERT(static_cast<int>(FeedbackVectorSlotKind::KINDS_NUMBER) < |
| 160 (1 << kFeedbackVectorSlotKindBits)); | 165 (1 << kFeedbackVectorSlotKindBits)); |
| 161 | 166 |
| 162 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind); | 167 void SetKind(FeedbackVectorSlot slot, FeedbackVectorSlotKind kind); |
| 163 | 168 |
| 164 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits, | 169 typedef BitSetComputer<FeedbackVectorSlotKind, kFeedbackVectorSlotKindBits, |
| 165 kSmiValueSize, uint32_t> VectorICComputer; | 170 kSmiValueSize, uint32_t> VectorICComputer; |
| 166 | 171 |
| 167 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata); | 172 DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackMetadata); |
| 168 }; | 173 }; |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 // The reason for having a vector handle and a raw pointer is that we can and | 397 // The reason for having a vector handle and a raw pointer is that we can and |
| 393 // should use handles during IC miss, but not during GC when we clear ICs. If | 398 // should use handles during IC miss, but not during GC when we clear ICs. If |
| 394 // you have a handle to the vector that is better because more operations can | 399 // you have a handle to the vector that is better because more operations can |
| 395 // be done, like allocation. | 400 // be done, like allocation. |
| 396 Handle<TypeFeedbackVector> vector_handle_; | 401 Handle<TypeFeedbackVector> vector_handle_; |
| 397 TypeFeedbackVector* vector_; | 402 TypeFeedbackVector* vector_; |
| 398 FeedbackVectorSlot slot_; | 403 FeedbackVectorSlot slot_; |
| 399 }; | 404 }; |
| 400 | 405 |
| 401 | 406 |
| 402 class CallICNexus final : public FeedbackNexus { | 407 class CallICNexus : public FeedbackNexus { |
| 403 public: | 408 public: |
| 404 // Monomorphic call ics store call counts. Platform code needs to increment | 409 // Monomorphic call ics store call counts. Platform code needs to increment |
| 405 // the count appropriately (ie, by 2). | 410 // the count appropriately (ie, by 2). |
| 406 static const int kCallCountIncrement = 2; | 411 static const int kCallCountIncrement = 2; |
| 407 | 412 |
| 408 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) | 413 CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) |
| 409 : FeedbackNexus(vector, slot) { | 414 : FeedbackNexus(vector, slot) { |
| 410 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot)); | 415 DCHECK(vector->GetKind(slot) == FeedbackVectorSlotKind::CALL_IC || |
| 416 vector->GetKind(slot) == FeedbackVectorSlotKind::CONSTRUCT_IC); |
| 411 } | 417 } |
| 412 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot) | 418 CallICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot) |
| 413 : FeedbackNexus(vector, slot) { | 419 : FeedbackNexus(vector, slot) { |
| 414 DCHECK_EQ(FeedbackVectorSlotKind::CALL_IC, vector->GetKind(slot)); | 420 DCHECK(vector->GetKind(slot) == FeedbackVectorSlotKind::CALL_IC || |
| 421 vector->GetKind(slot) == FeedbackVectorSlotKind::CONSTRUCT_IC); |
| 415 } | 422 } |
| 416 | 423 |
| 417 void Clear(Code* host); | 424 void Clear(Code* host); |
| 418 | 425 |
| 419 void ConfigureMonomorphicArray(); | 426 void ConfigureMonomorphicArray(); |
| 420 void ConfigureMonomorphic(Handle<JSFunction> function); | 427 void ConfigureMonomorphic(Handle<JSFunction> function); |
| 421 void ConfigureMegamorphic() final; | 428 void ConfigureMegamorphic() final; |
| 422 void ConfigureMegamorphic(int call_count); | 429 void ConfigureMegamorphic(int call_count); |
| 423 | 430 |
| 424 InlineCacheState StateFromFeedback() const final; | 431 InlineCacheState StateFromFeedback() const final; |
| 425 | 432 |
| 426 int ExtractMaps(MapHandleList* maps) const final { | 433 int ExtractMaps(MapHandleList* maps) const final { |
| 427 // CallICs don't record map feedback. | 434 // CallICs don't record map feedback. |
| 428 return 0; | 435 return 0; |
| 429 } | 436 } |
| 430 MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final { | 437 MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const final { |
| 431 return MaybeHandle<Code>(); | 438 return MaybeHandle<Code>(); |
| 432 } | 439 } |
| 433 bool FindHandlers(CodeHandleList* code_list, int length = -1) const final { | 440 bool FindHandlers(CodeHandleList* code_list, int length = -1) const final { |
| 434 return length == 0; | 441 return length == 0; |
| 435 } | 442 } |
| 436 | 443 |
| 444 Handle<Object> GetCallFeedback(); |
| 437 int ExtractCallCount(); | 445 int ExtractCallCount(); |
| 438 }; | 446 }; |
| 439 | 447 |
| 440 | 448 |
| 449 class ConstructICNexus final : public CallICNexus { |
| 450 public: |
| 451 ConstructICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) |
| 452 : CallICNexus(vector, slot) {} |
| 453 ConstructICNexus(TypeFeedbackVector* vector, FeedbackVectorSlot slot) |
| 454 : CallICNexus(vector, slot) {} |
| 455 |
| 456 void Clear(Code* host); |
| 457 }; |
| 458 |
| 459 |
| 441 class LoadICNexus : public FeedbackNexus { | 460 class LoadICNexus : public FeedbackNexus { |
| 442 public: | 461 public: |
| 443 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) | 462 LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot) |
| 444 : FeedbackNexus(vector, slot) { | 463 : FeedbackNexus(vector, slot) { |
| 445 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot)); | 464 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_IC, vector->GetKind(slot)); |
| 446 } | 465 } |
| 447 explicit LoadICNexus(Isolate* isolate) | 466 explicit LoadICNexus(Isolate* isolate) |
| 448 : FeedbackNexus( | 467 : FeedbackNexus( |
| 449 TypeFeedbackVector::DummyVector(isolate), | 468 TypeFeedbackVector::DummyVector(isolate), |
| 450 FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {} | 469 FeedbackVectorSlot(TypeFeedbackVector::kDummyLoadICSlot)) {} |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 KeyedAccessStoreMode GetKeyedAccessStoreMode() const; | 562 KeyedAccessStoreMode GetKeyedAccessStoreMode() const; |
| 544 IcCheckType GetKeyType() const; | 563 IcCheckType GetKeyType() const; |
| 545 | 564 |
| 546 InlineCacheState StateFromFeedback() const override; | 565 InlineCacheState StateFromFeedback() const override; |
| 547 Name* FindFirstName() const override; | 566 Name* FindFirstName() const override; |
| 548 }; | 567 }; |
| 549 } // namespace internal | 568 } // namespace internal |
| 550 } // namespace v8 | 569 } // namespace v8 |
| 551 | 570 |
| 552 #endif // V8_TRANSITIONS_H_ | 571 #endif // V8_TRANSITIONS_H_ |
| OLD | NEW |