| 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 |