OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 Object* obj; | 2271 Object* obj; |
2272 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2272 { MaybeObject* maybe_obj = GenerateMissBranch(); |
2273 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2273 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2274 } | 2274 } |
2275 | 2275 |
2276 // Return the generated code. | 2276 // Return the generated code. |
2277 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2277 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
2278 } | 2278 } |
2279 | 2279 |
2280 | 2280 |
| 2281 MaybeObject* CallStubCompiler::CompileFastApiCall( |
| 2282 const CallOptimization& optimization, |
| 2283 Object* object, |
| 2284 JSObject* holder, |
| 2285 JSGlobalPropertyCell* cell, |
| 2286 JSFunction* function, |
| 2287 String* name) { |
| 2288 ASSERT(optimization.is_simple_api_call()); |
| 2289 // Bail out if object is a global object as we don't want to |
| 2290 // repatch it to global receiver. |
| 2291 if (object->IsGlobalObject()) return Heap::undefined_value(); |
| 2292 if (cell != NULL) return Heap::undefined_value(); |
| 2293 int depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2294 JSObject::cast(object), holder); |
| 2295 if (depth == kInvalidProtoDepth) return Heap::undefined_value(); |
| 2296 |
| 2297 Label miss, miss_before_stack_reserved; |
| 2298 |
| 2299 GenerateNameCheck(name, &miss_before_stack_reserved); |
| 2300 |
| 2301 // Get the receiver from the stack. |
| 2302 const int argc = arguments().immediate(); |
| 2303 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2304 |
| 2305 // Check that the receiver isn't a smi. |
| 2306 __ tst(r1, Operand(kSmiTagMask)); |
| 2307 __ b(eq, &miss_before_stack_reserved); |
| 2308 |
| 2309 __ IncrementCounter(&Counters::call_const, 1, r0, r3); |
| 2310 __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); |
| 2311 |
| 2312 ReserveSpaceForFastApiCall(masm(), r0); |
| 2313 |
| 2314 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2315 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2316 depth, &miss); |
| 2317 |
| 2318 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
| 2319 if (result->IsFailure()) return result; |
| 2320 |
| 2321 __ bind(&miss); |
| 2322 FreeSpaceForFastApiCall(masm()); |
| 2323 |
| 2324 __ bind(&miss_before_stack_reserved); |
| 2325 Object* obj; |
| 2326 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2327 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2328 } |
| 2329 |
| 2330 // Return the generated code. |
| 2331 return GetCode(function); |
| 2332 } |
| 2333 |
| 2334 |
2281 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2335 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
2282 JSObject* holder, | 2336 JSObject* holder, |
2283 JSFunction* function, | 2337 JSFunction* function, |
2284 String* name, | 2338 String* name, |
2285 CheckType check) { | 2339 CheckType check) { |
2286 // ----------- S t a t e ------------- | 2340 // ----------- S t a t e ------------- |
2287 // -- r2 : name | 2341 // -- r2 : name |
2288 // -- lr : return address | 2342 // -- lr : return address |
2289 // ----------------------------------- | 2343 // ----------------------------------- |
2290 SharedFunctionInfo* function_info = function->shared(); | 2344 if (HasCustomCallGenerator(function)) { |
2291 if (function_info->HasBuiltinFunctionId()) { | |
2292 BuiltinFunctionId id = function_info->builtin_function_id(); | |
2293 MaybeObject* maybe_result = CompileCustomCall( | 2345 MaybeObject* maybe_result = CompileCustomCall( |
2294 id, object, holder, NULL, function, name); | 2346 object, holder, NULL, function, name); |
2295 Object* result; | 2347 Object* result; |
2296 if (!maybe_result->ToObject(&result)) return maybe_result; | 2348 if (!maybe_result->ToObject(&result)) return maybe_result; |
2297 // undefined means bail out to regular compiler. | 2349 // undefined means bail out to regular compiler. |
2298 if (!result->IsUndefined()) { | 2350 if (!result->IsUndefined()) return result; |
2299 return result; | |
2300 } | |
2301 } | 2351 } |
2302 | 2352 |
2303 Label miss_in_smi_check; | 2353 Label miss; |
2304 | 2354 |
2305 GenerateNameCheck(name, &miss_in_smi_check); | 2355 GenerateNameCheck(name, &miss); |
2306 | 2356 |
2307 // Get the receiver from the stack | 2357 // Get the receiver from the stack |
2308 const int argc = arguments().immediate(); | 2358 const int argc = arguments().immediate(); |
2309 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2359 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
2310 | 2360 |
2311 // Check that the receiver isn't a smi. | 2361 // Check that the receiver isn't a smi. |
2312 if (check != NUMBER_CHECK) { | 2362 if (check != NUMBER_CHECK) { |
2313 __ tst(r1, Operand(kSmiTagMask)); | 2363 __ tst(r1, Operand(kSmiTagMask)); |
2314 __ b(eq, &miss_in_smi_check); | 2364 __ b(eq, &miss); |
2315 } | 2365 } |
2316 | 2366 |
2317 // Make sure that it's okay not to patch the on stack receiver | 2367 // Make sure that it's okay not to patch the on stack receiver |
2318 // unless we're doing a receiver map check. | 2368 // unless we're doing a receiver map check. |
2319 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2369 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
2320 | 2370 |
2321 CallOptimization optimization(function); | 2371 SharedFunctionInfo* function_info = function->shared(); |
2322 int depth = kInvalidProtoDepth; | |
2323 Label miss; | |
2324 | |
2325 switch (check) { | 2372 switch (check) { |
2326 case RECEIVER_MAP_CHECK: | 2373 case RECEIVER_MAP_CHECK: |
2327 __ IncrementCounter(&Counters::call_const, 1, r0, r3); | 2374 __ IncrementCounter(&Counters::call_const, 1, r0, r3); |
2328 | 2375 |
2329 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { | |
2330 depth = optimization.GetPrototypeDepthOfExpectedType( | |
2331 JSObject::cast(object), holder); | |
2332 } | |
2333 | |
2334 if (depth != kInvalidProtoDepth) { | |
2335 __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); | |
2336 ReserveSpaceForFastApiCall(masm(), r0); | |
2337 } | |
2338 | |
2339 // Check that the maps haven't changed. | 2376 // Check that the maps haven't changed. |
2340 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2377 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
2341 depth, &miss); | 2378 &miss); |
2342 | 2379 |
2343 // Patch the receiver on the stack with the global proxy if | 2380 // Patch the receiver on the stack with the global proxy if |
2344 // necessary. | 2381 // necessary. |
2345 if (object->IsGlobalObject()) { | 2382 if (object->IsGlobalObject()) { |
2346 ASSERT(depth == kInvalidProtoDepth); | |
2347 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2383 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
2348 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2384 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
2349 } | 2385 } |
2350 break; | 2386 break; |
2351 | 2387 |
2352 case STRING_CHECK: | 2388 case STRING_CHECK: |
2353 if (!function->IsBuiltin() && !function_info->strict_mode()) { | 2389 if (!function->IsBuiltin() && !function_info->strict_mode()) { |
2354 // Calling non-strict non-builtins with a value as the receiver | 2390 // Calling non-strict non-builtins with a value as the receiver |
2355 // requires boxing. | 2391 // requires boxing. |
2356 __ jmp(&miss); | 2392 __ jmp(&miss); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2409 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 2445 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, |
2410 r1, r4, name, &miss); | 2446 r1, r4, name, &miss); |
2411 } | 2447 } |
2412 break; | 2448 break; |
2413 } | 2449 } |
2414 | 2450 |
2415 default: | 2451 default: |
2416 UNREACHABLE(); | 2452 UNREACHABLE(); |
2417 } | 2453 } |
2418 | 2454 |
2419 if (depth != kInvalidProtoDepth) { | 2455 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
2420 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | |
2421 if (result->IsFailure()) return result; | |
2422 } else { | |
2423 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | |
2424 } | |
2425 | 2456 |
2426 // Handle call cache miss. | 2457 // Handle call cache miss. |
2427 __ bind(&miss); | 2458 __ bind(&miss); |
2428 if (depth != kInvalidProtoDepth) { | |
2429 FreeSpaceForFastApiCall(masm()); | |
2430 } | |
2431 | |
2432 __ bind(&miss_in_smi_check); | |
2433 Object* obj; | 2459 Object* obj; |
2434 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2460 { MaybeObject* maybe_obj = GenerateMissBranch(); |
2435 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2461 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2436 } | 2462 } |
2437 | 2463 |
2438 // Return the generated code. | 2464 // Return the generated code. |
2439 return GetCode(function); | 2465 return GetCode(function); |
2440 } | 2466 } |
2441 | 2467 |
2442 | 2468 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2524 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
2499 GlobalObject* holder, | 2525 GlobalObject* holder, |
2500 JSGlobalPropertyCell* cell, | 2526 JSGlobalPropertyCell* cell, |
2501 JSFunction* function, | 2527 JSFunction* function, |
2502 String* name) { | 2528 String* name) { |
2503 // ----------- S t a t e ------------- | 2529 // ----------- S t a t e ------------- |
2504 // -- r2 : name | 2530 // -- r2 : name |
2505 // -- lr : return address | 2531 // -- lr : return address |
2506 // ----------------------------------- | 2532 // ----------------------------------- |
2507 | 2533 |
2508 SharedFunctionInfo* function_info = function->shared(); | 2534 if (HasCustomCallGenerator(function)) { |
2509 if (function_info->HasBuiltinFunctionId()) { | |
2510 BuiltinFunctionId id = function_info->builtin_function_id(); | |
2511 MaybeObject* maybe_result = CompileCustomCall( | 2535 MaybeObject* maybe_result = CompileCustomCall( |
2512 id, object, holder, cell, function, name); | 2536 object, holder, cell, function, name); |
2513 Object* result; | 2537 Object* result; |
2514 if (!maybe_result->ToObject(&result)) return maybe_result; | 2538 if (!maybe_result->ToObject(&result)) return maybe_result; |
2515 // undefined means bail out to regular compiler. | 2539 // undefined means bail out to regular compiler. |
2516 if (!result->IsUndefined()) return result; | 2540 if (!result->IsUndefined()) return result; |
2517 } | 2541 } |
2518 | 2542 |
2519 Label miss; | 2543 Label miss; |
2520 | 2544 |
2521 GenerateNameCheck(name, &miss); | 2545 GenerateNameCheck(name, &miss); |
2522 | 2546 |
(...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3990 | 4014 |
3991 return GetCode(flags); | 4015 return GetCode(flags); |
3992 } | 4016 } |
3993 | 4017 |
3994 | 4018 |
3995 #undef __ | 4019 #undef __ |
3996 | 4020 |
3997 } } // namespace v8::internal | 4021 } } // namespace v8::internal |
3998 | 4022 |
3999 #endif // V8_TARGET_ARCH_ARM | 4023 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |