OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
11 #include "src/codegen.h" | 11 #include "src/codegen.h" |
12 #include "src/ic/handler-compiler.h" | 12 #include "src/ic/handler-compiler.h" |
13 #include "src/isolate.h" | 13 #include "src/isolate.h" |
14 #include "src/jsregexp.h" | 14 #include "src/jsregexp.h" |
15 #include "src/regexp-macro-assembler.h" | 15 #include "src/regexp-macro-assembler.h" |
16 #include "src/runtime.h" | 16 #include "src/runtime.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 | 20 |
21 | 21 |
22 void FastNewClosureStub::InitializeInterfaceDescriptor( | |
23 CodeStubInterfaceDescriptor* descriptor) { | |
24 Register registers[] = { rsi, rbx }; | |
25 descriptor->Initialize( | |
26 MajorKey(), arraysize(registers), registers, | |
27 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); | |
28 } | |
29 | |
30 | |
31 void FastNewContextStub::InitializeInterfaceDescriptor( | |
32 CodeStubInterfaceDescriptor* descriptor) { | |
33 Register registers[] = { rsi, rdi }; | |
34 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
35 } | |
36 | |
37 | |
38 void ToNumberStub::InitializeInterfaceDescriptor( | |
39 CodeStubInterfaceDescriptor* descriptor) { | |
40 Register registers[] = { rsi, rax }; | |
41 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
42 } | |
43 | |
44 | |
45 void NumberToStringStub::InitializeInterfaceDescriptor( | |
46 CodeStubInterfaceDescriptor* descriptor) { | |
47 Register registers[] = { rsi, rax }; | |
48 descriptor->Initialize( | |
49 MajorKey(), arraysize(registers), registers, | |
50 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); | |
51 } | |
52 | |
53 | |
54 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | |
55 CodeStubInterfaceDescriptor* descriptor) { | |
56 Register registers[] = { rsi, rax, rbx, rcx }; | |
57 Representation representations[] = { | |
58 Representation::Tagged(), | |
59 Representation::Tagged(), | |
60 Representation::Smi(), | |
61 Representation::Tagged() }; | |
62 | |
63 descriptor->Initialize( | |
64 MajorKey(), arraysize(registers), registers, | |
65 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry, | |
66 representations); | |
67 } | |
68 | |
69 | |
70 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | |
71 CodeStubInterfaceDescriptor* descriptor) { | |
72 Register registers[] = { rsi, rax, rbx, rcx, rdx }; | |
73 descriptor->Initialize( | |
74 MajorKey(), arraysize(registers), registers, | |
75 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); | |
76 } | |
77 | |
78 | |
79 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | |
80 CodeStubInterfaceDescriptor* descriptor) { | |
81 Register registers[] = { rsi, rbx, rdx }; | |
82 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
83 } | |
84 | |
85 | |
86 void CallFunctionStub::InitializeInterfaceDescriptor( | |
87 CodeStubInterfaceDescriptor* descriptor) { | |
88 Register registers[] = {rsi, rdi}; | |
89 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
90 } | |
91 | |
92 | |
93 void CallConstructStub::InitializeInterfaceDescriptor( | |
94 CodeStubInterfaceDescriptor* descriptor) { | |
95 // rax : number of arguments | |
96 // rbx : feedback vector | |
97 // rdx : (only if rbx is not the megamorphic symbol) slot in feedback | |
98 // vector (Smi) | |
99 // rdi : constructor function | |
100 // TODO(turbofan): So far we don't gather type feedback and hence skip the | |
101 // slot parameter, but ArrayConstructStub needs the vector to be undefined. | |
102 Register registers[] = {rsi, rax, rdi, rbx}; | |
103 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
104 } | |
105 | |
106 | |
107 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | |
108 CodeStubInterfaceDescriptor* descriptor) { | |
109 Register registers[] = { rsi, rcx, rbx, rax }; | |
110 descriptor->Initialize( | |
111 MajorKey(), arraysize(registers), registers, | |
112 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | |
113 } | |
114 | |
115 | |
116 void TransitionElementsKindStub::InitializeInterfaceDescriptor( | |
117 CodeStubInterfaceDescriptor* descriptor) { | |
118 Register registers[] = { rsi, rax, rbx }; | |
119 descriptor->Initialize( | |
120 MajorKey(), arraysize(registers), registers, | |
121 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry); | |
122 } | |
123 | |
124 | |
125 static void InitializeArrayConstructorDescriptor( | 22 static void InitializeArrayConstructorDescriptor( |
126 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, | 23 Isolate* isolate, CodeStub::Major major, |
| 24 CodeStubInterfaceDescriptor* descriptor, |
127 int constant_stack_parameter_count) { | 25 int constant_stack_parameter_count) { |
128 // register state | |
129 // rax -- number of arguments | |
130 // rdi -- function | |
131 // rbx -- allocation site with elements kind | |
132 Address deopt_handler = Runtime::FunctionForId( | 26 Address deopt_handler = Runtime::FunctionForId( |
133 Runtime::kArrayConstructor)->entry; | 27 Runtime::kArrayConstructor)->entry; |
134 | 28 |
135 if (constant_stack_parameter_count == 0) { | 29 if (constant_stack_parameter_count == 0) { |
136 Register registers[] = { rsi, rdi, rbx }; | 30 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
137 descriptor->Initialize(major, arraysize(registers), registers, | 31 CallDescriptorKey::ArrayConstructorConstantArgCountCall); |
138 deopt_handler, NULL, constant_stack_parameter_count, | 32 descriptor->Initialize(major, call_descriptor, deopt_handler, |
| 33 constant_stack_parameter_count, |
139 JS_FUNCTION_STUB_MODE); | 34 JS_FUNCTION_STUB_MODE); |
140 } else { | 35 } else { |
141 // stack param count needs (constructor pointer, and single argument) | 36 CallInterfaceDescriptor* call_descriptor = |
142 Register registers[] = { rsi, rdi, rbx, rax }; | 37 isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall); |
143 Representation representations[] = { | 38 descriptor->Initialize(major, call_descriptor, rax, deopt_handler, |
144 Representation::Tagged(), | |
145 Representation::Tagged(), | |
146 Representation::Tagged(), | |
147 Representation::Integer32() }; | |
148 descriptor->Initialize(major, arraysize(registers), registers, rax, | |
149 deopt_handler, representations, | |
150 constant_stack_parameter_count, | 39 constant_stack_parameter_count, |
151 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 40 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
152 } | 41 } |
153 } | 42 } |
154 | 43 |
155 | 44 |
156 static void InitializeInternalArrayConstructorDescriptor( | 45 static void InitializeInternalArrayConstructorDescriptor( |
157 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, | 46 Isolate* isolate, CodeStub::Major major, |
| 47 CodeStubInterfaceDescriptor* descriptor, |
158 int constant_stack_parameter_count) { | 48 int constant_stack_parameter_count) { |
159 // register state | 49 // register state |
160 // rsi -- context | 50 // rsi -- context |
161 // rax -- number of arguments | 51 // rax -- number of arguments |
162 // rdi -- constructor function | 52 // rdi -- constructor function |
163 Address deopt_handler = Runtime::FunctionForId( | 53 Address deopt_handler = Runtime::FunctionForId( |
164 Runtime::kInternalArrayConstructor)->entry; | 54 Runtime::kInternalArrayConstructor)->entry; |
165 | 55 |
166 if (constant_stack_parameter_count == 0) { | 56 if (constant_stack_parameter_count == 0) { |
167 Register registers[] = { rsi, rdi }; | 57 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
168 descriptor->Initialize(major, arraysize(registers), registers, | 58 CallDescriptorKey::InternalArrayConstructorConstantArgCountCall); |
169 deopt_handler, NULL, constant_stack_parameter_count, | 59 descriptor->Initialize(major, call_descriptor, deopt_handler, |
| 60 constant_stack_parameter_count, |
170 JS_FUNCTION_STUB_MODE); | 61 JS_FUNCTION_STUB_MODE); |
171 } else { | 62 } else { |
172 // stack param count needs (constructor pointer, and single argument) | 63 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
173 Register registers[] = { rsi, rdi, rax }; | 64 CallDescriptorKey::InternalArrayConstructorCall); |
174 Representation representations[] = { | 65 descriptor->Initialize(major, call_descriptor, rax, deopt_handler, |
175 Representation::Tagged(), | |
176 Representation::Tagged(), | |
177 Representation::Integer32() }; | |
178 descriptor->Initialize(major, arraysize(registers), registers, rax, | |
179 deopt_handler, representations, | |
180 constant_stack_parameter_count, | 66 constant_stack_parameter_count, |
181 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 67 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
182 } | 68 } |
183 } | 69 } |
184 | 70 |
185 | 71 |
186 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 72 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
187 CodeStubInterfaceDescriptor* descriptor) { | 73 CodeStubInterfaceDescriptor* descriptor) { |
188 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 0); | 74 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 0); |
189 } | 75 } |
190 | 76 |
191 | 77 |
192 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 78 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
193 CodeStubInterfaceDescriptor* descriptor) { | 79 CodeStubInterfaceDescriptor* descriptor) { |
194 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 1); | 80 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 1); |
195 } | 81 } |
196 | 82 |
197 | 83 |
198 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 84 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
199 CodeStubInterfaceDescriptor* descriptor) { | 85 CodeStubInterfaceDescriptor* descriptor) { |
200 InitializeArrayConstructorDescriptor(MajorKey(), descriptor, -1); | 86 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, -1); |
201 } | 87 } |
202 | 88 |
203 | 89 |
204 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 90 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
205 CodeStubInterfaceDescriptor* descriptor) { | 91 CodeStubInterfaceDescriptor* descriptor) { |
206 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0); | 92 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 93 descriptor, 0); |
207 } | 94 } |
208 | 95 |
209 | 96 |
210 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 97 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
211 CodeStubInterfaceDescriptor* descriptor) { | 98 CodeStubInterfaceDescriptor* descriptor) { |
212 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1); | 99 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 100 descriptor, 1); |
213 } | 101 } |
214 | 102 |
215 | 103 |
216 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 104 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
217 CodeStubInterfaceDescriptor* descriptor) { | 105 CodeStubInterfaceDescriptor* descriptor) { |
218 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1); | 106 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 107 descriptor, -1); |
219 } | 108 } |
220 | 109 |
221 | 110 |
222 void CompareNilICStub::InitializeInterfaceDescriptor( | |
223 CodeStubInterfaceDescriptor* descriptor) { | |
224 Register registers[] = { rsi, rax }; | |
225 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
226 FUNCTION_ADDR(CompareNilIC_Miss)); | |
227 descriptor->SetMissHandler( | |
228 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); | |
229 } | |
230 | |
231 | |
232 void ToBooleanStub::InitializeInterfaceDescriptor( | |
233 CodeStubInterfaceDescriptor* descriptor) { | |
234 Register registers[] = { rsi, rax }; | |
235 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
236 FUNCTION_ADDR(ToBooleanIC_Miss)); | |
237 descriptor->SetMissHandler( | |
238 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); | |
239 } | |
240 | |
241 | |
242 void BinaryOpICStub::InitializeInterfaceDescriptor( | |
243 CodeStubInterfaceDescriptor* descriptor) { | |
244 Register registers[] = { rsi, rdx, rax }; | |
245 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
246 FUNCTION_ADDR(BinaryOpIC_Miss)); | |
247 descriptor->SetMissHandler( | |
248 ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); | |
249 } | |
250 | |
251 | |
252 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( | |
253 CodeStubInterfaceDescriptor* descriptor) { | |
254 Register registers[] = { rsi, rcx, rdx, rax }; | |
255 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
256 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); | |
257 } | |
258 | |
259 | |
260 void StringAddStub::InitializeInterfaceDescriptor( | |
261 CodeStubInterfaceDescriptor* descriptor) { | |
262 Register registers[] = { rsi, rdx, rax }; | |
263 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
264 Runtime::FunctionForId(Runtime::kStringAdd)->entry); | |
265 } | |
266 | |
267 | |
268 #define __ ACCESS_MASM(masm) | 111 #define __ ACCESS_MASM(masm) |
269 | 112 |
270 | 113 |
271 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 114 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
272 // Update the static counter each time a new code stub is generated. | 115 // Update the static counter each time a new code stub is generated. |
273 isolate()->counters()->code_stubs()->Increment(); | 116 isolate()->counters()->code_stubs()->Increment(); |
274 | 117 |
275 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); | 118 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); |
276 int param_count = descriptor->GetEnvironmentParameterCount(); | 119 int param_count = descriptor->GetEnvironmentParameterCount(); |
277 { | 120 { |
(...skipping 2573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2851 __ jmp(&done, Label::kNear); | 2694 __ jmp(&done, Label::kNear); |
2852 __ bind(&true_value); | 2695 __ bind(&true_value); |
2853 __ LoadRoot(rax, Heap::kTrueValueRootIndex); | 2696 __ LoadRoot(rax, Heap::kTrueValueRootIndex); |
2854 __ bind(&done); | 2697 __ bind(&done); |
2855 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) * | 2698 __ ret(((HasArgsInRegisters() ? 0 : 2) + extra_argument_offset) * |
2856 kPointerSize); | 2699 kPointerSize); |
2857 } | 2700 } |
2858 } | 2701 } |
2859 | 2702 |
2860 | 2703 |
2861 // Passing arguments in registers is not supported. | |
2862 Register InstanceofStub::left() { return rax; } | |
2863 | |
2864 | |
2865 Register InstanceofStub::right() { return rdx; } | |
2866 | |
2867 | |
2868 // ------------------------------------------------------------------------- | 2704 // ------------------------------------------------------------------------- |
2869 // StringCharCodeAtGenerator | 2705 // StringCharCodeAtGenerator |
2870 | 2706 |
2871 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2707 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
2872 Label flat_string; | 2708 Label flat_string; |
2873 Label ascii_string; | 2709 Label ascii_string; |
2874 Label got_char_code; | 2710 Label got_char_code; |
2875 Label sliced_string; | 2711 Label sliced_string; |
2876 | 2712 |
2877 // If the receiver is a smi trigger the non-string case. | 2713 // If the receiver is a smi trigger the non-string case. |
(...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4912 return_value_operand, | 4748 return_value_operand, |
4913 NULL); | 4749 NULL); |
4914 } | 4750 } |
4915 | 4751 |
4916 | 4752 |
4917 #undef __ | 4753 #undef __ |
4918 | 4754 |
4919 } } // namespace v8::internal | 4755 } } // namespace v8::internal |
4920 | 4756 |
4921 #endif // V8_TARGET_ARCH_X64 | 4757 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |