| 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" |
| 11 #include "src/type-feedback-vector-inl.h" | 11 #include "src/type-feedback-vector-inl.h" |
| 12 | 12 |
| 13 namespace v8 { | 13 namespace v8 { |
| 14 namespace internal { | 14 namespace internal { |
| 15 | 15 |
| 16 |
| 17 static bool IsPropertyNameFeedback(Object* feedback) { |
| 18 return feedback->IsString() || |
| 19 (feedback->IsSymbol() && !Symbol::cast(feedback)->is_private()); |
| 20 } |
| 21 |
| 22 |
| 16 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { | 23 std::ostream& operator<<(std::ostream& os, FeedbackVectorSlotKind kind) { |
| 17 return os << TypeFeedbackMetadata::Kind2String(kind); | 24 return os << TypeFeedbackMetadata::Kind2String(kind); |
| 18 } | 25 } |
| 19 | 26 |
| 20 | 27 |
| 21 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( | 28 FeedbackVectorSlotKind TypeFeedbackMetadata::GetKind( |
| 22 FeedbackVectorSlot slot) const { | 29 FeedbackVectorSlot slot) const { |
| 23 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); | 30 int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt()); |
| 24 int data = Smi::cast(get(index))->value(); | 31 int data = Smi::cast(get(index))->value(); |
| 25 return VectorICComputer::decode(data, slot.ToInt()); | 32 return VectorICComputer::decode(data, slot.ToInt()); |
| (...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 array->set((i * 3) + 1, *undefined_value); | 650 array->set((i * 3) + 1, *undefined_value); |
| 644 } | 651 } |
| 645 array->set((i * 3) + 2, *handlers->at(i)); | 652 array->set((i * 3) + 2, *handlers->at(i)); |
| 646 } | 653 } |
| 647 } | 654 } |
| 648 | 655 |
| 649 | 656 |
| 650 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { | 657 int FeedbackNexus::ExtractMaps(MapHandleList* maps) const { |
| 651 Isolate* isolate = GetIsolate(); | 658 Isolate* isolate = GetIsolate(); |
| 652 Object* feedback = GetFeedback(); | 659 Object* feedback = GetFeedback(); |
| 653 if (feedback->IsFixedArray() || feedback->IsString()) { | 660 bool is_named_feedback = IsPropertyNameFeedback(feedback); |
| 661 if (feedback->IsFixedArray() || is_named_feedback) { |
| 654 int found = 0; | 662 int found = 0; |
| 655 if (feedback->IsString()) { | 663 if (is_named_feedback) { |
| 656 feedback = GetFeedbackExtra(); | 664 feedback = GetFeedbackExtra(); |
| 657 } | 665 } |
| 658 FixedArray* array = FixedArray::cast(feedback); | 666 FixedArray* array = FixedArray::cast(feedback); |
| 659 // The array should be of the form | 667 // The array should be of the form |
| 660 // [map, handler, map, handler, ...] | 668 // [map, handler, map, handler, ...] |
| 661 // or | 669 // or |
| 662 // [map, map, handler, map, map, handler, ...] | 670 // [map, map, handler, map, map, handler, ...] |
| 663 DCHECK(array->length() >= 2); | 671 DCHECK(array->length() >= 2); |
| 664 int increment = array->get(1)->IsCode() ? 2 : 3; | 672 int increment = array->get(1)->IsCode() ? 2 : 3; |
| 665 for (int i = 0; i < array->length(); i += increment) { | 673 for (int i = 0; i < array->length(); i += increment) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 680 return 1; | 688 return 1; |
| 681 } | 689 } |
| 682 } | 690 } |
| 683 | 691 |
| 684 return 0; | 692 return 0; |
| 685 } | 693 } |
| 686 | 694 |
| 687 | 695 |
| 688 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { | 696 MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { |
| 689 Object* feedback = GetFeedback(); | 697 Object* feedback = GetFeedback(); |
| 690 if (feedback->IsFixedArray() || feedback->IsString()) { | 698 bool is_named_feedback = IsPropertyNameFeedback(feedback); |
| 691 if (feedback->IsString()) { | 699 if (feedback->IsFixedArray() || is_named_feedback) { |
| 700 if (is_named_feedback) { |
| 692 feedback = GetFeedbackExtra(); | 701 feedback = GetFeedbackExtra(); |
| 693 } | 702 } |
| 694 FixedArray* array = FixedArray::cast(feedback); | 703 FixedArray* array = FixedArray::cast(feedback); |
| 695 DCHECK(array->length() >= 2); | 704 DCHECK(array->length() >= 2); |
| 696 int increment = array->get(1)->IsCode() ? 2 : 3; | 705 int increment = array->get(1)->IsCode() ? 2 : 3; |
| 697 for (int i = 0; i < array->length(); i += increment) { | 706 for (int i = 0; i < array->length(); i += increment) { |
| 698 DCHECK(array->get(i)->IsWeakCell()); | 707 DCHECK(array->get(i)->IsWeakCell()); |
| 699 WeakCell* cell = WeakCell::cast(array->get(i)); | 708 WeakCell* cell = WeakCell::cast(array->get(i)); |
| 700 if (!cell->cleared()) { | 709 if (!cell->cleared()) { |
| 701 Map* array_map = Map::cast(cell->value()); | 710 Map* array_map = Map::cast(cell->value()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 718 } | 727 } |
| 719 } | 728 } |
| 720 | 729 |
| 721 return MaybeHandle<Code>(); | 730 return MaybeHandle<Code>(); |
| 722 } | 731 } |
| 723 | 732 |
| 724 | 733 |
| 725 bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { | 734 bool FeedbackNexus::FindHandlers(CodeHandleList* code_list, int length) const { |
| 726 Object* feedback = GetFeedback(); | 735 Object* feedback = GetFeedback(); |
| 727 int count = 0; | 736 int count = 0; |
| 728 if (feedback->IsFixedArray() || feedback->IsString()) { | 737 bool is_named_feedback = IsPropertyNameFeedback(feedback); |
| 729 if (feedback->IsString()) { | 738 if (feedback->IsFixedArray() || is_named_feedback) { |
| 739 if (is_named_feedback) { |
| 730 feedback = GetFeedbackExtra(); | 740 feedback = GetFeedbackExtra(); |
| 731 } | 741 } |
| 732 FixedArray* array = FixedArray::cast(feedback); | 742 FixedArray* array = FixedArray::cast(feedback); |
| 733 // The array should be of the form | 743 // The array should be of the form |
| 734 // [map, handler, map, handler, ...] | 744 // [map, handler, map, handler, ...] |
| 735 // or | 745 // or |
| 736 // [map, map, handler, map, map, handler, ...] | 746 // [map, map, handler, map, map, handler, ...] |
| 737 // Be sure to skip handlers whose maps have been cleared. | 747 // Be sure to skip handlers whose maps have been cleared. |
| 738 DCHECK(array->length() >= 2); | 748 DCHECK(array->length() >= 2); |
| 739 int increment = array->get(1)->IsCode() ? 2 : 3; | 749 int increment = array->get(1)->IsCode() ? 2 : 3; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 763 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } | 773 void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); } |
| 764 | 774 |
| 765 | 775 |
| 766 void KeyedLoadICNexus::Clear(Code* host) { | 776 void KeyedLoadICNexus::Clear(Code* host) { |
| 767 KeyedLoadIC::Clear(GetIsolate(), host, this); | 777 KeyedLoadIC::Clear(GetIsolate(), host, this); |
| 768 } | 778 } |
| 769 | 779 |
| 770 | 780 |
| 771 Name* KeyedLoadICNexus::FindFirstName() const { | 781 Name* KeyedLoadICNexus::FindFirstName() const { |
| 772 Object* feedback = GetFeedback(); | 782 Object* feedback = GetFeedback(); |
| 773 if (feedback->IsString()) { | 783 if (IsPropertyNameFeedback(feedback)) { |
| 774 return Name::cast(feedback); | 784 return Name::cast(feedback); |
| 775 } | 785 } |
| 776 return NULL; | 786 return NULL; |
| 777 } | 787 } |
| 778 | 788 |
| 779 | 789 |
| 780 Name* KeyedStoreICNexus::FindFirstName() const { | 790 Name* KeyedStoreICNexus::FindFirstName() const { |
| 781 Object* feedback = GetFeedback(); | 791 Object* feedback = GetFeedback(); |
| 782 if (feedback->IsString()) { | 792 if (IsPropertyNameFeedback(feedback)) { |
| 783 return Name::cast(feedback); | 793 return Name::cast(feedback); |
| 784 } | 794 } |
| 785 return NULL; | 795 return NULL; |
| 786 } | 796 } |
| 787 | 797 |
| 788 | 798 |
| 789 void StoreICNexus::Clear(Code* host) { | 799 void StoreICNexus::Clear(Code* host) { |
| 790 StoreIC::Clear(GetIsolate(), host, this); | 800 StoreIC::Clear(GetIsolate(), host, this); |
| 791 } | 801 } |
| 792 | 802 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 return mode; | 834 return mode; |
| 825 } | 835 } |
| 826 | 836 |
| 827 | 837 |
| 828 IcCheckType KeyedStoreICNexus::GetKeyType() const { | 838 IcCheckType KeyedStoreICNexus::GetKeyType() const { |
| 829 // The structure of the vector slots tells us the type. | 839 // The structure of the vector slots tells us the type. |
| 830 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; | 840 return GetFeedback()->IsName() ? PROPERTY : ELEMENT; |
| 831 } | 841 } |
| 832 } // namespace internal | 842 } // namespace internal |
| 833 } // namespace v8 | 843 } // namespace v8 |
| OLD | NEW |