Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: src/ic/keyed-store-generic.cc

Issue 2717203002: [StoreIC] Use StoreIC_Uninitialized for 0->PRE transitions (Closed)
Patch Set: check for map extensibility Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/keyed-store-generic.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/ic/keyed-store-generic.h" 5 #include "src/ic/keyed-store-generic.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h" 8 #include "src/code-stub-assembler.h"
9 #include "src/contexts.h" 9 #include "src/contexts.h"
10 #include "src/ic/accessor-assembler.h" 10 #include "src/ic/accessor-assembler.h"
11 #include "src/interface-descriptors.h" 11 #include "src/interface-descriptors.h"
12 #include "src/isolate.h" 12 #include "src/isolate.h"
13 #include "src/objects-inl.h" 13 #include "src/objects-inl.h"
14 14
15 namespace v8 { 15 namespace v8 {
16 namespace internal { 16 namespace internal {
17 17
18 using compiler::Node; 18 using compiler::Node;
19 19
20 class KeyedStoreGenericAssembler : public AccessorAssembler { 20 class KeyedStoreGenericAssembler : public AccessorAssembler {
21 public: 21 public:
22 explicit KeyedStoreGenericAssembler(compiler::CodeAssemblerState* state) 22 explicit KeyedStoreGenericAssembler(compiler::CodeAssemblerState* state)
23 : AccessorAssembler(state) {} 23 : AccessorAssembler(state) {}
24 24
25 void KeyedStoreGeneric(LanguageMode language_mode); 25 void KeyedStoreGeneric(LanguageMode language_mode);
26 26
27 void StoreIC_Uninitialized(LanguageMode language_mode);
28
27 private: 29 private:
28 enum UpdateLength { 30 enum UpdateLength {
29 kDontChangeLength, 31 kDontChangeLength,
30 kIncrementLengthByOne, 32 kIncrementLengthByOne,
31 kBumpLengthWithGap 33 kBumpLengthWithGap
32 }; 34 };
33 35
36 enum UseStubCache { kUseStubCache, kDontUseStubCache };
37
34 void EmitGenericElementStore(Node* receiver, Node* receiver_map, 38 void EmitGenericElementStore(Node* receiver, Node* receiver_map,
35 Node* instance_type, Node* intptr_index, 39 Node* instance_type, Node* intptr_index,
36 Node* value, Node* context, Label* slow); 40 Node* value, Node* context, Label* slow);
37 41
38 void EmitGenericPropertyStore(Node* receiver, Node* receiver_map, 42 void EmitGenericPropertyStore(Node* receiver, Node* receiver_map,
39 const StoreICParameters* p, Label* slow, 43 const StoreICParameters* p, Label* slow,
40 LanguageMode language_mode); 44 LanguageMode language_mode,
45 UseStubCache use_stub_cache = kUseStubCache);
41 46
42 void BranchIfPrototypesHaveNonFastElements(Node* receiver_map, 47 void BranchIfPrototypesHaveNonFastElements(Node* receiver_map,
43 Label* non_fast_elements, 48 Label* non_fast_elements,
44 Label* only_fast_elements); 49 Label* only_fast_elements);
45 50
46 void TryRewriteElements(Node* receiver, Node* receiver_map, Node* elements, 51 void TryRewriteElements(Node* receiver, Node* receiver_map, Node* elements,
47 Node* native_context, ElementsKind from_kind, 52 Node* native_context, ElementsKind from_kind,
48 ElementsKind to_kind, Label* bailout); 53 ElementsKind to_kind, Label* bailout);
49 54
50 void StoreElementWithCapacity(Node* receiver, Node* receiver_map, 55 void StoreElementWithCapacity(Node* receiver, Node* receiver_map,
(...skipping 29 matching lines...) Expand all
80 Node* descriptor_name_index, Node* details, 85 Node* descriptor_name_index, Node* details,
81 Node* value, Label* slow); 86 Node* value, Label* slow);
82 }; 87 };
83 88
84 void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state, 89 void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state,
85 LanguageMode language_mode) { 90 LanguageMode language_mode) {
86 KeyedStoreGenericAssembler assembler(state); 91 KeyedStoreGenericAssembler assembler(state);
87 assembler.KeyedStoreGeneric(language_mode); 92 assembler.KeyedStoreGeneric(language_mode);
88 } 93 }
89 94
95 void StoreICUninitializedGenerator::Generate(
96 compiler::CodeAssemblerState* state, LanguageMode language_mode) {
97 KeyedStoreGenericAssembler assembler(state);
98 assembler.StoreIC_Uninitialized(language_mode);
99 }
100
90 void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements( 101 void KeyedStoreGenericAssembler::BranchIfPrototypesHaveNonFastElements(
91 Node* receiver_map, Label* non_fast_elements, Label* only_fast_elements) { 102 Node* receiver_map, Label* non_fast_elements, Label* only_fast_elements) {
92 Variable var_map(this, MachineRepresentation::kTagged); 103 Variable var_map(this, MachineRepresentation::kTagged);
93 var_map.Bind(receiver_map); 104 var_map.Bind(receiver_map);
94 Label loop_body(this, &var_map); 105 Label loop_body(this, &var_map);
95 Goto(&loop_body); 106 Goto(&loop_body);
96 107
97 Bind(&loop_body); 108 Bind(&loop_body);
98 { 109 {
99 Node* map = var_map.value(); 110 Node* map = var_map.value();
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 { 742 {
732 StoreFixedArrayElement(properties, backing_store_index, value); 743 StoreFixedArrayElement(properties, backing_store_index, value);
733 Goto(&done); 744 Goto(&done);
734 } 745 }
735 } 746 }
736 Bind(&done); 747 Bind(&done);
737 } 748 }
738 749
739 void KeyedStoreGenericAssembler::EmitGenericPropertyStore( 750 void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
740 Node* receiver, Node* receiver_map, const StoreICParameters* p, Label* slow, 751 Node* receiver, Node* receiver_map, const StoreICParameters* p, Label* slow,
741 LanguageMode language_mode) { 752 LanguageMode language_mode, UseStubCache use_stub_cache) {
742 Variable var_accessor_pair(this, MachineRepresentation::kTagged); 753 Variable var_accessor_pair(this, MachineRepresentation::kTagged);
743 Variable var_accessor_holder(this, MachineRepresentation::kTagged); 754 Variable var_accessor_holder(this, MachineRepresentation::kTagged);
744 Label stub_cache(this), fast_properties(this), dictionary_properties(this), 755 Label stub_cache(this), fast_properties(this), dictionary_properties(this),
745 accessor(this), readonly(this); 756 accessor(this), readonly(this);
746 Node* properties = LoadProperties(receiver); 757 Node* properties = LoadProperties(receiver);
747 Node* properties_map = LoadMap(properties); 758 Node* properties_map = LoadMap(properties);
748 Branch(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), 759 Branch(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)),
749 &dictionary_properties, &fast_properties); 760 &dictionary_properties, &fast_properties);
750 761
751 Bind(&fast_properties); 762 Bind(&fast_properties);
752 { 763 {
753 Comment("fast property store"); 764 Comment("fast property store");
754 Node* bitfield3 = LoadMapBitField3(receiver_map); 765 Node* bitfield3 = LoadMapBitField3(receiver_map);
755 Node* descriptors = LoadMapDescriptors(receiver_map); 766 Node* descriptors = LoadMapDescriptors(receiver_map);
756 Label descriptor_found(this); 767 Label descriptor_found(this);
757 Variable var_name_index(this, MachineType::PointerRepresentation()); 768 Variable var_name_index(this, MachineType::PointerRepresentation());
758 // TODO(jkummerow): Maybe look for existing map transitions? 769 // TODO(jkummerow): Maybe look for existing map transitions?
759 Label* notfound = &stub_cache; 770 Label* notfound = use_stub_cache == kUseStubCache ? &stub_cache : slow;
760 DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found, 771 DescriptorLookup(p->name, descriptors, bitfield3, &descriptor_found,
761 &var_name_index, notfound); 772 &var_name_index, notfound);
762 773
763 Bind(&descriptor_found); 774 Bind(&descriptor_found);
764 { 775 {
765 Node* name_index = var_name_index.value(); 776 Node* name_index = var_name_index.value();
766 Node* details = 777 Node* details =
767 LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index); 778 LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index);
768 Label data_property(this); 779 Label data_property(this);
769 JumpIfDataProperty(details, &data_property, &readonly); 780 JumpIfDataProperty(details, &data_property, &readonly);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 Bind(&overwrite); 823 Bind(&overwrite);
813 { 824 {
814 StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(), 825 StoreValueByKeyIndex<NameDictionary>(properties, var_name_index.value(),
815 p->value); 826 p->value);
816 Return(p->value); 827 Return(p->value);
817 } 828 }
818 } 829 }
819 830
820 Bind(&not_found); 831 Bind(&not_found);
821 { 832 {
833 Label extensible(this);
834 GotoIf(IsPrivateSymbol(p->name), &extensible);
835 Node* bitfield2 = LoadMapBitField2(receiver_map);
836 Branch(IsSetWord32(bitfield2, 1 << Map::kIsExtensible), &extensible,
837 slow);
838
839 Bind(&extensible);
822 LookupPropertyOnPrototypeChain(receiver_map, p->name, &accessor, 840 LookupPropertyOnPrototypeChain(receiver_map, p->name, &accessor,
823 &var_accessor_pair, &var_accessor_holder, 841 &var_accessor_pair, &var_accessor_holder,
824 &readonly, slow); 842 &readonly, slow);
825 Add<NameDictionary>(properties, p->name, p->value, slow); 843 Add<NameDictionary>(properties, p->name, p->value, slow);
826 Return(p->value); 844 Return(p->value);
827 } 845 }
828 } 846 }
829 847
830 Bind(&accessor); 848 Bind(&accessor);
831 { 849 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 SmiConstant(Smi::FromInt(MessageTemplate::kStrictReadOnlyProperty)); 882 SmiConstant(Smi::FromInt(MessageTemplate::kStrictReadOnlyProperty));
865 Node* type = Typeof(p->receiver); 883 Node* type = Typeof(p->receiver);
866 TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name, 884 TailCallRuntime(Runtime::kThrowTypeError, p->context, message, p->name,
867 type, p->receiver); 885 type, p->receiver);
868 } else { 886 } else {
869 DCHECK_EQ(SLOPPY, language_mode); 887 DCHECK_EQ(SLOPPY, language_mode);
870 Return(p->value); 888 Return(p->value);
871 } 889 }
872 } 890 }
873 891
874 Bind(&stub_cache); 892 if (use_stub_cache == kUseStubCache) {
875 { 893 Bind(&stub_cache);
876 Comment("stub cache probe"); 894 Comment("stub cache probe");
877 Variable var_handler(this, MachineRepresentation::kTagged); 895 Variable var_handler(this, MachineRepresentation::kTagged);
878 Label found_handler(this, &var_handler), stub_cache_miss(this); 896 Label found_handler(this, &var_handler), stub_cache_miss(this);
879 TryProbeStubCache(isolate()->store_stub_cache(), receiver, p->name, 897 TryProbeStubCache(isolate()->store_stub_cache(), receiver, p->name,
880 &found_handler, &var_handler, &stub_cache_miss); 898 &found_handler, &var_handler, &stub_cache_miss);
881 Bind(&found_handler); 899 Bind(&found_handler);
882 { 900 {
883 Comment("KeyedStoreGeneric found handler"); 901 Comment("KeyedStoreGeneric found handler");
884 HandleStoreICHandlerCase(p, var_handler.value(), &stub_cache_miss); 902 HandleStoreICHandlerCase(p, var_handler.value(), &stub_cache_miss);
885 } 903 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 } 952 }
935 953
936 Bind(&slow); 954 Bind(&slow);
937 { 955 {
938 Comment("KeyedStoreGeneric_slow"); 956 Comment("KeyedStoreGeneric_slow");
939 TailCallRuntime(Runtime::kSetProperty, context, receiver, name, value, 957 TailCallRuntime(Runtime::kSetProperty, context, receiver, name, value,
940 SmiConstant(language_mode)); 958 SmiConstant(language_mode));
941 } 959 }
942 } 960 }
943 961
962 void KeyedStoreGenericAssembler::StoreIC_Uninitialized(
963 LanguageMode language_mode) {
964 typedef StoreWithVectorDescriptor Descriptor;
965
966 Node* receiver = Parameter(Descriptor::kReceiver);
967 Node* name = Parameter(Descriptor::kName);
968 Node* value = Parameter(Descriptor::kValue);
969 Node* slot = Parameter(Descriptor::kSlot);
970 Node* vector = Parameter(Descriptor::kVector);
971 Node* context = Parameter(Descriptor::kContext);
972
973 Label miss(this);
974
975 GotoIf(TaggedIsSmi(receiver), &miss);
976 Node* receiver_map = LoadMap(receiver);
977 Node* instance_type = LoadMapInstanceType(receiver_map);
978 // Receivers requiring non-standard element accesses (interceptors, access
979 // checks, strings and string wrappers, proxies) are handled in the runtime.
980 GotoIf(Int32LessThanOrEqual(instance_type,
981 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
982 &miss);
983
984 // Optimistically write the state transition to the vector.
985 StoreFixedArrayElement(vector, slot,
986 LoadRoot(Heap::kpremonomorphic_symbolRootIndex),
987 SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS);
988
989 StoreICParameters p(context, receiver, name, value, slot, vector);
990 EmitGenericPropertyStore(receiver, receiver_map, &p, &miss, language_mode,
991 kDontUseStubCache);
992
993 Bind(&miss);
994 {
995 // Undo the optimistic state transition.
996 StoreFixedArrayElement(vector, slot,
997 LoadRoot(Heap::kuninitialized_symbolRootIndex),
998 SKIP_WRITE_BARRIER, 0, SMI_PARAMETERS);
999 TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, vector,
1000 receiver, name);
1001 }
1002 }
1003
944 } // namespace internal 1004 } // namespace internal
945 } // namespace v8 1005 } // namespace v8
OLDNEW
« no previous file with comments | « src/ic/keyed-store-generic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698