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

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 1149053004: Make KeyedStores from a sloppy arguments array use a handler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Code comments. Created 5 years, 6 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/code-stubs.cc ('k') | src/ic/arm/ic-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bailout-reason.h" 7 #include "src/bailout-reason.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/field-index.h" 9 #include "src/field-index.h"
10 #include "src/hydrogen.h" 10 #include "src/hydrogen.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index, 67 void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index,
68 Representation representation, 68 Representation representation,
69 bool transition_to_field); 69 bool transition_to_field);
70 70
71 enum ArgumentClass { 71 enum ArgumentClass {
72 NONE, 72 NONE,
73 SINGLE, 73 SINGLE,
74 MULTIPLE 74 MULTIPLE
75 }; 75 };
76 76
77 HValue* UnmappedCase(HValue* elements, HValue* key); 77 HValue* UnmappedCase(HValue* elements, HValue* key, HValue* value);
78 HValue* EmitKeyedSloppyArguments(HValue* receiver, HValue* key,
79 HValue* value);
78 80
79 HValue* BuildArrayConstructor(ElementsKind kind, 81 HValue* BuildArrayConstructor(ElementsKind kind,
80 AllocationSiteOverrideMode override_mode, 82 AllocationSiteOverrideMode override_mode,
81 ArgumentClass argument_class); 83 ArgumentClass argument_class);
82 HValue* BuildInternalArrayConstructor(ElementsKind kind, 84 HValue* BuildInternalArrayConstructor(ElementsKind kind,
83 ArgumentClass argument_class); 85 ArgumentClass argument_class);
84 86
85 // BuildCheckAndInstallOptimizedCode emits code to install the optimized 87 // BuildCheckAndInstallOptimizedCode emits code to install the optimized
86 // function found in the optimized code map at map_index in js_function, if 88 // function found in the optimized code map at map_index in js_function, if
87 // the function at map_index matches the given native_context. Builder is 89 // the function at map_index matches the given native_context. Builder is
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 HValue* descriptors = Add<HLoadNamedField>(map, nullptr, descriptors_access); 791 HValue* descriptors = Add<HLoadNamedField>(map, nullptr, descriptors_access);
790 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset( 792 HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset(
791 DescriptorArray::GetValueOffset(casted_stub()->constant_index())); 793 DescriptorArray::GetValueOffset(casted_stub()->constant_index()));
792 return Add<HLoadNamedField>(descriptors, nullptr, value_access); 794 return Add<HLoadNamedField>(descriptors, nullptr, value_access);
793 } 795 }
794 796
795 797
796 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); } 798 Handle<Code> LoadConstantStub::GenerateCode() { return DoGenerateCode(this); }
797 799
798 800
799 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) { 801 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key,
800 HValue* result; 802 HValue* value) {
803 HValue* result = NULL;
801 HInstruction* backing_store = 804 HInstruction* backing_store =
802 Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS, 805 Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS,
803 ALLOW_RETURN_HOLE); 806 ALLOW_RETURN_HOLE);
804 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map()); 807 Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map());
805 HValue* backing_store_length = Add<HLoadNamedField>( 808 HValue* backing_store_length = Add<HLoadNamedField>(
806 backing_store, nullptr, HObjectAccess::ForFixedArrayLength()); 809 backing_store, nullptr, HObjectAccess::ForFixedArrayLength());
807 IfBuilder in_unmapped_range(this); 810 IfBuilder in_unmapped_range(this);
808 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length, 811 in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length,
809 Token::LT); 812 Token::LT);
810 in_unmapped_range.Then(); 813 in_unmapped_range.Then();
811 { 814 {
812 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS, 815 if (value == NULL) {
813 NEVER_RETURN_HOLE); 816 result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS,
817 NEVER_RETURN_HOLE);
818 } else {
819 Add<HStoreKeyed>(backing_store, key, value, FAST_HOLEY_ELEMENTS);
820 }
814 } 821 }
815 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange); 822 in_unmapped_range.ElseDeopt(Deoptimizer::kOutsideOfRange);
816 in_unmapped_range.End(); 823 in_unmapped_range.End();
817 return result; 824 return result;
818 } 825 }
819 826
820 827
821 template <> 828 HValue* CodeStubGraphBuilderBase::EmitKeyedSloppyArguments(HValue* receiver,
822 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() { 829 HValue* key,
823 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex); 830 HValue* value) {
824 HValue* key = GetParameter(LoadDescriptor::kNameIndex);
825
826 // Mapped arguments are actual arguments. Unmapped arguments are values added 831 // Mapped arguments are actual arguments. Unmapped arguments are values added
827 // to the arguments object after it was created for the call. Mapped arguments 832 // to the arguments object after it was created for the call. Mapped arguments
828 // are stored in the context at indexes given by elements[key + 2]. Unmapped 833 // are stored in the context at indexes given by elements[key + 2]. Unmapped
829 // arguments are stored as regular indexed properties in the arguments array, 834 // arguments are stored as regular indexed properties in the arguments array,
830 // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed 835 // held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed
831 // look at argument object construction. 836 // look at argument object construction.
832 // 837 //
833 // The sloppy arguments elements array has a special format: 838 // The sloppy arguments elements array has a special format:
834 // 839 //
835 // 0: context 840 // 0: context
836 // 1: unmapped arguments array 841 // 1: unmapped arguments array
837 // 2: mapped_index0, 842 // 2: mapped_index0,
838 // 3: mapped_index1, 843 // 3: mapped_index1,
839 // ... 844 // ...
840 // 845 //
841 // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments). 846 // length is 2 + min(number_of_actual_arguments, number_of_formal_arguments).
842 // If key + 2 >= elements.length then attempt to look in the unmapped 847 // If key + 2 >= elements.length then attempt to look in the unmapped
843 // arguments array (given by elements[1]) and return the value at key, missing 848 // arguments array (given by elements[1]) and return the value at key, missing
844 // to the runtime if the unmapped arguments array is not a fixed array or if 849 // to the runtime if the unmapped arguments array is not a fixed array or if
845 // key >= unmapped_arguments_array.length. 850 // key >= unmapped_arguments_array.length.
846 // 851 //
847 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value 852 // Otherwise, t = elements[key + 2]. If t is the hole, then look up the value
848 // in the unmapped arguments array, as described above. Otherwise, t is a Smi 853 // in the unmapped arguments array, as described above. Otherwise, t is a Smi
849 // index into the context array given at elements[0]. Return the value at 854 // index into the context array given at elements[0]. Return the value at
850 // context[t]. 855 // context[t].
851 856
857 bool is_load = value == NULL;
858
852 key = AddUncasted<HForceRepresentation>(key, Representation::Smi()); 859 key = AddUncasted<HForceRepresentation>(key, Representation::Smi());
853 IfBuilder positive_smi(this); 860 IfBuilder positive_smi(this);
854 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(), 861 positive_smi.If<HCompareNumericAndBranch>(key, graph()->GetConstant0(),
855 Token::LT); 862 Token::LT);
856 positive_smi.ThenDeopt(Deoptimizer::kKeyIsNegative); 863 positive_smi.ThenDeopt(Deoptimizer::kKeyIsNegative);
857 positive_smi.End(); 864 positive_smi.End();
858 865
859 HValue* constant_two = Add<HConstant>(2); 866 HValue* constant_two = Add<HConstant>(2);
860 HValue* elements = AddLoadElements(receiver, nullptr); 867 HValue* elements = AddLoadElements(receiver, nullptr);
861 HValue* elements_length = Add<HLoadNamedField>( 868 HValue* elements_length = Add<HLoadNamedField>(
(...skipping 11 matching lines...) Expand all
873 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index, 880 is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index,
874 graph()->GetConstantHole()); 881 graph()->GetConstantHole());
875 is_valid.Then(); 882 is_valid.Then();
876 { 883 {
877 // TODO(mvstanton): I'd like to assert from this point, that if the 884 // TODO(mvstanton): I'd like to assert from this point, that if the
878 // mapped_index is not the hole that it is indeed, a smi. An unnecessary 885 // mapped_index is not the hole that it is indeed, a smi. An unnecessary
879 // smi check is being emitted. 886 // smi check is being emitted.
880 HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(), 887 HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(),
881 nullptr, FAST_ELEMENTS); 888 nullptr, FAST_ELEMENTS);
882 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize); 889 STATIC_ASSERT(Context::kHeaderSize == FixedArray::kHeaderSize);
883 HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr, 890 if (is_load) {
884 FAST_ELEMENTS, ALLOW_RETURN_HOLE); 891 HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr,
885 environment()->Push(result); 892 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
893 environment()->Push(result);
894 } else {
895 DCHECK(value != NULL);
896 Add<HStoreKeyed>(the_context, mapped_index, value, FAST_ELEMENTS);
897 environment()->Push(value);
898 }
886 } 899 }
887 is_valid.Else(); 900 is_valid.Else();
888 { 901 {
889 HValue* result = UnmappedCase(elements, key); 902 HValue* result = UnmappedCase(elements, key, value);
890 environment()->Push(result); 903 environment()->Push(is_load ? result : value);
891 } 904 }
892 is_valid.End(); 905 is_valid.End();
893 } 906 }
894 in_range.Else(); 907 in_range.Else();
895 { 908 {
896 HValue* result = UnmappedCase(elements, key); 909 HValue* result = UnmappedCase(elements, key, value);
897 environment()->Push(result); 910 environment()->Push(is_load ? result : value);
898 } 911 }
899 in_range.End(); 912 in_range.End();
900 913
901 return environment()->Pop(); 914 return environment()->Pop();
902 } 915 }
903 916
904 917
918 template <>
919 HValue* CodeStubGraphBuilder<KeyedLoadSloppyArgumentsStub>::BuildCodeStub() {
920 HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
921 HValue* key = GetParameter(LoadDescriptor::kNameIndex);
922
923 return EmitKeyedSloppyArguments(receiver, key, NULL);
924 }
925
926
905 Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() { 927 Handle<Code> KeyedLoadSloppyArgumentsStub::GenerateCode() {
906 return DoGenerateCode(this); 928 return DoGenerateCode(this);
907 } 929 }
908 930
909 931
932 template <>
933 HValue* CodeStubGraphBuilder<KeyedStoreSloppyArgumentsStub>::BuildCodeStub() {
934 HValue* receiver = GetParameter(StoreDescriptor::kReceiverIndex);
935 HValue* key = GetParameter(StoreDescriptor::kNameIndex);
936 HValue* value = GetParameter(StoreDescriptor::kValueIndex);
937
938 return EmitKeyedSloppyArguments(receiver, key, value);
939 }
940
941
942 Handle<Code> KeyedStoreSloppyArgumentsStub::GenerateCode() {
943 return DoGenerateCode(this);
944 }
945
946
910 void CodeStubGraphBuilderBase::BuildStoreNamedField( 947 void CodeStubGraphBuilderBase::BuildStoreNamedField(
911 HValue* object, HValue* value, FieldIndex index, 948 HValue* object, HValue* value, FieldIndex index,
912 Representation representation, bool transition_to_field) { 949 Representation representation, bool transition_to_field) {
913 DCHECK(!index.is_double() || representation.IsDouble()); 950 DCHECK(!index.is_double() || representation.IsDouble());
914 int offset = index.offset(); 951 int offset = index.offset();
915 HObjectAccess access = 952 HObjectAccess access =
916 index.is_inobject() 953 index.is_inobject()
917 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation) 954 ? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
918 : HObjectAccess::ForBackingStoreOffset(offset, representation); 955 : HObjectAccess::ForBackingStoreOffset(offset, representation);
919 956
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 2236
2200 return Pop(); 2237 return Pop();
2201 } 2238 }
2202 2239
2203 2240
2204 Handle<Code> KeyedLoadGenericStub::GenerateCode() { 2241 Handle<Code> KeyedLoadGenericStub::GenerateCode() {
2205 return DoGenerateCode(this); 2242 return DoGenerateCode(this);
2206 } 2243 }
2207 2244
2208 } } // namespace v8::internal 2245 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/ic/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698