| 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 2271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 Object* obj; | 2282 Object* obj; |
| 2283 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2283 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2284 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2284 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2285 } | 2285 } |
| 2286 | 2286 |
| 2287 // Return the generated code. | 2287 // Return the generated code. |
| 2288 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | 2288 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); |
| 2289 } | 2289 } |
| 2290 | 2290 |
| 2291 | 2291 |
| 2292 MaybeObject* CallStubCompiler::CompileFastApiCall( |
| 2293 const CallOptimization& optimization, |
| 2294 Object* object, |
| 2295 JSObject* holder, |
| 2296 JSGlobalPropertyCell* cell, |
| 2297 JSFunction* function, |
| 2298 String* name) { |
| 2299 ASSERT(optimization.is_simple_api_call()); |
| 2300 // Bail out if object is a global object as we don't want to |
| 2301 // repatch it to global receiver. |
| 2302 if (object->IsGlobalObject()) return Heap::undefined_value(); |
| 2303 if (cell != NULL) return Heap::undefined_value(); |
| 2304 int depth = optimization.GetPrototypeDepthOfExpectedType( |
| 2305 JSObject::cast(object), holder); |
| 2306 if (depth == kInvalidProtoDepth) return Heap::undefined_value(); |
| 2307 |
| 2308 Label miss, miss_before_stack_reserved; |
| 2309 |
| 2310 GenerateNameCheck(name, &miss_before_stack_reserved); |
| 2311 |
| 2312 // Get the receiver from the stack. |
| 2313 const int argc = arguments().immediate(); |
| 2314 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2315 |
| 2316 // Check that the receiver isn't a smi. |
| 2317 __ tst(r1, Operand(kSmiTagMask)); |
| 2318 __ b(eq, &miss_before_stack_reserved); |
| 2319 |
| 2320 __ IncrementCounter(&Counters::call_const, 1, r0, r3); |
| 2321 __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); |
| 2322 |
| 2323 ReserveSpaceForFastApiCall(masm(), r0); |
| 2324 |
| 2325 // Check that the maps haven't changed and find a Holder as a side effect. |
| 2326 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2327 depth, &miss); |
| 2328 |
| 2329 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); |
| 2330 if (result->IsFailure()) return result; |
| 2331 |
| 2332 __ bind(&miss); |
| 2333 FreeSpaceForFastApiCall(masm()); |
| 2334 |
| 2335 __ bind(&miss_before_stack_reserved); |
| 2336 Object* obj; |
| 2337 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2338 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2339 } |
| 2340 |
| 2341 // Return the generated code. |
| 2342 return GetCode(function); |
| 2343 } |
| 2344 |
| 2345 |
| 2292 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, | 2346 MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, |
| 2293 JSObject* holder, | 2347 JSObject* holder, |
| 2294 JSFunction* function, | 2348 JSFunction* function, |
| 2295 String* name, | 2349 String* name, |
| 2296 CheckType check) { | 2350 CheckType check) { |
| 2297 // ----------- S t a t e ------------- | 2351 // ----------- S t a t e ------------- |
| 2298 // -- r2 : name | 2352 // -- r2 : name |
| 2299 // -- lr : return address | 2353 // -- lr : return address |
| 2300 // ----------------------------------- | 2354 // ----------------------------------- |
| 2301 SharedFunctionInfo* function_info = function->shared(); | 2355 if (HasCustomCallGenerator(function)) { |
| 2302 if (function_info->HasBuiltinFunctionId()) { | |
| 2303 BuiltinFunctionId id = function_info->builtin_function_id(); | |
| 2304 MaybeObject* maybe_result = CompileCustomCall( | 2356 MaybeObject* maybe_result = CompileCustomCall( |
| 2305 id, object, holder, NULL, function, name); | 2357 object, holder, NULL, function, name); |
| 2306 Object* result; | 2358 Object* result; |
| 2307 if (!maybe_result->ToObject(&result)) return maybe_result; | 2359 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2308 // undefined means bail out to regular compiler. | 2360 // undefined means bail out to regular compiler. |
| 2309 if (!result->IsUndefined()) { | 2361 if (!result->IsUndefined()) return result; |
| 2310 return result; | |
| 2311 } | |
| 2312 } | 2362 } |
| 2313 | 2363 |
| 2314 Label miss_in_smi_check; | 2364 Label miss; |
| 2315 | 2365 |
| 2316 GenerateNameCheck(name, &miss_in_smi_check); | 2366 GenerateNameCheck(name, &miss); |
| 2317 | 2367 |
| 2318 // Get the receiver from the stack | 2368 // Get the receiver from the stack |
| 2319 const int argc = arguments().immediate(); | 2369 const int argc = arguments().immediate(); |
| 2320 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2370 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 2321 | 2371 |
| 2322 // Check that the receiver isn't a smi. | 2372 // Check that the receiver isn't a smi. |
| 2323 if (check != NUMBER_CHECK) { | 2373 if (check != NUMBER_CHECK) { |
| 2324 __ tst(r1, Operand(kSmiTagMask)); | 2374 __ tst(r1, Operand(kSmiTagMask)); |
| 2325 __ b(eq, &miss_in_smi_check); | 2375 __ b(eq, &miss); |
| 2326 } | 2376 } |
| 2327 | 2377 |
| 2328 // Make sure that it's okay not to patch the on stack receiver | 2378 // Make sure that it's okay not to patch the on stack receiver |
| 2329 // unless we're doing a receiver map check. | 2379 // unless we're doing a receiver map check. |
| 2330 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2380 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2331 | 2381 |
| 2332 CallOptimization optimization(function); | 2382 SharedFunctionInfo* function_info = function->shared(); |
| 2333 int depth = kInvalidProtoDepth; | |
| 2334 Label miss; | |
| 2335 | |
| 2336 switch (check) { | 2383 switch (check) { |
| 2337 case RECEIVER_MAP_CHECK: | 2384 case RECEIVER_MAP_CHECK: |
| 2338 __ IncrementCounter(&Counters::call_const, 1, r0, r3); | 2385 __ IncrementCounter(&Counters::call_const, 1, r0, r3); |
| 2339 | 2386 |
| 2340 if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { | |
| 2341 depth = optimization.GetPrototypeDepthOfExpectedType( | |
| 2342 JSObject::cast(object), holder); | |
| 2343 } | |
| 2344 | |
| 2345 if (depth != kInvalidProtoDepth) { | |
| 2346 __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); | |
| 2347 ReserveSpaceForFastApiCall(masm(), r0); | |
| 2348 } | |
| 2349 | |
| 2350 // Check that the maps haven't changed. | 2387 // Check that the maps haven't changed. |
| 2351 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, | 2388 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, |
| 2352 depth, &miss); | 2389 &miss); |
| 2353 | 2390 |
| 2354 // Patch the receiver on the stack with the global proxy if | 2391 // Patch the receiver on the stack with the global proxy if |
| 2355 // necessary. | 2392 // necessary. |
| 2356 if (object->IsGlobalObject()) { | 2393 if (object->IsGlobalObject()) { |
| 2357 ASSERT(depth == kInvalidProtoDepth); | |
| 2358 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2394 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2359 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2395 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 2360 } | 2396 } |
| 2361 break; | 2397 break; |
| 2362 | 2398 |
| 2363 case STRING_CHECK: | 2399 case STRING_CHECK: |
| 2364 if (!function->IsBuiltin() && !function_info->strict_mode()) { | 2400 if (!function->IsBuiltin() && !function_info->strict_mode()) { |
| 2365 // Calling non-strict non-builtins with a value as the receiver | 2401 // Calling non-strict non-builtins with a value as the receiver |
| 2366 // requires boxing. | 2402 // requires boxing. |
| 2367 __ jmp(&miss); | 2403 __ jmp(&miss); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, | 2456 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, |
| 2421 r1, r4, name, &miss); | 2457 r1, r4, name, &miss); |
| 2422 } | 2458 } |
| 2423 break; | 2459 break; |
| 2424 } | 2460 } |
| 2425 | 2461 |
| 2426 default: | 2462 default: |
| 2427 UNREACHABLE(); | 2463 UNREACHABLE(); |
| 2428 } | 2464 } |
| 2429 | 2465 |
| 2430 if (depth != kInvalidProtoDepth) { | 2466 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); |
| 2431 MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); | |
| 2432 if (result->IsFailure()) return result; | |
| 2433 } else { | |
| 2434 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | |
| 2435 } | |
| 2436 | 2467 |
| 2437 // Handle call cache miss. | 2468 // Handle call cache miss. |
| 2438 __ bind(&miss); | 2469 __ bind(&miss); |
| 2439 if (depth != kInvalidProtoDepth) { | |
| 2440 FreeSpaceForFastApiCall(masm()); | |
| 2441 } | |
| 2442 | |
| 2443 __ bind(&miss_in_smi_check); | |
| 2444 Object* obj; | 2470 Object* obj; |
| 2445 { MaybeObject* maybe_obj = GenerateMissBranch(); | 2471 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 2446 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2472 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2447 } | 2473 } |
| 2448 | 2474 |
| 2449 // Return the generated code. | 2475 // Return the generated code. |
| 2450 return GetCode(function); | 2476 return GetCode(function); |
| 2451 } | 2477 } |
| 2452 | 2478 |
| 2453 | 2479 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2509 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, | 2535 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, |
| 2510 GlobalObject* holder, | 2536 GlobalObject* holder, |
| 2511 JSGlobalPropertyCell* cell, | 2537 JSGlobalPropertyCell* cell, |
| 2512 JSFunction* function, | 2538 JSFunction* function, |
| 2513 String* name) { | 2539 String* name) { |
| 2514 // ----------- S t a t e ------------- | 2540 // ----------- S t a t e ------------- |
| 2515 // -- r2 : name | 2541 // -- r2 : name |
| 2516 // -- lr : return address | 2542 // -- lr : return address |
| 2517 // ----------------------------------- | 2543 // ----------------------------------- |
| 2518 | 2544 |
| 2519 SharedFunctionInfo* function_info = function->shared(); | 2545 if (HasCustomCallGenerator(function)) { |
| 2520 if (function_info->HasBuiltinFunctionId()) { | |
| 2521 BuiltinFunctionId id = function_info->builtin_function_id(); | |
| 2522 MaybeObject* maybe_result = CompileCustomCall( | 2546 MaybeObject* maybe_result = CompileCustomCall( |
| 2523 id, object, holder, cell, function, name); | 2547 object, holder, cell, function, name); |
| 2524 Object* result; | 2548 Object* result; |
| 2525 if (!maybe_result->ToObject(&result)) return maybe_result; | 2549 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2526 // undefined means bail out to regular compiler. | 2550 // undefined means bail out to regular compiler. |
| 2527 if (!result->IsUndefined()) return result; | 2551 if (!result->IsUndefined()) return result; |
| 2528 } | 2552 } |
| 2529 | 2553 |
| 2530 Label miss; | 2554 Label miss; |
| 2531 | 2555 |
| 2532 GenerateNameCheck(name, &miss); | 2556 GenerateNameCheck(name, &miss); |
| 2533 | 2557 |
| (...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4003 | 4027 |
| 4004 return GetCode(flags); | 4028 return GetCode(flags); |
| 4005 } | 4029 } |
| 4006 | 4030 |
| 4007 | 4031 |
| 4008 #undef __ | 4032 #undef __ |
| 4009 | 4033 |
| 4010 } } // namespace v8::internal | 4034 } } // namespace v8::internal |
| 4011 | 4035 |
| 4012 #endif // V8_TARGET_ARCH_ARM | 4036 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |