OLD | NEW |
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 2260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 2271 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
2272 FixedArray::kHeaderSize)); | 2272 FixedArray::kHeaderSize)); |
2273 | 2273 |
2274 // A monomorphic cache hit or an already megamorphic state: invoke the | 2274 // A monomorphic cache hit or an already megamorphic state: invoke the |
2275 // function without changing the state. | 2275 // function without changing the state. |
2276 __ cmp(ecx, edi); | 2276 __ cmp(ecx, edi); |
2277 __ j(equal, &done, Label::kFar); | 2277 __ j(equal, &done, Label::kFar); |
2278 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); | 2278 __ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
2279 __ j(equal, &done, Label::kFar); | 2279 __ j(equal, &done, Label::kFar); |
2280 | 2280 |
2281 // If we came here, we need to see if we are the array function. | 2281 if (!FLAG_pretenuring_call_new) { |
2282 // If we didn't have a matching function, and we didn't find the megamorph | 2282 // If we came here, we need to see if we are the array function. |
2283 // sentinel, then we have in the slot either some other function or an | 2283 // If we didn't have a matching function, and we didn't find the megamorph |
2284 // AllocationSite. Do a map check on the object in ecx. | 2284 // sentinel, then we have in the slot either some other function or an |
2285 Handle<Map> allocation_site_map = | 2285 // AllocationSite. Do a map check on the object in ecx. |
2286 masm->isolate()->factory()->allocation_site_map(); | 2286 Handle<Map> allocation_site_map = |
2287 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); | 2287 masm->isolate()->factory()->allocation_site_map(); |
2288 __ j(not_equal, &miss); | 2288 __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map)); |
| 2289 __ j(not_equal, &miss); |
2289 | 2290 |
2290 // Make sure the function is the Array() function | 2291 // Make sure the function is the Array() function |
2291 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 2292 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
2292 __ cmp(edi, ecx); | 2293 __ cmp(edi, ecx); |
2293 __ j(not_equal, &megamorphic); | 2294 __ j(not_equal, &megamorphic); |
2294 __ jmp(&done, Label::kFar); | 2295 __ jmp(&done, Label::kFar); |
| 2296 } |
2295 | 2297 |
2296 __ bind(&miss); | 2298 __ bind(&miss); |
2297 | 2299 |
2298 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2300 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
2299 // megamorphic. | 2301 // megamorphic. |
2300 __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate))); | 2302 __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate))); |
2301 __ j(equal, &initialize); | 2303 __ j(equal, &initialize); |
2302 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2304 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
2303 // write-barrier is needed. | 2305 // write-barrier is needed. |
2304 __ bind(&megamorphic); | 2306 __ bind(&megamorphic); |
2305 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | 2307 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
2306 FixedArray::kHeaderSize), | 2308 FixedArray::kHeaderSize), |
2307 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); | 2309 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
2308 __ jmp(&done, Label::kFar); | 2310 __ jmp(&done, Label::kFar); |
2309 | 2311 |
2310 // An uninitialized cache is patched with the function or sentinel to | 2312 // An uninitialized cache is patched with the function or sentinel to |
2311 // indicate the ElementsKind if function is the Array constructor. | 2313 // indicate the ElementsKind if function is the Array constructor. |
2312 __ bind(&initialize); | 2314 __ bind(&initialize); |
2313 // Make sure the function is the Array() function | 2315 if (!FLAG_pretenuring_call_new) { |
2314 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); | 2316 // Make sure the function is the Array() function |
2315 __ cmp(edi, ecx); | 2317 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx); |
2316 __ j(not_equal, ¬_array_function); | 2318 __ cmp(edi, ecx); |
| 2319 __ j(not_equal, ¬_array_function); |
2317 | 2320 |
2318 // The target function is the Array constructor, | 2321 // The target function is the Array constructor, |
2319 // Create an AllocationSite if we don't already have it, store it in the slot. | 2322 // Create an AllocationSite if we don't already have it, store it in the |
2320 { | 2323 // slot. |
2321 FrameScope scope(masm, StackFrame::INTERNAL); | 2324 { |
| 2325 FrameScope scope(masm, StackFrame::INTERNAL); |
2322 | 2326 |
2323 // Arguments register must be smi-tagged to call out. | 2327 // Arguments register must be smi-tagged to call out. |
2324 __ SmiTag(eax); | 2328 __ SmiTag(eax); |
2325 __ push(eax); | 2329 __ push(eax); |
2326 __ push(edi); | 2330 __ push(edi); |
2327 __ push(edx); | 2331 __ push(edx); |
2328 __ push(ebx); | 2332 __ push(ebx); |
2329 | 2333 |
2330 CreateAllocationSiteStub create_stub; | 2334 CreateAllocationSiteStub create_stub; |
2331 __ CallStub(&create_stub); | 2335 __ CallStub(&create_stub); |
2332 | 2336 |
2333 __ pop(ebx); | 2337 __ pop(ebx); |
2334 __ pop(edx); | 2338 __ pop(edx); |
2335 __ pop(edi); | 2339 __ pop(edi); |
2336 __ pop(eax); | 2340 __ pop(eax); |
2337 __ SmiUntag(eax); | 2341 __ SmiUntag(eax); |
| 2342 } |
| 2343 __ jmp(&done); |
| 2344 |
| 2345 __ bind(¬_array_function); |
2338 } | 2346 } |
2339 __ jmp(&done); | |
2340 | 2347 |
2341 __ bind(¬_array_function); | |
2342 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | 2348 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
2343 FixedArray::kHeaderSize), | 2349 FixedArray::kHeaderSize), |
2344 edi); | 2350 edi); |
2345 // We won't need edx or ebx anymore, just save edi | 2351 // We won't need edx or ebx anymore, just save edi |
2346 __ push(edi); | 2352 __ push(edi); |
2347 __ push(ebx); | 2353 __ push(ebx); |
2348 __ push(edx); | 2354 __ push(edx); |
2349 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, | 2355 __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs, |
2350 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 2356 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
2351 __ pop(edx); | 2357 __ pop(edx); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 // edi : constructor function | 2480 // edi : constructor function |
2475 Label slow, non_function_call; | 2481 Label slow, non_function_call; |
2476 | 2482 |
2477 // Check that function is not a smi. | 2483 // Check that function is not a smi. |
2478 __ JumpIfSmi(edi, &non_function_call); | 2484 __ JumpIfSmi(edi, &non_function_call); |
2479 // Check that function is a JSFunction. | 2485 // Check that function is a JSFunction. |
2480 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2486 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2481 __ j(not_equal, &slow); | 2487 __ j(not_equal, &slow); |
2482 | 2488 |
2483 if (RecordCallTarget()) { | 2489 if (RecordCallTarget()) { |
2484 Label feedback_register_initialized; | |
2485 GenerateRecordCallTarget(masm); | 2490 GenerateRecordCallTarget(masm); |
2486 | 2491 |
2487 // Put the AllocationSite from the feedback vector into ebx, or undefined. | 2492 if (FLAG_pretenuring_call_new) { |
2488 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, | 2493 // Put the AllocationSite from the feedback vector into ebx. |
2489 FixedArray::kHeaderSize)); | 2494 // By adding kPointerSize we encode that we know the AllocationSite |
2490 Handle<Map> allocation_site_map = | 2495 // entry is at the feedback vector slot given by edx + 1. |
2491 masm->isolate()->factory()->allocation_site_map(); | 2496 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
2492 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); | 2497 FixedArray::kHeaderSize + kPointerSize)); |
2493 __ j(equal, &feedback_register_initialized); | 2498 } else { |
2494 __ mov(ebx, masm->isolate()->factory()->undefined_value()); | 2499 Label feedback_register_initialized; |
2495 __ bind(&feedback_register_initialized); | 2500 // Put the AllocationSite from the feedback vector into ebx, or undefined. |
| 2501 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 2502 FixedArray::kHeaderSize)); |
| 2503 Handle<Map> allocation_site_map = |
| 2504 masm->isolate()->factory()->allocation_site_map(); |
| 2505 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); |
| 2506 __ j(equal, &feedback_register_initialized); |
| 2507 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
| 2508 __ bind(&feedback_register_initialized); |
| 2509 } |
| 2510 |
2496 __ AssertUndefinedOrAllocationSite(ebx); | 2511 __ AssertUndefinedOrAllocationSite(ebx); |
2497 } | 2512 } |
2498 | 2513 |
2499 // Jump to the function-specific construct stub. | 2514 // Jump to the function-specific construct stub. |
2500 Register jmp_reg = ecx; | 2515 Register jmp_reg = ecx; |
2501 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2516 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
2502 __ mov(jmp_reg, FieldOperand(jmp_reg, | 2517 __ mov(jmp_reg, FieldOperand(jmp_reg, |
2503 SharedFunctionInfo::kConstructStubOffset)); | 2518 SharedFunctionInfo::kConstructStubOffset)); |
2504 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); | 2519 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); |
2505 __ jmp(jmp_reg); | 2520 __ jmp(jmp_reg); |
(...skipping 2875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5381 Operand(ebp, 7 * kPointerSize), | 5396 Operand(ebp, 7 * kPointerSize), |
5382 NULL); | 5397 NULL); |
5383 } | 5398 } |
5384 | 5399 |
5385 | 5400 |
5386 #undef __ | 5401 #undef __ |
5387 | 5402 |
5388 } } // namespace v8::internal | 5403 } } // namespace v8::internal |
5389 | 5404 |
5390 #endif // V8_TARGET_ARCH_IA32 | 5405 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |