| 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 |