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/isolate.h" | 12 #include "src/isolate.h" |
13 #include "src/jsregexp.h" | 13 #include "src/jsregexp.h" |
14 #include "src/regexp-macro-assembler.h" | 14 #include "src/regexp-macro-assembler.h" |
15 #include "src/runtime.h" | 15 #include "src/runtime.h" |
16 #include "src/stub-cache.h" | 16 #include "src/stub-cache.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 | 20 |
21 | 21 |
22 void FastNewClosureStub::InitializeInterfaceDescriptor( | 22 void FastNewClosureStub::InitializeInterfaceDescriptor( |
23 CodeStubInterfaceDescriptor* descriptor) { | 23 CodeStubInterfaceDescriptor* descriptor) { |
24 Register registers[] = { esi, ebx }; | 24 Register registers[] = { esi, ebx }; |
25 descriptor->Initialize( | 25 descriptor->Initialize( |
26 ARRAY_SIZE(registers), registers, | 26 MajorKey(), ARRAY_SIZE(registers), registers, |
27 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); | 27 Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry); |
28 } | 28 } |
29 | 29 |
30 | 30 |
31 void FastNewContextStub::InitializeInterfaceDescriptor( | 31 void FastNewContextStub::InitializeInterfaceDescriptor( |
32 CodeStubInterfaceDescriptor* descriptor) { | 32 CodeStubInterfaceDescriptor* descriptor) { |
33 Register registers[] = { esi, edi }; | 33 Register registers[] = { esi, edi }; |
34 descriptor->Initialize(ARRAY_SIZE(registers), registers); | 34 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 void ToNumberStub::InitializeInterfaceDescriptor( | 38 void ToNumberStub::InitializeInterfaceDescriptor( |
39 CodeStubInterfaceDescriptor* descriptor) { | 39 CodeStubInterfaceDescriptor* descriptor) { |
40 // ToNumberStub invokes a function, and therefore needs a context. | 40 // ToNumberStub invokes a function, and therefore needs a context. |
41 Register registers[] = { esi, eax }; | 41 Register registers[] = { esi, eax }; |
42 descriptor->Initialize(ARRAY_SIZE(registers), registers); | 42 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
43 } | 43 } |
44 | 44 |
45 | 45 |
46 void NumberToStringStub::InitializeInterfaceDescriptor( | 46 void NumberToStringStub::InitializeInterfaceDescriptor( |
47 CodeStubInterfaceDescriptor* descriptor) { | 47 CodeStubInterfaceDescriptor* descriptor) { |
48 Register registers[] = { esi, eax }; | 48 Register registers[] = { esi, eax }; |
49 descriptor->Initialize( | 49 descriptor->Initialize( |
50 ARRAY_SIZE(registers), registers, | 50 MajorKey(), ARRAY_SIZE(registers), registers, |
51 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); | 51 Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry); |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( | 55 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( |
56 CodeStubInterfaceDescriptor* descriptor) { | 56 CodeStubInterfaceDescriptor* descriptor) { |
57 Register registers[] = { esi, eax, ebx, ecx }; | 57 Register registers[] = { esi, eax, ebx, ecx }; |
58 Representation representations[] = { | 58 Representation representations[] = { |
59 Representation::Tagged(), | 59 Representation::Tagged(), |
60 Representation::Tagged(), | 60 Representation::Tagged(), |
61 Representation::Smi(), | 61 Representation::Smi(), |
62 Representation::Tagged() }; | 62 Representation::Tagged() }; |
63 | 63 |
64 descriptor->Initialize( | 64 descriptor->Initialize( |
65 ARRAY_SIZE(registers), registers, | 65 MajorKey(), ARRAY_SIZE(registers), registers, |
66 Runtime::FunctionForId( | 66 Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry, |
67 Runtime::kCreateArrayLiteralStubBailout)->entry, | |
68 representations); | 67 representations); |
69 } | 68 } |
70 | 69 |
71 | 70 |
72 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( | 71 void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( |
73 CodeStubInterfaceDescriptor* descriptor) { | 72 CodeStubInterfaceDescriptor* descriptor) { |
74 Register registers[] = { esi, eax, ebx, ecx, edx }; | 73 Register registers[] = { esi, eax, ebx, ecx, edx }; |
75 descriptor->Initialize( | 74 descriptor->Initialize( |
76 ARRAY_SIZE(registers), registers, | 75 MajorKey(), ARRAY_SIZE(registers), registers, |
77 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); | 76 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry); |
78 } | 77 } |
79 | 78 |
80 | 79 |
81 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( | 80 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( |
82 CodeStubInterfaceDescriptor* descriptor) { | 81 CodeStubInterfaceDescriptor* descriptor) { |
83 Register registers[] = { esi, ebx, edx }; | 82 Register registers[] = { esi, ebx, edx }; |
84 descriptor->Initialize(ARRAY_SIZE(registers), registers); | 83 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
85 } | 84 } |
86 | 85 |
87 | 86 |
| 87 void InstanceofStub::InitializeInterfaceDescriptor( |
| 88 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 89 Register registers[] = {esi, left(), right()}; |
| 90 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 91 } |
| 92 |
| 93 |
| 94 void CallFunctionStub::InitializeInterfaceDescriptor( |
| 95 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 96 Register registers[] = {esi, edi}; |
| 97 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 98 } |
| 99 |
| 100 |
| 101 void CallConstructStub::InitializeInterfaceDescriptor( |
| 102 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { |
| 103 // eax : number of arguments |
| 104 // ebx : feedback vector |
| 105 // edx : (only if ebx is not the megamorphic symbol) slot in feedback |
| 106 // vector (Smi) |
| 107 // edi : constructor function |
| 108 // TODO(turbofan): So far we don't gather type feedback and hence skip the |
| 109 // slot parameter, but ArrayConstructStub needs the vector to be undefined. |
| 110 Register registers[] = {esi, eax, edi, ebx}; |
| 111 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers); |
| 112 } |
| 113 |
| 114 |
88 void RegExpConstructResultStub::InitializeInterfaceDescriptor( | 115 void RegExpConstructResultStub::InitializeInterfaceDescriptor( |
89 CodeStubInterfaceDescriptor* descriptor) { | 116 CodeStubInterfaceDescriptor* descriptor) { |
90 Register registers[] = { esi, ecx, ebx, eax }; | 117 Register registers[] = { esi, ecx, ebx, eax }; |
91 descriptor->Initialize( | 118 descriptor->Initialize( |
92 ARRAY_SIZE(registers), registers, | 119 MajorKey(), ARRAY_SIZE(registers), registers, |
93 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); | 120 Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry); |
94 } | 121 } |
95 | 122 |
96 | 123 |
97 void TransitionElementsKindStub::InitializeInterfaceDescriptor( | 124 void TransitionElementsKindStub::InitializeInterfaceDescriptor( |
98 CodeStubInterfaceDescriptor* descriptor) { | 125 CodeStubInterfaceDescriptor* descriptor) { |
99 Register registers[] = { esi, eax, ebx }; | 126 Register registers[] = { esi, eax, ebx }; |
100 descriptor->Initialize( | 127 descriptor->Initialize( |
101 ARRAY_SIZE(registers), registers, | 128 MajorKey(), ARRAY_SIZE(registers), registers, |
102 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry); | 129 Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry); |
103 } | 130 } |
104 | 131 |
105 | 132 |
106 const Register InterfaceDescriptor::ContextRegister() { return esi; } | 133 const Register InterfaceDescriptor::ContextRegister() { return esi; } |
107 | 134 |
108 | 135 |
109 static void InitializeArrayConstructorDescriptor( | 136 static void InitializeArrayConstructorDescriptor( |
110 Isolate* isolate, | 137 Isolate* isolate, CodeStub::Major major, |
111 CodeStubInterfaceDescriptor* descriptor, | 138 CodeStubInterfaceDescriptor* descriptor, |
112 int constant_stack_parameter_count) { | 139 int constant_stack_parameter_count) { |
113 // register state | 140 // register state |
114 // eax -- number of arguments | 141 // eax -- number of arguments |
115 // edi -- function | 142 // edi -- function |
116 // ebx -- allocation site with elements kind | 143 // ebx -- allocation site with elements kind |
117 Address deopt_handler = Runtime::FunctionForId( | 144 Address deopt_handler = Runtime::FunctionForId( |
118 Runtime::kArrayConstructor)->entry; | 145 Runtime::kArrayConstructor)->entry; |
119 | 146 |
120 if (constant_stack_parameter_count == 0) { | 147 if (constant_stack_parameter_count == 0) { |
121 Register registers[] = { esi, edi, ebx }; | 148 Register registers[] = { esi, edi, ebx }; |
122 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 149 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, |
123 deopt_handler, | 150 deopt_handler, NULL, constant_stack_parameter_count, |
124 NULL, | |
125 constant_stack_parameter_count, | |
126 JS_FUNCTION_STUB_MODE); | 151 JS_FUNCTION_STUB_MODE); |
127 } else { | 152 } else { |
128 // stack param count needs (constructor pointer, and single argument) | 153 // stack param count needs (constructor pointer, and single argument) |
129 Register registers[] = { esi, edi, ebx, eax }; | 154 Register registers[] = { esi, edi, ebx, eax }; |
130 Representation representations[] = { | 155 Representation representations[] = { |
131 Representation::Tagged(), | 156 Representation::Tagged(), |
132 Representation::Tagged(), | 157 Representation::Tagged(), |
133 Representation::Tagged(), | 158 Representation::Tagged(), |
134 Representation::Integer32() }; | 159 Representation::Integer32() }; |
135 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 160 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, eax, |
136 eax, | 161 deopt_handler, representations, |
137 deopt_handler, | |
138 representations, | |
139 constant_stack_parameter_count, | 162 constant_stack_parameter_count, |
140 JS_FUNCTION_STUB_MODE, | 163 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
141 PASS_ARGUMENTS); | |
142 } | 164 } |
143 } | 165 } |
144 | 166 |
145 | 167 |
146 static void InitializeInternalArrayConstructorDescriptor( | 168 static void InitializeInternalArrayConstructorDescriptor( |
147 CodeStubInterfaceDescriptor* descriptor, | 169 CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor, |
148 int constant_stack_parameter_count) { | 170 int constant_stack_parameter_count) { |
149 // register state | 171 // register state |
150 // eax -- number of arguments | 172 // eax -- number of arguments |
151 // edi -- constructor function | 173 // edi -- constructor function |
152 Address deopt_handler = Runtime::FunctionForId( | 174 Address deopt_handler = Runtime::FunctionForId( |
153 Runtime::kInternalArrayConstructor)->entry; | 175 Runtime::kInternalArrayConstructor)->entry; |
154 | 176 |
155 if (constant_stack_parameter_count == 0) { | 177 if (constant_stack_parameter_count == 0) { |
156 Register registers[] = { esi, edi }; | 178 Register registers[] = { esi, edi }; |
157 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 179 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, |
158 deopt_handler, | 180 deopt_handler, NULL, constant_stack_parameter_count, |
159 NULL, | |
160 constant_stack_parameter_count, | |
161 JS_FUNCTION_STUB_MODE); | 181 JS_FUNCTION_STUB_MODE); |
162 } else { | 182 } else { |
163 // stack param count needs (constructor pointer, and single argument) | 183 // stack param count needs (constructor pointer, and single argument) |
164 Register registers[] = { esi, edi, eax }; | 184 Register registers[] = { esi, edi, eax }; |
165 Representation representations[] = { | 185 Representation representations[] = { |
166 Representation::Tagged(), | 186 Representation::Tagged(), |
167 Representation::Tagged(), | 187 Representation::Tagged(), |
168 Representation::Integer32() }; | 188 Representation::Integer32() }; |
169 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 189 descriptor->Initialize(major, ARRAY_SIZE(registers), registers, eax, |
170 eax, | 190 deopt_handler, representations, |
171 deopt_handler, | |
172 representations, | |
173 constant_stack_parameter_count, | 191 constant_stack_parameter_count, |
174 JS_FUNCTION_STUB_MODE, | 192 JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS); |
175 PASS_ARGUMENTS); | |
176 } | 193 } |
177 } | 194 } |
178 | 195 |
179 | 196 |
180 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 197 void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
181 CodeStubInterfaceDescriptor* descriptor) { | 198 CodeStubInterfaceDescriptor* descriptor) { |
182 InitializeArrayConstructorDescriptor(isolate(), descriptor, 0); | 199 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 0); |
183 } | 200 } |
184 | 201 |
185 | 202 |
186 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 203 void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
187 CodeStubInterfaceDescriptor* descriptor) { | 204 CodeStubInterfaceDescriptor* descriptor) { |
188 InitializeArrayConstructorDescriptor(isolate(), descriptor, 1); | 205 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, 1); |
189 } | 206 } |
190 | 207 |
191 | 208 |
192 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 209 void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
193 CodeStubInterfaceDescriptor* descriptor) { | 210 CodeStubInterfaceDescriptor* descriptor) { |
194 InitializeArrayConstructorDescriptor(isolate(), descriptor, -1); | 211 InitializeArrayConstructorDescriptor(isolate(), MajorKey(), descriptor, -1); |
195 } | 212 } |
196 | 213 |
197 | 214 |
198 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( | 215 void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor( |
199 CodeStubInterfaceDescriptor* descriptor) { | 216 CodeStubInterfaceDescriptor* descriptor) { |
200 InitializeInternalArrayConstructorDescriptor(descriptor, 0); | 217 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0); |
201 } | 218 } |
202 | 219 |
203 | 220 |
204 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( | 221 void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor( |
205 CodeStubInterfaceDescriptor* descriptor) { | 222 CodeStubInterfaceDescriptor* descriptor) { |
206 InitializeInternalArrayConstructorDescriptor(descriptor, 1); | 223 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1); |
207 } | 224 } |
208 | 225 |
209 | 226 |
210 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( | 227 void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor( |
211 CodeStubInterfaceDescriptor* descriptor) { | 228 CodeStubInterfaceDescriptor* descriptor) { |
212 InitializeInternalArrayConstructorDescriptor(descriptor, -1); | 229 InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1); |
213 } | 230 } |
214 | 231 |
215 | 232 |
216 void CompareNilICStub::InitializeInterfaceDescriptor( | 233 void CompareNilICStub::InitializeInterfaceDescriptor( |
217 CodeStubInterfaceDescriptor* descriptor) { | 234 CodeStubInterfaceDescriptor* descriptor) { |
218 Register registers[] = { esi, eax }; | 235 Register registers[] = { esi, eax }; |
219 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 236 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, |
220 FUNCTION_ADDR(CompareNilIC_Miss)); | 237 FUNCTION_ADDR(CompareNilIC_Miss)); |
221 descriptor->SetMissHandler( | 238 descriptor->SetMissHandler( |
222 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); | 239 ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate())); |
223 } | 240 } |
224 | 241 |
225 void ToBooleanStub::InitializeInterfaceDescriptor( | 242 void ToBooleanStub::InitializeInterfaceDescriptor( |
226 CodeStubInterfaceDescriptor* descriptor) { | 243 CodeStubInterfaceDescriptor* descriptor) { |
227 Register registers[] = { esi, eax }; | 244 Register registers[] = { esi, eax }; |
228 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 245 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, |
229 FUNCTION_ADDR(ToBooleanIC_Miss)); | 246 FUNCTION_ADDR(ToBooleanIC_Miss)); |
230 descriptor->SetMissHandler( | 247 descriptor->SetMissHandler( |
231 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); | 248 ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate())); |
232 } | 249 } |
233 | 250 |
234 | 251 |
235 void BinaryOpICStub::InitializeInterfaceDescriptor( | 252 void BinaryOpICStub::InitializeInterfaceDescriptor( |
236 CodeStubInterfaceDescriptor* descriptor) { | 253 CodeStubInterfaceDescriptor* descriptor) { |
237 Register registers[] = { esi, edx, eax }; | 254 Register registers[] = { esi, edx, eax }; |
238 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 255 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, |
239 FUNCTION_ADDR(BinaryOpIC_Miss)); | 256 FUNCTION_ADDR(BinaryOpIC_Miss)); |
240 descriptor->SetMissHandler( | 257 descriptor->SetMissHandler( |
241 ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); | 258 ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate())); |
242 } | 259 } |
243 | 260 |
244 | 261 |
245 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( | 262 void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor( |
246 CodeStubInterfaceDescriptor* descriptor) { | 263 CodeStubInterfaceDescriptor* descriptor) { |
247 Register registers[] = { esi, ecx, edx, eax }; | 264 Register registers[] = { esi, ecx, edx, eax }; |
248 descriptor->Initialize(ARRAY_SIZE(registers), registers, | 265 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, |
249 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); | 266 FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite)); |
250 } | 267 } |
251 | 268 |
252 | 269 |
253 void StringAddStub::InitializeInterfaceDescriptor( | 270 void StringAddStub::InitializeInterfaceDescriptor( |
254 CodeStubInterfaceDescriptor* descriptor) { | 271 CodeStubInterfaceDescriptor* descriptor) { |
255 Register registers[] = { esi, edx, eax }; | 272 Register registers[] = { esi, edx, eax }; |
256 descriptor->Initialize( | 273 descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers, |
257 ARRAY_SIZE(registers), registers, | 274 Runtime::FunctionForId(Runtime::kStringAdd)->entry); |
258 Runtime::FunctionForId(Runtime::kStringAdd)->entry); | |
259 } | 275 } |
260 | 276 |
261 | 277 |
262 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { | 278 void CallDescriptors::InitializeForIsolate(Isolate* isolate) { |
263 { | 279 { |
264 CallInterfaceDescriptor* descriptor = | 280 CallInterfaceDescriptor* descriptor = |
265 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); | 281 isolate->call_descriptor(Isolate::ArgumentAdaptorCall); |
266 Register registers[] = { esi, // context | 282 Register registers[] = { esi, // context |
267 edi, // JSFunction | 283 edi, // JSFunction |
268 eax, // actual number of arguments | 284 eax, // actual number of arguments |
(...skipping 2507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2776 __ mov(object, Operand(esp, 2 * kPointerSize)); | 2792 __ mov(object, Operand(esp, 2 * kPointerSize)); |
2777 __ mov(function, Operand(esp, 1 * kPointerSize)); | 2793 __ mov(function, Operand(esp, 1 * kPointerSize)); |
2778 } | 2794 } |
2779 | 2795 |
2780 // Check that the left hand is a JS object. | 2796 // Check that the left hand is a JS object. |
2781 __ JumpIfSmi(object, ¬_js_object); | 2797 __ JumpIfSmi(object, ¬_js_object); |
2782 __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); | 2798 __ IsObjectJSObjectType(object, map, scratch, ¬_js_object); |
2783 | 2799 |
2784 // If there is a call site cache don't look in the global cache, but do the | 2800 // If there is a call site cache don't look in the global cache, but do the |
2785 // real lookup and update the call site cache. | 2801 // real lookup and update the call site cache. |
2786 if (!HasCallSiteInlineCheck()) { | 2802 if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) { |
2787 // Look up the function and the map in the instanceof cache. | 2803 // Look up the function and the map in the instanceof cache. |
2788 Label miss; | 2804 Label miss; |
2789 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex); | 2805 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex); |
2790 __ j(not_equal, &miss, Label::kNear); | 2806 __ j(not_equal, &miss, Label::kNear); |
2791 __ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex); | 2807 __ CompareRoot(map, scratch, Heap::kInstanceofCacheMapRootIndex); |
2792 __ j(not_equal, &miss, Label::kNear); | 2808 __ j(not_equal, &miss, Label::kNear); |
2793 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex); | 2809 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex); |
2794 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2810 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2795 __ bind(&miss); | 2811 __ bind(&miss); |
2796 } | 2812 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2835 __ cmp(scratch, Immediate(factory->null_value())); | 2851 __ cmp(scratch, Immediate(factory->null_value())); |
2836 __ j(equal, &is_not_instance, Label::kNear); | 2852 __ j(equal, &is_not_instance, Label::kNear); |
2837 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); | 2853 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); |
2838 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); | 2854 __ mov(scratch, FieldOperand(scratch, Map::kPrototypeOffset)); |
2839 __ jmp(&loop); | 2855 __ jmp(&loop); |
2840 | 2856 |
2841 __ bind(&is_instance); | 2857 __ bind(&is_instance); |
2842 if (!HasCallSiteInlineCheck()) { | 2858 if (!HasCallSiteInlineCheck()) { |
2843 __ mov(eax, Immediate(0)); | 2859 __ mov(eax, Immediate(0)); |
2844 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); | 2860 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); |
| 2861 if (ReturnTrueFalseObject()) { |
| 2862 __ mov(eax, factory->true_value()); |
| 2863 } |
2845 } else { | 2864 } else { |
2846 // Get return address and delta to inlined map check. | 2865 // Get return address and delta to inlined map check. |
2847 __ mov(eax, factory->true_value()); | 2866 __ mov(eax, factory->true_value()); |
2848 __ mov(scratch, Operand(esp, 0 * kPointerSize)); | 2867 __ mov(scratch, Operand(esp, 0 * kPointerSize)); |
2849 __ sub(scratch, Operand(esp, 1 * kPointerSize)); | 2868 __ sub(scratch, Operand(esp, 1 * kPointerSize)); |
2850 if (FLAG_debug_code) { | 2869 if (FLAG_debug_code) { |
2851 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); | 2870 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); |
2852 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); | 2871 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); |
2853 } | 2872 } |
2854 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); | 2873 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); |
2855 if (!ReturnTrueFalseObject()) { | 2874 if (!ReturnTrueFalseObject()) { |
2856 __ Move(eax, Immediate(0)); | 2875 __ Move(eax, Immediate(0)); |
2857 } | 2876 } |
2858 } | 2877 } |
2859 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2878 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2860 | 2879 |
2861 __ bind(&is_not_instance); | 2880 __ bind(&is_not_instance); |
2862 if (!HasCallSiteInlineCheck()) { | 2881 if (!HasCallSiteInlineCheck()) { |
2863 __ mov(eax, Immediate(Smi::FromInt(1))); | 2882 __ mov(eax, Immediate(Smi::FromInt(1))); |
2864 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); | 2883 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex); |
| 2884 if (ReturnTrueFalseObject()) { |
| 2885 __ mov(eax, factory->false_value()); |
| 2886 } |
2865 } else { | 2887 } else { |
2866 // Get return address and delta to inlined map check. | 2888 // Get return address and delta to inlined map check. |
2867 __ mov(eax, factory->false_value()); | 2889 __ mov(eax, factory->false_value()); |
2868 __ mov(scratch, Operand(esp, 0 * kPointerSize)); | 2890 __ mov(scratch, Operand(esp, 0 * kPointerSize)); |
2869 __ sub(scratch, Operand(esp, 1 * kPointerSize)); | 2891 __ sub(scratch, Operand(esp, 1 * kPointerSize)); |
2870 if (FLAG_debug_code) { | 2892 if (FLAG_debug_code) { |
2871 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); | 2893 __ cmpb(Operand(scratch, kDeltaToMov), kMovEaxImmediateByte); |
2872 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); | 2894 __ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov); |
2873 } | 2895 } |
2874 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); | 2896 __ mov(Operand(scratch, kDeltaToMovImmediate), eax); |
2875 if (!ReturnTrueFalseObject()) { | 2897 if (!ReturnTrueFalseObject()) { |
2876 __ Move(eax, Immediate(Smi::FromInt(1))); | 2898 __ Move(eax, Immediate(Smi::FromInt(1))); |
2877 } | 2899 } |
2878 } | 2900 } |
2879 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2901 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2880 | 2902 |
2881 Label object_not_null, object_not_null_or_smi; | 2903 Label object_not_null, object_not_null_or_smi; |
2882 __ bind(¬_js_object); | 2904 __ bind(¬_js_object); |
2883 // Before null, smi and string value checks, check that the rhs is a function | 2905 // Before null, smi and string value checks, check that the rhs is a function |
2884 // as for a non-function rhs an exception needs to be thrown. | 2906 // as for a non-function rhs an exception needs to be thrown. |
2885 __ JumpIfSmi(function, &slow, Label::kNear); | 2907 __ JumpIfSmi(function, &slow, Label::kNear); |
2886 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); | 2908 __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); |
2887 __ j(not_equal, &slow, Label::kNear); | 2909 __ j(not_equal, &slow, Label::kNear); |
2888 | 2910 |
2889 // Null is not instance of anything. | 2911 // Null is not instance of anything. |
2890 __ cmp(object, factory->null_value()); | 2912 __ cmp(object, factory->null_value()); |
2891 __ j(not_equal, &object_not_null, Label::kNear); | 2913 __ j(not_equal, &object_not_null, Label::kNear); |
2892 __ Move(eax, Immediate(Smi::FromInt(1))); | 2914 if (ReturnTrueFalseObject()) { |
| 2915 __ mov(eax, factory->false_value()); |
| 2916 } else { |
| 2917 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2918 } |
2893 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2919 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2894 | 2920 |
2895 __ bind(&object_not_null); | 2921 __ bind(&object_not_null); |
2896 // Smi values is not instance of anything. | 2922 // Smi values is not instance of anything. |
2897 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear); | 2923 __ JumpIfNotSmi(object, &object_not_null_or_smi, Label::kNear); |
2898 __ Move(eax, Immediate(Smi::FromInt(1))); | 2924 if (ReturnTrueFalseObject()) { |
| 2925 __ mov(eax, factory->false_value()); |
| 2926 } else { |
| 2927 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2928 } |
2899 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2929 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2900 | 2930 |
2901 __ bind(&object_not_null_or_smi); | 2931 __ bind(&object_not_null_or_smi); |
2902 // String values is not instance of anything. | 2932 // String values is not instance of anything. |
2903 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); | 2933 Condition is_string = masm->IsObjectStringType(object, scratch, scratch); |
2904 __ j(NegateCondition(is_string), &slow, Label::kNear); | 2934 __ j(NegateCondition(is_string), &slow, Label::kNear); |
2905 __ Move(eax, Immediate(Smi::FromInt(1))); | 2935 if (ReturnTrueFalseObject()) { |
| 2936 __ mov(eax, factory->false_value()); |
| 2937 } else { |
| 2938 __ Move(eax, Immediate(Smi::FromInt(1))); |
| 2939 } |
2906 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); | 2940 __ ret((HasArgsInRegisters() ? 0 : 2) * kPointerSize); |
2907 | 2941 |
2908 // Slow-case: Go through the JavaScript implementation. | 2942 // Slow-case: Go through the JavaScript implementation. |
2909 __ bind(&slow); | 2943 __ bind(&slow); |
2910 if (!ReturnTrueFalseObject()) { | 2944 if (!ReturnTrueFalseObject()) { |
2911 // Tail call the builtin which returns 0 or 1. | 2945 // Tail call the builtin which returns 0 or 1. |
2912 if (HasArgsInRegisters()) { | 2946 if (HasArgsInRegisters()) { |
2913 // Push arguments below return address. | 2947 // Push arguments below return address. |
2914 __ pop(scratch); | 2948 __ pop(scratch); |
2915 __ push(object); | 2949 __ push(object); |
(...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4978 Operand(ebp, 7 * kPointerSize), | 5012 Operand(ebp, 7 * kPointerSize), |
4979 NULL); | 5013 NULL); |
4980 } | 5014 } |
4981 | 5015 |
4982 | 5016 |
4983 #undef __ | 5017 #undef __ |
4984 | 5018 |
4985 } } // namespace v8::internal | 5019 } } // namespace v8::internal |
4986 | 5020 |
4987 #endif // V8_TARGET_ARCH_IA32 | 5021 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |