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