OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 Label loop_header, loop_check; | 538 Label loop_header, loop_check; |
539 __ jmp(&loop_check); | 539 __ jmp(&loop_check); |
540 __ bind(&loop_header); | 540 __ bind(&loop_header); |
541 __ Push(Operand(ebx, 0)); | 541 __ Push(Operand(ebx, 0)); |
542 __ sub(ebx, Immediate(kPointerSize)); | 542 __ sub(ebx, Immediate(kPointerSize)); |
543 __ bind(&loop_check); | 543 __ bind(&loop_check); |
544 __ cmp(ebx, array_limit); | 544 __ cmp(ebx, array_limit); |
545 __ j(greater, &loop_header, Label::kNear); | 545 __ j(greater, &loop_header, Label::kNear); |
546 } | 546 } |
547 | 547 |
| 548 static void Generate_InterpreterComputeLastArgumentAddress(MacroAssembler* masm, |
| 549 Register r) { |
| 550 // Find the address of the last argument. |
| 551 // ----------- S t a t e ------------- |
| 552 // input: eax : Number of arguments. |
| 553 // input: ebx : Address of the first argument. |
| 554 // output: Register |r|: Address of the last argument. |
| 555 // ----------------------------------- |
| 556 __ mov(r, eax); |
| 557 __ add(r, Immediate(1)); // Add one for receiver. |
| 558 __ shl(r, kPointerSizeLog2); |
| 559 __ neg(r); |
| 560 __ add(r, ebx); |
| 561 } |
| 562 |
| 563 // static |
| 564 void Builtins::Generate_InterpreterPushArgsAndCallICImpl( |
| 565 MacroAssembler* masm, TailCallMode tail_call_mode) { |
| 566 // ----------- S t a t e ------------- |
| 567 // -- eax : the number of arguments (not including the receiver) |
| 568 // -- ebx : the address of the first argument to be pushed. Subsequent |
| 569 // arguments should be consecutive above this, in the same order as |
| 570 // they are to be pushed onto the stack. |
| 571 // -- edi : the target to call (can be any Object). |
| 572 // -- edx : feedback slot id. |
| 573 // -- ecx : type feedback vector. |
| 574 // ----------------------------------- |
| 575 |
| 576 { |
| 577 FrameScope scope(masm, StackFrame::INTERNAL); |
| 578 // Store type feedback vector on the stack since we ran out of registers. |
| 579 __ Push(ecx); |
| 580 |
| 581 // computes the address of last argument in ecx. |
| 582 // ecx = ebx - (eax + 1) * kPointerSize. |
| 583 Generate_InterpreterComputeLastArgumentAddress(masm, ecx); |
| 584 Generate_InterpreterPushArgs(masm, ecx); |
| 585 |
| 586 // Restore feedback vector to ebx from the stack. It was pushed |
| 587 // before the arguments were pushed, so compute the correct offset. |
| 588 __ mov(ebx, Operand(esp, eax, times_pointer_size, 1 * kPointerSize)); |
| 589 |
| 590 // Call via the CallIC stub. |
| 591 CallICState call_ic_state(0, ConvertReceiverMode::kAny, tail_call_mode, |
| 592 true); |
| 593 CallICStub stub(masm->isolate(), call_ic_state); |
| 594 // TODO(mythria): This should be replaced by a TailCallStub, when we |
| 595 // update the code to find the target IC from jump instructions. |
| 596 __ CallStub(&stub); |
| 597 } |
| 598 __ Ret(); |
| 599 } |
548 | 600 |
549 // static | 601 // static |
550 void Builtins::Generate_InterpreterPushArgsAndCallImpl( | 602 void Builtins::Generate_InterpreterPushArgsAndCallImpl( |
551 MacroAssembler* masm, TailCallMode tail_call_mode) { | 603 MacroAssembler* masm, TailCallMode tail_call_mode) { |
552 // ----------- S t a t e ------------- | 604 // ----------- S t a t e ------------- |
553 // -- eax : the number of arguments (not including the receiver) | 605 // -- eax : the number of arguments (not including the receiver) |
554 // -- ebx : the address of the first argument to be pushed. Subsequent | 606 // -- ebx : the address of the first argument to be pushed. Subsequent |
555 // arguments should be consecutive above this, in the same order as | 607 // arguments should be consecutive above this, in the same order as |
556 // they are to be pushed onto the stack. | 608 // they are to be pushed onto the stack. |
557 // -- edi : the target to call (can be any Object). | 609 // -- edi : the target to call (can be any Object). |
558 // ----------------------------------- | 610 // ----------------------------------- |
559 | 611 |
560 // Pop return address to allow tail-call after pushing arguments. | 612 // Pop return address to allow tail-call after pushing arguments. |
561 __ Pop(edx); | 613 __ Pop(edx); |
562 | 614 |
563 // Find the address of the last argument. | 615 // computes the address of last argument in ecx. |
564 __ mov(ecx, eax); | 616 // ecx = ebx - (eax + 1) * kPointerSize. |
565 __ add(ecx, Immediate(1)); // Add one for receiver. | 617 Generate_InterpreterComputeLastArgumentAddress(masm, ecx); |
566 __ shl(ecx, kPointerSizeLog2); | |
567 __ neg(ecx); | |
568 __ add(ecx, ebx); | |
569 | |
570 Generate_InterpreterPushArgs(masm, ecx); | 618 Generate_InterpreterPushArgs(masm, ecx); |
571 | 619 |
572 // Call the target. | 620 // Call the target. |
573 __ Push(edx); // Re-push return address. | 621 __ Push(edx); // Re-push return address. |
574 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 622 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
575 tail_call_mode), | 623 tail_call_mode), |
576 RelocInfo::CODE_TARGET); | 624 RelocInfo::CODE_TARGET); |
577 } | 625 } |
578 | 626 |
579 | |
580 // static | 627 // static |
581 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { | 628 void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) { |
582 // ----------- S t a t e ------------- | 629 // ----------- S t a t e ------------- |
583 // -- eax : the number of arguments (not including the receiver) | 630 // -- eax : the number of arguments (not including the receiver) |
584 // -- edx : the new target | 631 // -- edx : the new target |
585 // -- edi : the constructor | 632 // -- edi : the constructor |
586 // -- ebx : the address of the first argument to be pushed. Subsequent | 633 // -- ebx : the address of the first argument to be pushed. Subsequent |
587 // arguments should be consecutive above this, in the same order as | 634 // arguments should be consecutive above this, in the same order as |
588 // they are to be pushed onto the stack. | 635 // they are to be pushed onto the stack. |
589 // ----------------------------------- | 636 // ----------------------------------- |
590 | 637 |
591 // Save number of arguments on the stack below where arguments are going | |
592 // to be pushed. | |
593 __ mov(ecx, eax); | |
594 __ neg(ecx); | |
595 __ mov(Operand(esp, ecx, times_pointer_size, -kPointerSize), eax); | |
596 __ mov(eax, ecx); | |
597 | |
598 // Pop return address to allow tail-call after pushing arguments. | 638 // Pop return address to allow tail-call after pushing arguments. |
599 __ Pop(ecx); | 639 __ Pop(ecx); |
600 | 640 |
| 641 // Push edi in the slot meant for receiver. We need an extra register so |
| 642 // store edi temporarily on the stack. |
| 643 __ Push(edi); |
| 644 |
601 // Find the address of the last argument. | 645 // Find the address of the last argument. |
602 __ shl(eax, kPointerSizeLog2); | 646 __ mov(edi, eax); |
603 __ add(eax, ebx); | 647 __ neg(edi); |
| 648 __ shl(edi, kPointerSizeLog2); |
| 649 __ add(edi, ebx); |
604 | 650 |
605 // Push padding for receiver. | 651 Generate_InterpreterPushArgs(masm, edi); |
606 __ Push(Immediate(0)); | |
607 | 652 |
608 Generate_InterpreterPushArgs(masm, eax); | 653 // Restore number of arguments from slot on stack. edi was pushed at |
609 | 654 // the slot meant for receiver. |
610 // Restore number of arguments from slot on stack. | 655 __ mov(edi, Operand(esp, eax, times_pointer_size, 0)); |
611 __ mov(eax, Operand(esp, -kPointerSize)); | |
612 | 656 |
613 // Re-push return address. | 657 // Re-push return address. |
614 __ Push(ecx); | 658 __ Push(ecx); |
615 | 659 |
616 // Call the constructor with unmodified eax, edi, ebi values. | 660 // Call the constructor with unmodified eax, edi, ebi values. |
617 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 661 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
618 } | 662 } |
619 | 663 |
620 | 664 |
621 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { | 665 static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) { |
(...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 Comment cmnt(masm, "[ PrepareForTailCall"); | 1896 Comment cmnt(masm, "[ PrepareForTailCall"); |
1853 | 1897 |
1854 // Prepare for tail call only if the debugger is not active. | 1898 // Prepare for tail call only if the debugger is not active. |
1855 Label done; | 1899 Label done; |
1856 ExternalReference debug_is_active = | 1900 ExternalReference debug_is_active = |
1857 ExternalReference::debug_is_active_address(masm->isolate()); | 1901 ExternalReference::debug_is_active_address(masm->isolate()); |
1858 __ movzx_b(scratch1, Operand::StaticVariable(debug_is_active)); | 1902 __ movzx_b(scratch1, Operand::StaticVariable(debug_is_active)); |
1859 __ cmp(scratch1, Immediate(0)); | 1903 __ cmp(scratch1, Immediate(0)); |
1860 __ j(not_equal, &done, Label::kNear); | 1904 __ j(not_equal, &done, Label::kNear); |
1861 | 1905 |
| 1906 // Drop possible internal frame pushed for calling CallICStub. |
| 1907 // TODO(mythria): when we tail call the CallICStub, remove this. |
| 1908 { |
| 1909 Label no_internal_callic_frame; |
| 1910 __ cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), |
| 1911 Immediate(Smi::FromInt(StackFrame::INTERNAL))); |
| 1912 __ j(not_equal, &no_internal_callic_frame, Label::kNear); |
| 1913 __ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 1914 __ bind(&no_internal_callic_frame); |
| 1915 } |
| 1916 |
1862 // Drop possible interpreter handler/stub frame. | 1917 // Drop possible interpreter handler/stub frame. |
1863 { | 1918 { |
1864 Label no_interpreter_frame; | 1919 Label no_interpreter_frame; |
1865 __ cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), | 1920 __ cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), |
1866 Immediate(Smi::FromInt(StackFrame::STUB))); | 1921 Immediate(Smi::FromInt(StackFrame::STUB))); |
1867 __ j(not_equal, &no_interpreter_frame, Label::kNear); | 1922 __ j(not_equal, &no_interpreter_frame, Label::kNear); |
1868 __ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 1923 __ mov(ebp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
1869 __ bind(&no_interpreter_frame); | 1924 __ bind(&no_interpreter_frame); |
1870 } | 1925 } |
1871 | 1926 |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2649 | 2704 |
2650 __ bind(&ok); | 2705 __ bind(&ok); |
2651 __ ret(0); | 2706 __ ret(0); |
2652 } | 2707 } |
2653 | 2708 |
2654 #undef __ | 2709 #undef __ |
2655 } // namespace internal | 2710 } // namespace internal |
2656 } // namespace v8 | 2711 } // namespace v8 |
2657 | 2712 |
2658 #endif // V8_TARGET_ARCH_IA32 | 2713 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |