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/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 | 2207 |
2208 // Unreachable. | 2208 // Unreachable. |
2209 __ int3(); | 2209 __ int3(); |
2210 } | 2210 } |
2211 | 2211 |
2212 | 2212 |
2213 void CallICStub::Generate(MacroAssembler* masm) { | 2213 void CallICStub::Generate(MacroAssembler* masm) { |
2214 // edi - function | 2214 // edi - function |
2215 // edx - slot id | 2215 // edx - slot id |
2216 Isolate* isolate = masm->isolate(); | 2216 Isolate* isolate = masm->isolate(); |
| 2217 const int with_types_offset = |
| 2218 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2219 const int generic_offset = |
| 2220 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
2217 Label extra_checks_or_miss, slow_start; | 2221 Label extra_checks_or_miss, slow_start; |
2218 Label slow, non_function, wrap, cont; | 2222 Label slow, non_function, wrap, cont; |
2219 Label have_js_function; | 2223 Label have_js_function; |
2220 int argc = arg_count(); | 2224 int argc = arg_count(); |
2221 ParameterCount actual(argc); | 2225 ParameterCount actual(argc); |
2222 | 2226 |
2223 EmitLoadTypeFeedbackVector(masm, ebx); | 2227 EmitLoadTypeFeedbackVector(masm, ebx); |
2224 | 2228 |
2225 // The checks. First, does edi match the recorded monomorphic target? | 2229 // The checks. First, does edi match the recorded monomorphic target? |
2226 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, | 2230 __ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, |
(...skipping 19 matching lines...) Expand all Loading... |
2246 | 2250 |
2247 __ bind(&slow); | 2251 __ bind(&slow); |
2248 EmitSlowCase(isolate, masm, argc, &non_function); | 2252 EmitSlowCase(isolate, masm, argc, &non_function); |
2249 | 2253 |
2250 if (CallAsMethod()) { | 2254 if (CallAsMethod()) { |
2251 __ bind(&wrap); | 2255 __ bind(&wrap); |
2252 EmitWrapCase(masm, argc, &cont); | 2256 EmitWrapCase(masm, argc, &cont); |
2253 } | 2257 } |
2254 | 2258 |
2255 __ bind(&extra_checks_or_miss); | 2259 __ bind(&extra_checks_or_miss); |
2256 Label miss; | 2260 Label uninitialized, miss; |
2257 | 2261 |
2258 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 2262 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
2259 FixedArray::kHeaderSize)); | 2263 FixedArray::kHeaderSize)); |
2260 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 2264 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
2261 __ j(equal, &slow_start); | 2265 __ j(equal, &slow_start); |
| 2266 |
| 2267 // The following cases attempt to handle MISS cases without going to the |
| 2268 // runtime. |
| 2269 if (FLAG_trace_ic) { |
| 2270 __ jmp(&miss); |
| 2271 } |
| 2272 |
2262 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); | 2273 __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate))); |
| 2274 __ j(equal, &uninitialized); |
| 2275 |
| 2276 // We are going megamorphic. If the feedback is a JSFunction, it is fine |
| 2277 // to handle it here. More complex cases are dealt with in the runtime. |
| 2278 __ AssertNotSmi(ecx); |
| 2279 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); |
| 2280 __ j(not_equal, &miss); |
| 2281 __ mov( |
| 2282 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
| 2283 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
| 2284 // We have to update statistics for runtime profiling. |
| 2285 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); |
| 2286 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); |
| 2287 __ jmp(&slow_start); |
| 2288 |
| 2289 __ bind(&uninitialized); |
| 2290 |
| 2291 // We are going monomorphic, provided we actually have a JSFunction. |
| 2292 __ JumpIfSmi(edi, &miss); |
| 2293 |
| 2294 // Goto miss case if we do not have a function. |
| 2295 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2296 __ j(not_equal, &miss); |
| 2297 |
| 2298 // Make sure the function is not the Array() function, which requires special |
| 2299 // behavior on MISS. |
| 2300 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
| 2301 __ cmp(edi, ecx); |
2263 __ j(equal, &miss); | 2302 __ j(equal, &miss); |
2264 | 2303 |
2265 if (!FLAG_trace_ic) { | 2304 // Update stats. |
2266 // We are going megamorphic. If the feedback is a JSFunction, it is fine | 2305 __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); |
2267 // to handle it here. More complex cases are dealt with in the runtime. | |
2268 __ AssertNotSmi(ecx); | |
2269 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); | |
2270 __ j(not_equal, &miss); | |
2271 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | |
2272 FixedArray::kHeaderSize), | |
2273 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | |
2274 // We have to update statistics for runtime profiling. | |
2275 const int with_types_offset = | |
2276 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | |
2277 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); | |
2278 const int generic_offset = | |
2279 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | |
2280 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); | |
2281 __ jmp(&slow_start); | |
2282 } | |
2283 | 2306 |
2284 // We are here because tracing is on or we are going monomorphic. | 2307 // Store the function. |
| 2308 __ mov( |
| 2309 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), |
| 2310 edi); |
| 2311 |
| 2312 // Update the write barrier. |
| 2313 __ mov(eax, edi); |
| 2314 __ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
| 2315 OMIT_SMI_CHECK); |
| 2316 __ jmp(&have_js_function); |
| 2317 |
| 2318 // We are here because tracing is on or we encountered a MISS case we can't |
| 2319 // handle here. |
2285 __ bind(&miss); | 2320 __ bind(&miss); |
2286 GenerateMiss(masm); | 2321 GenerateMiss(masm); |
2287 | 2322 |
2288 // the slow case | 2323 // the slow case |
2289 __ bind(&slow_start); | 2324 __ bind(&slow_start); |
2290 | 2325 |
2291 // Check that the function really is a JavaScript function. | 2326 // Check that the function really is a JavaScript function. |
2292 __ JumpIfSmi(edi, &non_function); | 2327 __ JumpIfSmi(edi, &non_function); |
2293 | 2328 |
2294 // Goto slow case if we do not have a function. | 2329 // Goto slow case if we do not have a function. |
(...skipping 2446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4741 Operand(ebp, 7 * kPointerSize), | 4776 Operand(ebp, 7 * kPointerSize), |
4742 NULL); | 4777 NULL); |
4743 } | 4778 } |
4744 | 4779 |
4745 | 4780 |
4746 #undef __ | 4781 #undef __ |
4747 | 4782 |
4748 } } // namespace v8::internal | 4783 } } // namespace v8::internal |
4749 | 4784 |
4750 #endif // V8_TARGET_ARCH_IA32 | 4785 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |