OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 void FullCodeGenerator::CallIC(Handle<Code> code, | 2324 void FullCodeGenerator::CallIC(Handle<Code> code, |
2325 TypeFeedbackId ast_id) { | 2325 TypeFeedbackId ast_id) { |
2326 ic_total_count_++; | 2326 ic_total_count_++; |
2327 // All calls must have a predictable size in full-codegen code to ensure that | 2327 // All calls must have a predictable size in full-codegen code to ensure that |
2328 // the debugger can patch them correctly. | 2328 // the debugger can patch them correctly. |
2329 __ Call(code, RelocInfo::CODE_TARGET, ast_id); | 2329 __ Call(code, RelocInfo::CODE_TARGET, ast_id); |
2330 } | 2330 } |
2331 | 2331 |
2332 | 2332 |
2333 // Code common for calls using the IC. | 2333 // Code common for calls using the IC. |
2334 void FullCodeGenerator::EmitCallWithIC(Call* expr) { | 2334 void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { |
2335 ASM_LOCATION("EmitCallWithIC"); | 2335 Expression* callee = expr->expression(); |
2336 | 2336 |
2337 Expression* callee = expr->expression(); | 2337 CallIC::CallType call_type = callee->IsVariableProxy() |
2338 ZoneList<Expression*>* args = expr->arguments(); | 2338 ? CallIC::FUNCTION |
2339 int arg_count = args->length(); | 2339 : CallIC::METHOD; |
2340 | 2340 |
2341 CallFunctionFlags flags; | |
2342 // Get the target function. | 2341 // Get the target function. |
2343 if (callee->IsVariableProxy()) { | 2342 if (call_type == CallIC::FUNCTION) { |
2344 { StackValueContext context(this); | 2343 { StackValueContext context(this); |
2345 EmitVariableLoad(callee->AsVariableProxy()); | 2344 EmitVariableLoad(callee->AsVariableProxy()); |
2346 PrepareForBailout(callee, NO_REGISTERS); | 2345 PrepareForBailout(callee, NO_REGISTERS); |
2347 } | 2346 } |
2348 // Push undefined as receiver. This is patched in the method prologue if it | 2347 // Push undefined as receiver. This is patched in the method prologue if it |
2349 // is a sloppy mode method. | 2348 // is a sloppy mode method. |
2350 __ Push(isolate()->factory()->undefined_value()); | 2349 __ Push(isolate()->factory()->undefined_value()); |
2351 flags = NO_CALL_FUNCTION_FLAGS; | |
2352 } else { | 2350 } else { |
2353 // Load the function from the receiver. | 2351 // Load the function from the receiver. |
2354 ASSERT(callee->IsProperty()); | 2352 ASSERT(callee->IsProperty()); |
2355 __ Peek(x0, 0); | 2353 __ Peek(x0, 0); |
2356 EmitNamedPropertyLoad(callee->AsProperty()); | 2354 EmitNamedPropertyLoad(callee->AsProperty()); |
2357 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2355 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2358 // Push the target function under the receiver. | 2356 // Push the target function under the receiver. |
2359 __ Pop(x10); | 2357 __ Pop(x10); |
2360 __ Push(x0, x10); | 2358 __ Push(x0, x10); |
2361 flags = CALL_AS_METHOD; | |
2362 } | 2359 } |
2363 | 2360 |
2364 // Load the arguments. | 2361 EmitCall(expr, call_type); |
2365 { PreservePositionScope scope(masm()->positions_recorder()); | |
2366 for (int i = 0; i < arg_count; i++) { | |
2367 VisitForStackValue(args->at(i)); | |
2368 } | |
2369 } | |
2370 | |
2371 // Record source position for debugger. | |
2372 SetSourcePosition(expr->position()); | |
2373 CallFunctionStub stub(arg_count, flags); | |
2374 __ Peek(x1, (arg_count + 1) * kPointerSize); | |
2375 __ CallStub(&stub); | |
2376 | |
2377 RecordJSReturnSite(expr); | |
2378 | |
2379 // Restore context register. | |
2380 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2381 | |
2382 context()->DropAndPlug(1, x0); | |
2383 } | 2362 } |
2384 | 2363 |
2385 | 2364 |
2386 // Code common for calls using the IC. | 2365 // Code common for calls using the IC. |
2387 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2366 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2388 Expression* key) { | 2367 Expression* key) { |
2389 // Load the key. | 2368 // Load the key. |
2390 VisitForAccumulatorValue(key); | 2369 VisitForAccumulatorValue(key); |
2391 | 2370 |
2392 Expression* callee = expr->expression(); | 2371 Expression* callee = expr->expression(); |
2393 ZoneList<Expression*>* args = expr->arguments(); | |
2394 int arg_count = args->length(); | |
2395 | 2372 |
2396 // Load the function from the receiver. | 2373 // Load the function from the receiver. |
2397 ASSERT(callee->IsProperty()); | 2374 ASSERT(callee->IsProperty()); |
2398 __ Peek(x1, 0); | 2375 __ Peek(x1, 0); |
2399 EmitKeyedPropertyLoad(callee->AsProperty()); | 2376 EmitKeyedPropertyLoad(callee->AsProperty()); |
2400 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2377 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2401 | 2378 |
2402 // Push the target function under the receiver. | 2379 // Push the target function under the receiver. |
2403 __ Pop(x10); | 2380 __ Pop(x10); |
2404 __ Push(x0, x10); | 2381 __ Push(x0, x10); |
2405 | 2382 |
2406 { PreservePositionScope scope(masm()->positions_recorder()); | 2383 EmitCall(expr, CallIC::METHOD); |
2407 for (int i = 0; i < arg_count; i++) { | |
2408 VisitForStackValue(args->at(i)); | |
2409 } | |
2410 } | |
2411 | |
2412 // Record source position for debugger. | |
2413 SetSourcePosition(expr->position()); | |
2414 CallFunctionStub stub(arg_count, CALL_AS_METHOD); | |
2415 __ Peek(x1, (arg_count + 1) * kPointerSize); | |
2416 __ CallStub(&stub); | |
2417 | |
2418 RecordJSReturnSite(expr); | |
2419 // Restore context register. | |
2420 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | |
2421 | |
2422 context()->DropAndPlug(1, x0); | |
2423 } | 2384 } |
2424 | 2385 |
2425 | 2386 |
2426 void FullCodeGenerator::EmitCallWithStub(Call* expr) { | 2387 void FullCodeGenerator::EmitCall(Call* expr, CallIC::CallType call_type) { |
2427 // Code common for calls using the call stub. | 2388 // Load the arguments. |
2428 ZoneList<Expression*>* args = expr->arguments(); | 2389 ZoneList<Expression*>* args = expr->arguments(); |
2429 int arg_count = args->length(); | 2390 int arg_count = args->length(); |
2430 { PreservePositionScope scope(masm()->positions_recorder()); | 2391 { PreservePositionScope scope(masm()->positions_recorder()); |
2431 for (int i = 0; i < arg_count; i++) { | 2392 for (int i = 0; i < arg_count; i++) { |
2432 VisitForStackValue(args->at(i)); | 2393 VisitForStackValue(args->at(i)); |
2433 } | 2394 } |
2434 } | 2395 } |
2435 // Record source position for debugger. | 2396 // Record source position of the IC call. |
2436 SetSourcePosition(expr->position()); | 2397 SetSourcePosition(expr->position()); |
2437 | 2398 |
2438 __ LoadObject(x2, FeedbackVector()); | 2399 Handle<Code> ic = CallIC::initialize_stub( |
| 2400 isolate(), arg_count, call_type); |
2439 __ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot())); | 2401 __ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot())); |
| 2402 __ Peek(x1, (arg_count + 1) * kXRegSize); |
| 2403 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 2404 // by the vector above. |
| 2405 CallIC(ic); |
2440 | 2406 |
2441 // Record call targets in unoptimized code. | |
2442 CallFunctionStub stub(arg_count, RECORD_CALL_TARGET); | |
2443 __ Peek(x1, (arg_count + 1) * kXRegSize); | |
2444 __ CallStub(&stub); | |
2445 RecordJSReturnSite(expr); | 2407 RecordJSReturnSite(expr); |
2446 // Restore context register. | 2408 // Restore context register. |
2447 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2409 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2448 context()->DropAndPlug(1, x0); | 2410 context()->DropAndPlug(1, x0); |
2449 } | 2411 } |
2450 | 2412 |
2451 | 2413 |
2452 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { | 2414 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { |
2453 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); | 2415 ASM_LOCATION("FullCodeGenerator::EmitResolvePossiblyDirectEval"); |
2454 // Prepare to push a copy of the first argument or undefined if it doesn't | 2416 // Prepare to push a copy of the first argument or undefined if it doesn't |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2526 // Call the evaluated function. | 2488 // Call the evaluated function. |
2527 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); | 2489 CallFunctionStub stub(arg_count, NO_CALL_FUNCTION_FLAGS); |
2528 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2490 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2529 __ CallStub(&stub); | 2491 __ CallStub(&stub); |
2530 RecordJSReturnSite(expr); | 2492 RecordJSReturnSite(expr); |
2531 // Restore context register. | 2493 // Restore context register. |
2532 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2494 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2533 context()->DropAndPlug(1, x0); | 2495 context()->DropAndPlug(1, x0); |
2534 | 2496 |
2535 } else if (call_type == Call::GLOBAL_CALL) { | 2497 } else if (call_type == Call::GLOBAL_CALL) { |
2536 EmitCallWithIC(expr); | 2498 EmitCallWithLoadIC(expr); |
2537 | 2499 |
2538 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2500 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
2539 // Call to a lookup slot (dynamically introduced variable). | 2501 // Call to a lookup slot (dynamically introduced variable). |
2540 VariableProxy* proxy = callee->AsVariableProxy(); | 2502 VariableProxy* proxy = callee->AsVariableProxy(); |
2541 Label slow, done; | 2503 Label slow, done; |
2542 | 2504 |
2543 { PreservePositionScope scope(masm()->positions_recorder()); | 2505 { PreservePositionScope scope(masm()->positions_recorder()); |
2544 // Generate code for loading from variables potentially shadowed | 2506 // Generate code for loading from variables potentially shadowed |
2545 // by eval-introduced variables. | 2507 // by eval-introduced variables. |
2546 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2508 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
(...skipping 19 matching lines...) Expand all Loading... |
2566 __ Push(x0); | 2528 __ Push(x0); |
2567 // The receiver is implicitly the global receiver. Indicate this | 2529 // The receiver is implicitly the global receiver. Indicate this |
2568 // by passing the undefined to the call function stub. | 2530 // by passing the undefined to the call function stub. |
2569 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2531 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
2570 __ Push(x1); | 2532 __ Push(x1); |
2571 __ Bind(&call); | 2533 __ Bind(&call); |
2572 } | 2534 } |
2573 | 2535 |
2574 // The receiver is either the global receiver or an object found | 2536 // The receiver is either the global receiver or an object found |
2575 // by LoadContextSlot. | 2537 // by LoadContextSlot. |
2576 EmitCallWithStub(expr); | 2538 EmitCall(expr); |
2577 } else if (call_type == Call::PROPERTY_CALL) { | 2539 } else if (call_type == Call::PROPERTY_CALL) { |
2578 Property* property = callee->AsProperty(); | 2540 Property* property = callee->AsProperty(); |
2579 { PreservePositionScope scope(masm()->positions_recorder()); | 2541 { PreservePositionScope scope(masm()->positions_recorder()); |
2580 VisitForStackValue(property->obj()); | 2542 VisitForStackValue(property->obj()); |
2581 } | 2543 } |
2582 if (property->key()->IsPropertyName()) { | 2544 if (property->key()->IsPropertyName()) { |
2583 EmitCallWithIC(expr); | 2545 EmitCallWithLoadIC(expr); |
2584 } else { | 2546 } else { |
2585 EmitKeyedCallWithIC(expr, property->key()); | 2547 EmitKeyedCallWithLoadIC(expr, property->key()); |
2586 } | 2548 } |
2587 | 2549 |
2588 } else { | 2550 } else { |
2589 ASSERT(call_type == Call::OTHER_CALL); | 2551 ASSERT(call_type == Call::OTHER_CALL); |
2590 // Call to an arbitrary expression not handled specially above. | 2552 // Call to an arbitrary expression not handled specially above. |
2591 { PreservePositionScope scope(masm()->positions_recorder()); | 2553 { PreservePositionScope scope(masm()->positions_recorder()); |
2592 VisitForStackValue(callee); | 2554 VisitForStackValue(callee); |
2593 } | 2555 } |
2594 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2556 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
2595 __ Push(x1); | 2557 __ Push(x1); |
2596 // Emit function call. | 2558 // Emit function call. |
2597 EmitCallWithStub(expr); | 2559 EmitCall(expr); |
2598 } | 2560 } |
2599 | 2561 |
2600 #ifdef DEBUG | 2562 #ifdef DEBUG |
2601 // RecordJSReturnSite should have been called. | 2563 // RecordJSReturnSite should have been called. |
2602 ASSERT(expr->return_is_recorded_); | 2564 ASSERT(expr->return_is_recorded_); |
2603 #endif | 2565 #endif |
2604 } | 2566 } |
2605 | 2567 |
2606 | 2568 |
2607 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2569 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
(...skipping 25 matching lines...) Expand all Loading... |
2633 // Record call targets in unoptimized code. | 2595 // Record call targets in unoptimized code. |
2634 if (FLAG_pretenuring_call_new) { | 2596 if (FLAG_pretenuring_call_new) { |
2635 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 2597 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
2636 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2598 ASSERT(expr->AllocationSiteFeedbackSlot() == |
2637 expr->CallNewFeedbackSlot() + 1); | 2599 expr->CallNewFeedbackSlot() + 1); |
2638 } | 2600 } |
2639 | 2601 |
2640 __ LoadObject(x2, FeedbackVector()); | 2602 __ LoadObject(x2, FeedbackVector()); |
2641 __ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot())); | 2603 __ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot())); |
2642 | 2604 |
2643 CallConstructStub stub(RECORD_CALL_TARGET); | 2605 CallConstructStub stub(RECORD_CONSTRUCTOR_TARGET); |
2644 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); | 2606 __ Call(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL); |
2645 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); | 2607 PrepareForBailoutForId(expr->ReturnId(), TOS_REG); |
2646 context()->Plug(x0); | 2608 context()->Plug(x0); |
2647 } | 2609 } |
2648 | 2610 |
2649 | 2611 |
2650 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 2612 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
2651 ZoneList<Expression*>* args = expr->arguments(); | 2613 ZoneList<Expression*>* args = expr->arguments(); |
2652 ASSERT(args->length() == 1); | 2614 ASSERT(args->length() == 1); |
2653 | 2615 |
(...skipping 2327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4981 return previous_; | 4943 return previous_; |
4982 } | 4944 } |
4983 | 4945 |
4984 | 4946 |
4985 #undef __ | 4947 #undef __ |
4986 | 4948 |
4987 | 4949 |
4988 } } // namespace v8::internal | 4950 } } // namespace v8::internal |
4989 | 4951 |
4990 #endif // V8_TARGET_ARCH_ARM64 | 4952 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |