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 #include "src/type-feedback-vector.h" | 5 #include "src/type-feedback-vector.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
9 #include "src/ic/ic-state.h" | 9 #include "src/ic/ic-state.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 } | 132 } |
133 | 133 |
134 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { | 134 const char* TypeFeedbackMetadata::Kind2String(FeedbackVectorSlotKind kind) { |
135 switch (kind) { | 135 switch (kind) { |
136 case FeedbackVectorSlotKind::INVALID: | 136 case FeedbackVectorSlotKind::INVALID: |
137 return "INVALID"; | 137 return "INVALID"; |
138 case FeedbackVectorSlotKind::CALL_IC: | 138 case FeedbackVectorSlotKind::CALL_IC: |
139 return "CALL_IC"; | 139 return "CALL_IC"; |
140 case FeedbackVectorSlotKind::LOAD_IC: | 140 case FeedbackVectorSlotKind::LOAD_IC: |
141 return "LOAD_IC"; | 141 return "LOAD_IC"; |
| 142 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: |
| 143 return "LOAD_GLOBAL_IC"; |
142 case FeedbackVectorSlotKind::KEYED_LOAD_IC: | 144 case FeedbackVectorSlotKind::KEYED_LOAD_IC: |
143 return "KEYED_LOAD_IC"; | 145 return "KEYED_LOAD_IC"; |
144 case FeedbackVectorSlotKind::STORE_IC: | 146 case FeedbackVectorSlotKind::STORE_IC: |
145 return "STORE_IC"; | 147 return "STORE_IC"; |
146 case FeedbackVectorSlotKind::KEYED_STORE_IC: | 148 case FeedbackVectorSlotKind::KEYED_STORE_IC: |
147 return "KEYED_STORE_IC"; | 149 return "KEYED_STORE_IC"; |
148 case FeedbackVectorSlotKind::GENERAL: | 150 case FeedbackVectorSlotKind::GENERAL: |
149 return "STUB"; | 151 return "STUB"; |
150 case FeedbackVectorSlotKind::KINDS_NUMBER: | 152 case FeedbackVectorSlotKind::KINDS_NUMBER: |
151 break; | 153 break; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 case FeedbackVectorSlotKind::CALL_IC: { | 231 case FeedbackVectorSlotKind::CALL_IC: { |
230 CallICNexus nexus(this, slot); | 232 CallICNexus nexus(this, slot); |
231 nexus.Clear(shared->code()); | 233 nexus.Clear(shared->code()); |
232 break; | 234 break; |
233 } | 235 } |
234 case FeedbackVectorSlotKind::LOAD_IC: { | 236 case FeedbackVectorSlotKind::LOAD_IC: { |
235 LoadICNexus nexus(this, slot); | 237 LoadICNexus nexus(this, slot); |
236 nexus.Clear(shared->code()); | 238 nexus.Clear(shared->code()); |
237 break; | 239 break; |
238 } | 240 } |
| 241 case FeedbackVectorSlotKind::LOAD_GLOBAL_IC: { |
| 242 LoadGlobalICNexus nexus(this, slot); |
| 243 nexus.Clear(shared->code()); |
| 244 break; |
| 245 } |
239 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { | 246 case FeedbackVectorSlotKind::KEYED_LOAD_IC: { |
240 KeyedLoadICNexus nexus(this, slot); | 247 KeyedLoadICNexus nexus(this, slot); |
241 nexus.Clear(shared->code()); | 248 nexus.Clear(shared->code()); |
242 break; | 249 break; |
243 } | 250 } |
244 case FeedbackVectorSlotKind::STORE_IC: { | 251 case FeedbackVectorSlotKind::STORE_IC: { |
245 StoreICNexus nexus(this, slot); | 252 StoreICNexus nexus(this, slot); |
246 nexus.Clear(shared->code()); | 253 nexus.Clear(shared->code()); |
247 break; | 254 break; |
248 } | 255 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // cleared. | 437 // cleared. |
431 return POLYMORPHIC; | 438 return POLYMORPHIC; |
432 } else if (feedback->IsWeakCell()) { | 439 } else if (feedback->IsWeakCell()) { |
433 // Don't check if the map is cleared. | 440 // Don't check if the map is cleared. |
434 return MONOMORPHIC; | 441 return MONOMORPHIC; |
435 } | 442 } |
436 | 443 |
437 return UNINITIALIZED; | 444 return UNINITIALIZED; |
438 } | 445 } |
439 | 446 |
| 447 InlineCacheState LoadGlobalICNexus::StateFromFeedback() const { |
| 448 Isolate* isolate = GetIsolate(); |
| 449 Object* feedback = GetFeedback(); |
| 450 |
| 451 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { |
| 452 return UNINITIALIZED; |
| 453 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
| 454 return MEGAMORPHIC; |
| 455 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { |
| 456 return PREMONOMORPHIC; |
| 457 } else if (feedback->IsFixedArray()) { |
| 458 // Determine state purely by our structure, don't check if the maps are |
| 459 // cleared. |
| 460 return POLYMORPHIC; |
| 461 } else if (feedback->IsWeakCell()) { |
| 462 // Don't check if the map is cleared. |
| 463 return MONOMORPHIC; |
| 464 } |
| 465 |
| 466 return UNINITIALIZED; |
| 467 } |
440 | 468 |
441 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { | 469 InlineCacheState KeyedLoadICNexus::StateFromFeedback() const { |
442 Isolate* isolate = GetIsolate(); | 470 Isolate* isolate = GetIsolate(); |
443 Object* feedback = GetFeedback(); | 471 Object* feedback = GetFeedback(); |
444 | 472 |
445 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { | 473 if (feedback == *TypeFeedbackVector::UninitializedSentinel(isolate)) { |
446 return UNINITIALIZED; | 474 return UNINITIALIZED; |
447 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { | 475 } else if (feedback == *TypeFeedbackVector::PremonomorphicSentinel(isolate)) { |
448 return PREMONOMORPHIC; | 476 return PREMONOMORPHIC; |
449 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { | 477 } else if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate)) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 } | 604 } |
577 | 605 |
578 | 606 |
579 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, | 607 void LoadICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, |
580 Handle<Code> handler) { | 608 Handle<Code> handler) { |
581 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 609 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
582 SetFeedback(*cell); | 610 SetFeedback(*cell); |
583 SetFeedbackExtra(*handler); | 611 SetFeedbackExtra(*handler); |
584 } | 612 } |
585 | 613 |
| 614 void LoadGlobalICNexus::ConfigureMonomorphic(Handle<Map> receiver_map, |
| 615 Handle<Code> handler) { |
| 616 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
| 617 SetFeedback(*cell); |
| 618 SetFeedbackExtra(*handler); |
| 619 } |
586 | 620 |
587 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, | 621 void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name, |
588 Handle<Map> receiver_map, | 622 Handle<Map> receiver_map, |
589 Handle<Code> handler) { | 623 Handle<Code> handler) { |
590 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); | 624 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); |
591 if (name.is_null()) { | 625 if (name.is_null()) { |
592 SetFeedback(*cell); | 626 SetFeedback(*cell); |
593 SetFeedbackExtra(*handler); | 627 SetFeedbackExtra(*handler); |
594 } else { | 628 } else { |
595 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); | 629 Handle<FixedArray> array = EnsureExtraArrayOfSize(2); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, | 661 void LoadICNexus::ConfigurePolymorphic(MapHandleList* maps, |
628 CodeHandleList* handlers) { | 662 CodeHandleList* handlers) { |
629 Isolate* isolate = GetIsolate(); | 663 Isolate* isolate = GetIsolate(); |
630 int receiver_count = maps->length(); | 664 int receiver_count = maps->length(); |
631 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); | 665 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); |
632 InstallHandlers(array, maps, handlers); | 666 InstallHandlers(array, maps, handlers); |
633 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), | 667 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), |
634 SKIP_WRITE_BARRIER); | 668 SKIP_WRITE_BARRIER); |
635 } | 669 } |
636 | 670 |
| 671 void LoadGlobalICNexus::ConfigurePolymorphic(MapHandleList* maps, |
| 672 CodeHandleList* handlers) { |
| 673 Isolate* isolate = GetIsolate(); |
| 674 int receiver_count = maps->length(); |
| 675 Handle<FixedArray> array = EnsureArrayOfSize(receiver_count * 2); |
| 676 InstallHandlers(array, maps, handlers); |
| 677 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(isolate), |
| 678 SKIP_WRITE_BARRIER); |
| 679 } |
637 | 680 |
638 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, | 681 void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name, |
639 MapHandleList* maps, | 682 MapHandleList* maps, |
640 CodeHandleList* handlers) { | 683 CodeHandleList* handlers) { |
641 int receiver_count = maps->length(); | 684 int receiver_count = maps->length(); |
642 DCHECK(receiver_count > 1); | 685 DCHECK(receiver_count > 1); |
643 Handle<FixedArray> array; | 686 Handle<FixedArray> array; |
644 if (name.is_null()) { | 687 if (name.is_null()) { |
645 array = EnsureArrayOfSize(receiver_count * 2); | 688 array = EnsureArrayOfSize(receiver_count * 2); |
646 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), | 689 SetFeedbackExtra(*TypeFeedbackVector::UninitializedSentinel(GetIsolate()), |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 code_list->Add(handle(code)); | 864 code_list->Add(handle(code)); |
822 count++; | 865 count++; |
823 } | 866 } |
824 } | 867 } |
825 return count == length; | 868 return count == length; |
826 } | 869 } |
827 | 870 |
828 | 871 |
829 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } | 872 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } |
830 | 873 |
| 874 void LoadGlobalICNexus::Clear(Code* host) { |
| 875 LoadGlobalIC::Clear(GetIsolate(), host, this); |
| 876 } |
831 | 877 |
832 void KeyedLoadICNexus::Clear(Code* host) { | 878 void KeyedLoadICNexus::Clear(Code* host) { |
833 KeyedLoadIC::Clear(GetIsolate(), host, this); | 879 KeyedLoadIC::Clear(GetIsolate(), host, this); |
834 } | 880 } |
835 | 881 |
836 | 882 |
837 Name* KeyedLoadICNexus::FindFirstName() const { | 883 Name* KeyedLoadICNexus::FindFirstName() const { |
838 Object* feedback = GetFeedback(); | 884 Object* feedback = GetFeedback(); |
839 if (IsPropertyNameFeedback(feedback)) { | 885 if (IsPropertyNameFeedback(feedback)) { |
840 return Name::cast(feedback); | 886 return Name::cast(feedback); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 | 946 |
901 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 947 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
902 Object* feedback = GetFeedback(); | 948 Object* feedback = GetFeedback(); |
903 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { | 949 if (feedback == *TypeFeedbackVector::MegamorphicSentinel(GetIsolate())) { |
904 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); | 950 return static_cast<IcCheckType>(Smi::cast(GetFeedbackExtra())->value()); |
905 } | 951 } |
906 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; | 952 return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT; |
907 } | 953 } |
908 } // namespace internal | 954 } // namespace internal |
909 } // namespace v8 | 955 } // namespace v8 |
OLD | NEW |