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 |