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

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

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: We still generated the arrays with feature flag off. Fixed. Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/lithium-codegen-x64.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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 Isolate* isolate, 89 Isolate* isolate,
90 CodeStubInterfaceDescriptor* descriptor) { 90 CodeStubInterfaceDescriptor* descriptor) {
91 static Register registers[] = { rax, rbx }; 91 static Register registers[] = { rax, rbx };
92 descriptor->register_param_count_ = 2; 92 descriptor->register_param_count_ = 2;
93 descriptor->register_params_ = registers; 93 descriptor->register_params_ = registers;
94 descriptor->deoptimization_handler_ = 94 descriptor->deoptimization_handler_ =
95 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry; 95 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
96 } 96 }
97 97
98 98
99 static void InitializeArrayConstructorDescriptor(Isolate* isolate, 99 static void InitializeArrayConstructorDescriptor(
100 CodeStubInterfaceDescriptor* descriptor) { 100 Isolate* isolate,
101 CodeStubInterfaceDescriptor* descriptor,
102 int constant_stack_parameter_count) {
101 // register state 103 // register state
102 // rdi -- constructor function 104 // rax -- number of arguments
103 // rbx -- type info cell with elements kind 105 // rbx -- type info cell with elements kind
104 // rax -- number of arguments to the constructor function 106 static Register registers[] = { rbx };
105 static Register registers[] = { rdi, rbx }; 107 descriptor->register_param_count_ = 1;
106 descriptor->register_param_count_ = 2; 108 if (constant_stack_parameter_count != 0) {
107 // stack param count needs (constructor pointer, and single argument) 109 // stack param count needs (constructor pointer, and single argument)
108 descriptor->stack_parameter_count_ = &rax; 110 descriptor->stack_parameter_count_ = &rax;
111 }
112 descriptor->hint_stack_parameter_count_ = constant_stack_parameter_count;
109 descriptor->register_params_ = registers; 113 descriptor->register_params_ = registers;
110 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE; 114 descriptor->function_mode_ = JS_FUNCTION_STUB_MODE;
111 descriptor->deoptimization_handler_ = 115 descriptor->deoptimization_handler_ =
112 FUNCTION_ADDR(ArrayConstructor_StubFailure); 116 FUNCTION_ADDR(ArrayConstructor_StubFailure);
113 } 117 }
114 118
115 119
116 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( 120 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
117 Isolate* isolate, 121 Isolate* isolate,
118 CodeStubInterfaceDescriptor* descriptor) { 122 CodeStubInterfaceDescriptor* descriptor) {
119 InitializeArrayConstructorDescriptor(isolate, descriptor); 123 InitializeArrayConstructorDescriptor(isolate, descriptor, 0);
120 } 124 }
121 125
122 126
123 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( 127 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
124 Isolate* isolate, 128 Isolate* isolate,
125 CodeStubInterfaceDescriptor* descriptor) { 129 CodeStubInterfaceDescriptor* descriptor) {
126 InitializeArrayConstructorDescriptor(isolate, descriptor); 130 InitializeArrayConstructorDescriptor(isolate, descriptor, 1);
127 } 131 }
128 132
129 133
130 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( 134 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
131 Isolate* isolate, 135 Isolate* isolate,
132 CodeStubInterfaceDescriptor* descriptor) { 136 CodeStubInterfaceDescriptor* descriptor) {
133 InitializeArrayConstructorDescriptor(isolate, descriptor); 137 InitializeArrayConstructorDescriptor(isolate, descriptor, -1);
134 } 138 }
135 139
136 140
137 #define __ ACCESS_MASM(masm) 141 #define __ ACCESS_MASM(masm)
138 142
139 143
140 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 144 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
141 // Update the static counter each time a new code stub is generated. 145 // Update the static counter each time a new code stub is generated.
142 Isolate* isolate = masm->isolate(); 146 Isolate* isolate = masm->isolate();
143 isolate->counters()->code_stubs()->Increment(); 147 isolate->counters()->code_stubs()->Increment();
(...skipping 3669 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate)); 3817 __ Cmp(rcx, TypeFeedbackCells::MegamorphicSentinel(isolate));
3814 __ j(equal, &done); 3818 __ j(equal, &done);
3815 3819
3816 // Special handling of the Array() function, which caches not only the 3820 // Special handling of the Array() function, which caches not only the
3817 // monomorphic Array function but the initial ElementsKind with special 3821 // monomorphic Array function but the initial ElementsKind with special
3818 // sentinels 3822 // sentinels
3819 Handle<Object> terminal_kind_sentinel = 3823 Handle<Object> terminal_kind_sentinel =
3820 TypeFeedbackCells::MonomorphicArraySentinel(isolate, 3824 TypeFeedbackCells::MonomorphicArraySentinel(isolate,
3821 LAST_FAST_ELEMENTS_KIND); 3825 LAST_FAST_ELEMENTS_KIND);
3822 __ Cmp(rcx, terminal_kind_sentinel); 3826 __ Cmp(rcx, terminal_kind_sentinel);
3823 __ j(not_equal, &miss); 3827 __ j(above, &miss);
3824 // Make sure the function is the Array() function 3828 // Make sure the function is the Array() function
3825 __ LoadArrayFunction(rcx); 3829 __ LoadArrayFunction(rcx);
3826 __ cmpq(rdi, rcx); 3830 __ cmpq(rdi, rcx);
3827 __ j(not_equal, &megamorphic); 3831 __ j(not_equal, &megamorphic);
3828 __ jmp(&done); 3832 __ jmp(&done);
3829 3833
3830 __ bind(&miss); 3834 __ bind(&miss);
3831 3835
3832 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 3836 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
3833 // megamorphic. 3837 // megamorphic.
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
4025 #endif 4029 #endif
4026 } 4030 }
4027 4031
4028 4032
4029 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { 4033 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
4030 CEntryStub::GenerateAheadOfTime(isolate); 4034 CEntryStub::GenerateAheadOfTime(isolate);
4031 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); 4035 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
4032 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); 4036 StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
4033 // It is important that the store buffer overflow stubs are generated first. 4037 // It is important that the store buffer overflow stubs are generated first.
4034 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); 4038 RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate);
4039 if (FLAG_optimize_constructed_arrays) {
4040 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
4041 }
4035 } 4042 }
4036 4043
4037 4044
4038 void CodeStub::GenerateFPStubs(Isolate* isolate) { 4045 void CodeStub::GenerateFPStubs(Isolate* isolate) {
4039 } 4046 }
4040 4047
4041 4048
4042 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 4049 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
4043 CEntryStub stub(1, kDontSaveFPRegs); 4050 CEntryStub stub(1, kDontSaveFPRegs);
4044 stub.GetCode(isolate)->set_is_pregenerated(true); 4051 stub.GetCode(isolate)->set_is_pregenerated(true);
(...skipping 2717 matching lines...) Expand 10 before | Expand all | Expand 10 after
6762 __ pop(rcx); 6769 __ pop(rcx);
6763 #else 6770 #else
6764 __ pop(rsi); 6771 __ pop(rsi);
6765 __ pop(rdi); 6772 __ pop(rdi);
6766 __ pop(rcx); 6773 __ pop(rcx);
6767 #endif 6774 #endif
6768 6775
6769 __ Ret(); 6776 __ Ret();
6770 } 6777 }
6771 6778
6779
6780 template<class T>
6781 static void CreateArrayDispatch(MacroAssembler* masm) {
6782 int last_index = GetSequenceIndexFromFastElementsKind(
6783 TERMINAL_FAST_ELEMENTS_KIND);
6784 for (int i = 0; i <= last_index; ++i) {
6785 Label next;
6786 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6787 __ cmpl(rdx, Immediate(kind));
6788 __ j(not_equal, &next);
6789 T stub(kind);
6790 __ TailCallStub(&stub);
6791 __ bind(&next);
6792 }
6793
6794 // If we reached this point there is a problem.
6795 __ Abort("Unexpected ElementsKind in array constructor");
6796 }
6797
6798
6799 static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
6800 // rbx - type info cell
6801 // rdx - kind
6802 // rax - number of arguments
6803 // rdi - constructor?
6804 // esp[0] - return address
6805 // esp[4] - last argument
6806 ASSERT(FAST_SMI_ELEMENTS == 0);
6807 ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
6808 ASSERT(FAST_ELEMENTS == 2);
6809 ASSERT(FAST_HOLEY_ELEMENTS == 3);
6810 ASSERT(FAST_DOUBLE_ELEMENTS == 4);
6811 ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
6812
6813 Handle<Object> undefined_sentinel(
6814 masm->isolate()->heap()->undefined_value(),
6815 masm->isolate());
6816
6817 // is the low bit set? If so, we are holey and that is good.
6818 __ testb(rdx, Immediate(1));
6819 Label normal_sequence;
6820 __ j(not_zero, &normal_sequence);
6821
6822 // look at the first argument
6823 __ movq(rcx, Operand(rsp, kPointerSize));
6824 __ testq(rcx, rcx);
6825 __ j(zero, &normal_sequence);
6826
6827 // We are going to create a holey array, but our kind is non-holey.
6828 // Fix kind and retry
6829 __ incl(rdx);
6830 __ Cmp(rbx, undefined_sentinel);
6831 __ j(equal, &normal_sequence);
6832
6833 // Save the resulting elements kind in type info
6834 __ Integer32ToSmi(rdx, rdx);
6835 __ movq(FieldOperand(rbx, kPointerSize), rdx);
6836 __ SmiToInteger32(rdx, rdx);
6837
6838 __ bind(&normal_sequence);
6839 int last_index = GetSequenceIndexFromFastElementsKind(
6840 TERMINAL_FAST_ELEMENTS_KIND);
6841 for (int i = 0; i <= last_index; ++i) {
6842 Label next;
6843 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6844 __ cmpl(rdx, Immediate(kind));
6845 __ j(not_equal, &next);
6846 ArraySingleArgumentConstructorStub stub(kind);
6847 __ TailCallStub(&stub);
6848 __ bind(&next);
6849 }
6850
6851 // If we reached this point there is a problem.
6852 __ Abort("Unexpected ElementsKind in array constructor");
6853 }
6854
6855
6856 template<class T>
6857 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
6858 int to_index = GetSequenceIndexFromFastElementsKind(
6859 TERMINAL_FAST_ELEMENTS_KIND);
6860 for (int i = 0; i <= to_index; ++i) {
6861 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
6862 T stub(kind);
6863 stub.GetCode(isolate)->set_is_pregenerated(true);
6864 }
6865 }
6866
6867
6868 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
6869 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
6870 isolate);
6871 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
6872 isolate);
6873 ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
6874 isolate);
6875 }
6876
6877
6878
6879 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
6880 // ----------- S t a t e -------------
6881 // -- rax : argc
6882 // -- rbx : type info cell
6883 // -- rdi : constructor
6884 // -- rsp[0] : return address
6885 // -- rsp[4] : last argument
6886 // -----------------------------------
6887 Handle<Object> undefined_sentinel(
6888 masm->isolate()->heap()->undefined_value(),
6889 masm->isolate());
6890
6891 if (FLAG_debug_code) {
6892 // The array construct code is only set for the global and natives
6893 // builtin Array functions which always have maps.
6894
6895 // Initial map for the builtin Array function should be a map.
6896 __ movq(rcx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset));
6897 // Will both indicate a NULL and a Smi.
6898 STATIC_ASSERT(kSmiTag == 0);
6899 Condition not_smi = NegateCondition(masm->CheckSmi(rcx));
6900 __ Check(not_smi, "Unexpected initial map for Array function");
6901 __ CmpObjectType(rcx, MAP_TYPE, rcx);
6902 __ Check(equal, "Unexpected initial map for Array function");
6903
6904 // We should either have undefined in ebx or a valid jsglobalpropertycell
6905 Label okay_here;
6906 Handle<Map> global_property_cell_map(
6907 masm->isolate()->heap()->global_property_cell_map());
6908 __ Cmp(rbx, undefined_sentinel);
6909 __ j(equal, &okay_here);
6910 __ Cmp(FieldOperand(rbx, 0), global_property_cell_map);
6911 __ Assert(equal, "Expected property cell in register rbx");
6912 __ bind(&okay_here);
6913 }
6914
6915 if (FLAG_optimize_constructed_arrays) {
6916 Label no_info, switch_ready;
6917 // Get the elements kind and case on that.
6918 __ Cmp(rbx, undefined_sentinel);
6919 __ j(equal, &no_info);
6920 __ movq(rdx, FieldOperand(rbx, kPointerSize));
6921
6922 // There is no info if the call site went megamorphic either
6923
6924 // TODO(mvstanton): Really? I thought if it was the array function that
6925 // the cell wouldn't get stamped as megamorphic.
6926 __ Cmp(rdx, TypeFeedbackCells::MegamorphicSentinel(masm->isolate()));
6927 __ j(equal, &no_info);
6928 __ SmiToInteger32(rdx, rdx);
6929 __ jmp(&switch_ready);
6930 __ bind(&no_info);
6931 __ movq(rdx, Immediate(GetInitialFastElementsKind()));
6932 __ bind(&switch_ready);
6933
6934 if (argument_count_ == ANY) {
6935 Label not_zero_case, not_one_case;
6936 __ testq(rax, rax);
6937 __ j(not_zero, &not_zero_case);
6938 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6939
6940 __ bind(&not_zero_case);
6941 __ cmpl(rax, Immediate(1));
6942 __ j(greater, &not_one_case);
6943 CreateArrayDispatchOneArgument(masm);
6944
6945 __ bind(&not_one_case);
6946 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6947 } else if (argument_count_ == NONE) {
6948 CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm);
6949 } else if (argument_count_ == ONE) {
6950 CreateArrayDispatchOneArgument(masm);
6951 } else if (argument_count_ == MORE_THAN_ONE) {
6952 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm);
6953 } else {
6954 UNREACHABLE();
6955 }
6956 } else {
6957 Label generic_constructor;
6958 // Run the native code for the Array function called as constructor.
6959 ArrayNativeCode(masm, &generic_constructor);
6960
6961 // Jump to the generic construct code in case the specialized code cannot
6962 // handle the construction.
6963 __ bind(&generic_constructor);
6964 Handle<Code> generic_construct_stub =
6965 masm->isolate()->builtins()->JSConstructStubGeneric();
6966 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
6967 }
6968 }
6969
6970
6772 #undef __ 6971 #undef __
6773 6972
6774 } } // namespace v8::internal 6973 } } // namespace v8::internal
6775 6974
6776 #endif // V8_TARGET_ARCH_X64 6975 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698