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 2350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); | 2361 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); |
2362 | 2362 |
2363 __ bind(&miss_before_stack_reserved); | 2363 __ bind(&miss_before_stack_reserved); |
2364 GenerateMissBranch(); | 2364 GenerateMissBranch(); |
2365 | 2365 |
2366 // Return the generated code. | 2366 // Return the generated code. |
2367 return GetCode(function); | 2367 return GetCode(function); |
2368 } | 2368 } |
2369 | 2369 |
2370 | 2370 |
2371 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2371 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, |
2372 Handle<JSObject> holder, | 2372 Handle<JSObject> holder, |
2373 Handle<JSFunction> function, | 2373 Handle<String> name, |
2374 Handle<String> name, | 2374 CheckType check, |
2375 CheckType check) { | 2375 Label* success) { |
2376 // ----------- S t a t e ------------- | 2376 // ----------- S t a t e ------------- |
2377 // -- ecx : name | 2377 // -- ecx : name |
2378 // -- esp[0] : return address | 2378 // -- esp[0] : return address |
2379 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2379 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
2380 // -- ... | 2380 // -- ... |
2381 // -- esp[(argc + 1) * 4] : receiver | 2381 // -- esp[(argc + 1) * 4] : receiver |
2382 // ----------------------------------- | 2382 // ----------------------------------- |
2383 | |
2384 if (HasCustomCallGenerator(function)) { | |
2385 Handle<Code> code = CompileCustomCall(object, holder, | |
2386 Handle<JSGlobalPropertyCell>::null(), | |
2387 function, name); | |
2388 // A null handle means bail out to the regular compiler code below. | |
2389 if (!code.is_null()) return code; | |
2390 } | |
2391 | |
2392 Label miss; | 2383 Label miss; |
2393 GenerateNameCheck(name, &miss); | 2384 GenerateNameCheck(name, &miss); |
2394 | 2385 |
2395 // Get the receiver from the stack. | 2386 // Get the receiver from the stack. |
2396 const int argc = arguments().immediate(); | 2387 const int argc = arguments().immediate(); |
2397 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 2388 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
2398 | 2389 |
2399 // Check that the receiver isn't a smi. | 2390 // Check that the receiver isn't a smi. |
2400 if (check != NUMBER_CHECK) { | 2391 if (check != NUMBER_CHECK) { |
2401 __ JumpIfSmi(edx, &miss); | 2392 __ JumpIfSmi(edx, &miss); |
(...skipping 12 matching lines...) Expand all Loading... |
2414 | 2405 |
2415 // Patch the receiver on the stack with the global proxy if | 2406 // Patch the receiver on the stack with the global proxy if |
2416 // necessary. | 2407 // necessary. |
2417 if (object->IsGlobalObject()) { | 2408 if (object->IsGlobalObject()) { |
2418 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2409 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
2419 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2410 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
2420 } | 2411 } |
2421 break; | 2412 break; |
2422 | 2413 |
2423 case STRING_CHECK: | 2414 case STRING_CHECK: |
2424 if (function->IsBuiltin() || !function->shared()->is_classic_mode()) { | 2415 // Check that the object is a string or a symbol. |
2425 // Check that the object is a string or a symbol. | 2416 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); |
2426 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax); | 2417 __ j(above_equal, &miss); |
2427 __ j(above_equal, &miss); | 2418 // Check that the maps starting from the prototype haven't changed. |
2428 // Check that the maps starting from the prototype haven't changed. | 2419 GenerateDirectLoadGlobalFunctionPrototype( |
2429 GenerateDirectLoadGlobalFunctionPrototype( | 2420 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); |
2430 masm(), Context::STRING_FUNCTION_INDEX, eax, &miss); | 2421 CheckPrototypes( |
2431 CheckPrototypes( | 2422 Handle<JSObject>(JSObject::cast(object->GetPrototype())), |
2432 Handle<JSObject>(JSObject::cast(object->GetPrototype())), | 2423 eax, holder, ebx, edx, edi, name, &miss); |
2433 eax, holder, ebx, edx, edi, name, &miss); | |
2434 } else { | |
2435 // Calling non-strict non-builtins with a value as the receiver | |
2436 // requires boxing. | |
2437 __ jmp(&miss); | |
2438 } | |
2439 break; | 2424 break; |
2440 | 2425 |
2441 case NUMBER_CHECK: | 2426 case NUMBER_CHECK: { |
2442 if (function->IsBuiltin() || !function->shared()->is_classic_mode()) { | 2427 Label fast; |
2443 Label fast; | 2428 // Check that the object is a smi or a heap number. |
2444 // Check that the object is a smi or a heap number. | 2429 __ JumpIfSmi(edx, &fast); |
2445 __ JumpIfSmi(edx, &fast); | 2430 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); |
2446 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); | 2431 __ j(not_equal, &miss); |
2447 __ j(not_equal, &miss); | 2432 __ bind(&fast); |
2448 __ bind(&fast); | 2433 // Check that the maps starting from the prototype haven't changed. |
2449 // Check that the maps starting from the prototype haven't changed. | 2434 GenerateDirectLoadGlobalFunctionPrototype( |
2450 GenerateDirectLoadGlobalFunctionPrototype( | 2435 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); |
2451 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); | 2436 CheckPrototypes( |
2452 CheckPrototypes( | 2437 Handle<JSObject>(JSObject::cast(object->GetPrototype())), |
2453 Handle<JSObject>(JSObject::cast(object->GetPrototype())), | 2438 eax, holder, ebx, edx, edi, name, &miss); |
2454 eax, holder, ebx, edx, edi, name, &miss); | |
2455 } else { | |
2456 // Calling non-strict non-builtins with a value as the receiver | |
2457 // requires boxing. | |
2458 __ jmp(&miss); | |
2459 } | |
2460 break; | 2439 break; |
2461 | 2440 } |
2462 case BOOLEAN_CHECK: | 2441 case BOOLEAN_CHECK: { |
2463 if (function->IsBuiltin() || !function->shared()->is_classic_mode()) { | 2442 Label fast; |
2464 Label fast; | 2443 // Check that the object is a boolean. |
2465 // Check that the object is a boolean. | 2444 __ cmp(edx, factory()->true_value()); |
2466 __ cmp(edx, factory()->true_value()); | 2445 __ j(equal, &fast); |
2467 __ j(equal, &fast); | 2446 __ cmp(edx, factory()->false_value()); |
2468 __ cmp(edx, factory()->false_value()); | 2447 __ j(not_equal, &miss); |
2469 __ j(not_equal, &miss); | 2448 __ bind(&fast); |
2470 __ bind(&fast); | 2449 // Check that the maps starting from the prototype haven't changed. |
2471 // Check that the maps starting from the prototype haven't changed. | 2450 GenerateDirectLoadGlobalFunctionPrototype( |
2472 GenerateDirectLoadGlobalFunctionPrototype( | 2451 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); |
2473 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); | 2452 CheckPrototypes( |
2474 CheckPrototypes( | 2453 Handle<JSObject>(JSObject::cast(object->GetPrototype())), |
2475 Handle<JSObject>(JSObject::cast(object->GetPrototype())), | 2454 eax, holder, ebx, edx, edi, name, &miss); |
2476 eax, holder, ebx, edx, edi, name, &miss); | |
2477 } else { | |
2478 // Calling non-strict non-builtins with a value as the receiver | |
2479 // requires boxing. | |
2480 __ jmp(&miss); | |
2481 } | |
2482 break; | 2455 break; |
| 2456 } |
2483 } | 2457 } |
2484 | 2458 |
| 2459 __ jmp(success); |
| 2460 |
| 2461 // Handle call cache miss. |
| 2462 __ bind(&miss); |
| 2463 GenerateMissBranch(); |
| 2464 } |
| 2465 |
| 2466 |
| 2467 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { |
2485 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2468 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2486 ? CALL_AS_FUNCTION | 2469 ? CALL_AS_FUNCTION |
2487 : CALL_AS_METHOD; | 2470 : CALL_AS_METHOD; |
2488 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2471 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
2489 NullCallWrapper(), call_kind); | 2472 NullCallWrapper(), call_kind); |
| 2473 } |
2490 | 2474 |
2491 // Handle call cache miss. | 2475 |
2492 __ bind(&miss); | 2476 Handle<Code> CallStubCompiler::CompileCallConstant( |
2493 GenerateMissBranch(); | 2477 Handle<Object> object, |
| 2478 Handle<JSObject> holder, |
| 2479 Handle<String> name, |
| 2480 CheckType check, |
| 2481 Handle<JSFunction> function) { |
| 2482 |
| 2483 if (HasCustomCallGenerator(function)) { |
| 2484 Handle<Code> code = CompileCustomCall(object, holder, |
| 2485 Handle<JSGlobalPropertyCell>::null(), |
| 2486 function, name); |
| 2487 // A null handle means bail out to the regular compiler code below. |
| 2488 if (!code.is_null()) return code; |
| 2489 } |
| 2490 |
| 2491 Label success; |
| 2492 |
| 2493 CompileHandlerFrontend(object, holder, name, check, &success); |
| 2494 __ bind(&success); |
| 2495 CompileHandlerBackend(function); |
2494 | 2496 |
2495 // Return the generated code. | 2497 // Return the generated code. |
2496 return GetCode(function); | 2498 return GetCode(function); |
2497 } | 2499 } |
2498 | 2500 |
2499 | 2501 |
2500 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2502 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2501 Handle<JSObject> holder, | 2503 Handle<JSObject> holder, |
2502 Handle<String> name) { | 2504 Handle<String> name) { |
2503 // ----------- S t a t e ------------- | 2505 // ----------- S t a t e ------------- |
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3917 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3919 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3918 } | 3920 } |
3919 } | 3921 } |
3920 | 3922 |
3921 | 3923 |
3922 #undef __ | 3924 #undef __ |
3923 | 3925 |
3924 } } // namespace v8::internal | 3926 } } // namespace v8::internal |
3925 | 3927 |
3926 #endif // V8_TARGET_ARCH_IA32 | 3928 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |