OLD | NEW |
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 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
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[] = { esi, ebx }; | |
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[] = { esi, edi }; | |
34 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
35 } | |
36 | |
37 | |
38 void ToNumberStub::InitializeInterfaceDescriptor( | |
39 CodeStubInterfaceDescriptor* descriptor) { | |
40 // ToNumberStub invokes a function, and therefore needs a context. | |
41 Register registers[] = { esi, eax }; | |
42 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
43 } | |
44 | |
45 | |
46 void NumberToStringStub::InitializeInterfaceDescriptor( | |
47 CodeStubInterfaceDescriptor* descriptor) { | |
48 Register registers[] = { esi, eax }; | |
49 descriptor->Initialize( | |
50 MajorKey(), arraysize(registers), registers, | |
51 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); | |
52 } | |
53 | |
54 | |
55 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | |
56 CodeStubInterfaceDescriptor* descriptor) { | |
57 Register registers[] = { esi, eax, ebx, ecx }; | |
58 Representation representations[] = { | |
59 Representation::Tagged(), | |
60 Representation::Tagged(), | |
61 Representation::Smi(), | |
62 Representation::Tagged() }; | |
63 | |
64 descriptor->Initialize( | |
65 MajorKey(), arraysize(registers), registers, | |
66 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry, | |
67 representations); | |
68 } | |
69 | |
70 | |
71 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | |
72 CodeStubInterfaceDescriptor* descriptor) { | |
73 Register registers[] = { esi, eax, ebx, ecx, edx }; | |
74 descriptor->Initialize( | |
75 MajorKey(), arraysize(registers), registers, | |
76 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); | |
77 } | |
78 | |
79 | |
80 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | |
81 CodeStubInterfaceDescriptor* descriptor) { | |
82 Register registers[] = { esi, ebx, edx }; | |
83 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
84 } | |
85 | |
86 | |
87 void CallFunctionStub::InitializeInterfaceDescriptor( | |
88 CodeStubInterfaceDescriptor* descriptor) { | |
89 Register registers[] = {esi, edi}; | |
90 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
91 } | |
92 | |
93 | |
94 void CallConstructStub::InitializeInterfaceDescriptor( | |
95 CodeStubInterfaceDescriptor* descriptor) { | |
96 // eax : number of arguments | |
97 // ebx : feedback vector | |
98 // edx : (only if ebx is not the megamorphic symbol) slot in feedback | |
99 // vector (Smi) | |
100 // edi : constructor function | |
101 // TODO(turbofan): So far we don't gather type feedback and hence skip the | |
102 // slot parameter, but ArrayConstructStub needs the vector to be undefined. | |
103 Register registers[] = {esi, eax, edi, ebx}; | |
104 descriptor->Initialize(MajorKey(), arraysize(registers), registers); | |
105 } | |
106 | |
107 | |
108 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | |
109 CodeStubInterfaceDescriptor* descriptor) { | |
110 Register registers[] = { esi, ecx, ebx, eax }; | |
111 descriptor->Initialize( | |
112 MajorKey(), arraysize(registers), registers, | |
113 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | |
114 } | |
115 | |
116 | |
117 void TransitionElementsKindStub::InitializeInterfaceDescriptor( | |
118 CodeStubInterfaceDescriptor* descriptor) { | |
119 Register registers[] = { esi, eax, ebx }; | |
120 descriptor->Initialize( | |
121 MajorKey(), arraysize(registers), registers, | |
122 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry); | |
123 } | |
124 | |
125 | |
126 static void InitializeArrayConstructorDescriptor( | 22 static void InitializeArrayConstructorDescriptor( |
127 Isolate* isolate, CodeStub::Major major, | 23 Isolate* isolate, CodeStub::Major major, |
128 CodeStubInterfaceDescriptor* descriptor, | 24 CodeStubInterfaceDescriptor* descriptor, |
129 int constant_stack_parameter_count) { | 25 int constant_stack_parameter_count) { |
130 // register state | 26 // register state |
131 // eax -- number of arguments | 27 // eax -- number of arguments |
132 // edi -- function | 28 // edi -- function |
133 // ebx -- allocation site with elements kind | 29 // ebx -- allocation site with elements kind |
134 Address deopt_handler = Runtime::FunctionForId( | 30 Address deopt_handler = Runtime::FunctionForId( |
135 Runtime::kArrayConstructor)->entry; | 31 Runtime::kArrayConstructor)->entry; |
136 | 32 |
137 if (constant_stack_parameter_count == 0) { | 33 if (constant_stack_parameter_count == 0) { |
138 Register registers[] = { esi, edi, ebx }; | 34 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
139 descriptor->Initialize(major, arraysize(registers), registers, | 35 CallDescriptorKey::ArrayConstructorConstantArgCountCall); |
140 deopt_handler, NULL, constant_stack_parameter_count, | 36 descriptor->Initialize(major, call_descriptor, deopt_handler, |
| 37 constant_stack_parameter_count, |
141 JS_FUNCTION_STUB_MODE); | 38 JS_FUNCTION_STUB_MODE); |
142 } else { | 39 } else { |
143 // stack param count needs (constructor pointer, and single argument) | 40 CallInterfaceDescriptor* call_descriptor = |
144 Register registers[] = { esi, edi, ebx, eax }; | 41 isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall); |
145 Representation representations[] = { | 42 descriptor->Initialize(major, call_descriptor, eax, deopt_handler, |
146 Representation::Tagged(), | |
147 Representation::Tagged(), | |
148 Representation::Tagged(), | |
149 Representation::Integer32() }; | |
150 descriptor->Initialize(major, arraysize(registers), registers, eax, | |
151 deopt_handler, representations, | |
152 constant_stack_parameter_count, | 43 constant_stack_parameter_count, |
153 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 44 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
154 } | 45 } |
155 } | 46 } |
156 | 47 |
157 | 48 |
158 static void InitializeInternalArrayConstructorDescriptor( | 49 static void InitializeInternalArrayConstructorDescriptor( |
159 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, | 50 Isolate* isolate, CodeStub::Major major, |
| 51 CodeStubInterfaceDescriptor* descriptor, |
160 int constant_stack_parameter_count) { | 52 int constant_stack_parameter_count) { |
161 // register state | 53 // register state |
162 // eax -- number of arguments | 54 // eax -- number of arguments |
163 // edi -- constructor function | 55 // edi -- constructor function |
164 Address deopt_handler = Runtime::FunctionForId( | 56 Address deopt_handler = Runtime::FunctionForId( |
165 Runtime::kInternalArrayConstructor)->entry; | 57 Runtime::kInternalArrayConstructor)->entry; |
166 | 58 |
167 if (constant_stack_parameter_count == 0) { | 59 if (constant_stack_parameter_count == 0) { |
168 Register registers[] = { esi, edi }; | 60 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
169 descriptor->Initialize(major, arraysize(registers), registers, | 61 CallDescriptorKey::InternalArrayConstructorConstantArgCountCall); |
170 deopt_handler, NULL, constant_stack_parameter_count, | 62 descriptor->Initialize(major, call_descriptor, deopt_handler, |
| 63 constant_stack_parameter_count, |
171 JS_FUNCTION_STUB_MODE); | 64 JS_FUNCTION_STUB_MODE); |
172 } else { | 65 } else { |
173 // stack param count needs (constructor pointer, and single argument) | 66 CallInterfaceDescriptor* call_descriptor = isolate->call_descriptor( |
174 Register registers[] = { esi, edi, eax }; | 67 CallDescriptorKey::InternalArrayConstructorCall); |
175 Representation representations[] = { | 68 descriptor->Initialize(major, call_descriptor, eax, deopt_handler, |
176 Representation::Tagged(), | |
177 Representation::Tagged(), | |
178 Representation::Integer32() }; | |
179 descriptor->Initialize(major, arraysize(registers), registers, eax, | |
180 deopt_handler, representations, | |
181 constant_stack_parameter_count, | 69 constant_stack_parameter_count, |
182 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); | 70 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
183 } | 71 } |
184 } | 72 } |
185 | 73 |
186 | 74 |
187 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 75 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
188 CodeStubInterfaceDescriptor* descriptor) { | 76 CodeStubInterfaceDescriptor* descriptor) { |
189 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 0); | 77 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 0); |
190 } | 78 } |
191 | 79 |
192 | 80 |
193 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 81 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
194 CodeStubInterfaceDescriptor* descriptor) { | 82 CodeStubInterfaceDescriptor* descriptor) { |
195 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 1); | 83 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 1); |
196 } | 84 } |
197 | 85 |
198 | 86 |
199 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 87 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
200 CodeStubInterfaceDescriptor* descriptor) { | 88 CodeStubInterfaceDescriptor* descriptor) { |
201 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, -1); | 89 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, -1); |
202 } | 90 } |
203 | 91 |
204 | 92 |
205 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 93 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
206 CodeStubInterfaceDescriptor* descriptor) { | 94 CodeStubInterfaceDescriptor* descriptor) { |
207 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0); | 95 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 96 descriptor, 0); |
208 } | 97 } |
209 | 98 |
210 | 99 |
211 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 100 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
212 CodeStubInterfaceDescriptor* descriptor) { | 101 CodeStubInterfaceDescriptor* descriptor) { |
213 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1); | 102 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 103 descriptor, 1); |
214 } | 104 } |
215 | 105 |
216 | 106 |
217 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 107 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
218 CodeStubInterfaceDescriptor* descriptor) { | 108 CodeStubInterfaceDescriptor* descriptor) { |
219 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1); | 109 InitializeInternalArrayConstructorDescriptor(isolate(), MajorKey(), |
| 110 descriptor, -1); |
220 } | 111 } |
221 | 112 |
222 | 113 |
223 void CompareNilICStub::InitializeInterfaceDescriptor( | |
224 CodeStubInterfaceDescriptor* descriptor) { | |
225 Register registers[] = { esi, eax }; | |
226 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
227 FUNCTION_ADDR(CompareNilIC_Miss)); | |
228 descriptor->SetMissHandler( | |
229 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); | |
230 } | |
231 | |
232 void ToBooleanStub::InitializeInterfaceDescriptor( | |
233 CodeStubInterfaceDescriptor* descriptor) { | |
234 Register registers[] = { esi, eax }; | |
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[] = { esi, edx, eax }; | |
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[] = { esi, ecx, edx, eax }; | |
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[] = { esi, edx, eax }; | |
263 descriptor->Initialize(MajorKey(), arraysize(registers), registers, | |
264 Runtime::FunctionForId(Runtime::kStringAdd)->entry); | |
265 } | |
266 | |
267 | |
268 #define __ ACCESS_MASM(masm) | 114 #define __ ACCESS_MASM(masm) |
269 | 115 |
270 | 116 |
271 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { | 117 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { |
272 // Update the static counter each time a new code stub is generated. | 118 // Update the static counter each time a new code stub is generated. |
273 isolate()->counters()->code_stubs()->Increment(); | 119 isolate()->counters()->code_stubs()->Increment(); |
274 | 120 |
275 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); | 121 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(); |
276 int param_count = descriptor->GetEnvironmentParameterCount(); | 122 int param_count = descriptor->GetEnvironmentParameterCount(); |
277 { | 123 { |
(...skipping 2603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2881 __ mov(eax, factory->false_value()); | 2727 __ mov(eax, factory->false_value()); |
2882 __ jmp(&done, Label::kNear); | 2728 __ jmp(&done, Label::kNear); |
2883 __ bind(&true_value); | 2729 __ bind(&true_value); |
2884 __ mov(eax, factory->true_value()); | 2730 __ mov(eax, factory->true_value()); |
2885 __ bind(&done); | 2731 __ bind(&done); |
2886 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2732 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2887 } | 2733 } |
2888 } | 2734 } |
2889 | 2735 |
2890 | 2736 |
2891 Register InstanceofStub::left() { return eax; } | |
2892 | |
2893 | |
2894 Register InstanceofStub::right() { return edx; } | |
2895 | |
2896 | |
2897 // ------------------------------------------------------------------------- | 2737 // ------------------------------------------------------------------------- |
2898 // StringCharCodeAtGenerator | 2738 // StringCharCodeAtGenerator |
2899 | 2739 |
2900 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2740 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
2901 // If the receiver is a smi trigger the non-string case. | 2741 // If the receiver is a smi trigger the non-string case. |
2902 STATIC_ASSERT(kSmiTag == 0); | 2742 STATIC_ASSERT(kSmiTag == 0); |
2903 __ JumpIfSmi(object_, receiver_not_string_); | 2743 __ JumpIfSmi(object_, receiver_not_string_); |
2904 | 2744 |
2905 // Fetch the instance type of the receiver into result register. | 2745 // Fetch the instance type of the receiver into result register. |
2906 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2746 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
(...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4941 Operand(ebp, 7 * kPointerSize), | 4781 Operand(ebp, 7 * kPointerSize), |
4942 NULL); | 4782 NULL); |
4943 } | 4783 } |
4944 | 4784 |
4945 | 4785 |
4946 #undef __ | 4786 #undef __ |
4947 | 4787 |
4948 } } // namespace v8::internal | 4788 } } // namespace v8::internal |
4949 | 4789 |
4950 #endif // V8_TARGET_ARCH_IA32 | 4790 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |