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 |