Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(457)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 1348773002: [turbofan] Call ArgumentsAccessStub to materialize arguments. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/mips64/interface-descriptors-mips64.cc ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 // by calling the runtime system. 589 // by calling the runtime system.
590 __ bind(&slow); 590 __ bind(&slow);
591 __ PopReturnAddressTo(rbx); 591 __ PopReturnAddressTo(rbx);
592 __ Push(rdx); 592 __ Push(rdx);
593 __ PushReturnAddressFrom(rbx); 593 __ PushReturnAddressFrom(rbx);
594 __ TailCallRuntime(Runtime::kArguments, 1, 1); 594 __ TailCallRuntime(Runtime::kArguments, 1, 1);
595 } 595 }
596 596
597 597
598 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { 598 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
599 // Stack layout: 599 // rcx : number of parameters (tagged)
600 // rsp[0] : return address 600 // rdx : parameters pointer
601 // rsp[8] : number of parameters (tagged) 601 // rdi : function
602 // rsp[16] : receiver displacement 602 // rsp[0] : return address
603 // rsp[24] : function
604 // Registers used over the whole function: 603 // Registers used over the whole function:
605 // rbx: the mapped parameter count (untagged) 604 // rbx: the mapped parameter count (untagged)
606 // rax: the allocated object (tagged). 605 // rax: the allocated object (tagged).
607 Factory* factory = isolate()->factory(); 606 Factory* factory = isolate()->factory();
608 607
609 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); 608 DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
610 __ SmiToInteger64(rbx, args.GetArgumentOperand(2)); 609 DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
610 DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
611
612 __ SmiToInteger64(rbx, rcx);
611 // rbx = parameter count (untagged) 613 // rbx = parameter count (untagged)
612 614
613 // Check if the calling frame is an arguments adaptor frame. 615 // Check if the calling frame is an arguments adaptor frame.
614 Label runtime; 616 Label adaptor_frame, try_allocate, runtime;
615 Label adaptor_frame, try_allocate; 617 __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
616 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 618 __ movp(r8, Operand(rax, StandardFrameConstants::kContextOffset));
617 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 619 __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
618 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
619 __ j(equal, &adaptor_frame); 620 __ j(equal, &adaptor_frame);
620 621
621 // No adaptor, parameter count = argument count. 622 // No adaptor, parameter count = argument count.
622 __ movp(rcx, rbx); 623 __ movp(r11, rbx);
623 __ jmp(&try_allocate, Label::kNear); 624 __ jmp(&try_allocate, Label::kNear);
624 625
625 // We have an adaptor frame. Patch the parameters pointer. 626 // We have an adaptor frame. Patch the parameters pointer.
626 __ bind(&adaptor_frame); 627 __ bind(&adaptor_frame);
627 __ SmiToInteger64(rcx, 628 __ SmiToInteger64(
628 Operand(rdx, 629 r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset));
629 ArgumentsAdaptorFrameConstants::kLengthOffset)); 630 __ leap(rdx, Operand(rax, r11, times_pointer_size,
630 __ leap(rdx, Operand(rdx, rcx, times_pointer_size, 631 StandardFrameConstants::kCallerSPOffset));
631 StandardFrameConstants::kCallerSPOffset));
632 __ movp(args.GetArgumentOperand(1), rdx);
633 632
634 // rbx = parameter count (untagged) 633 // rbx = parameter count (untagged)
635 // rcx = argument count (untagged) 634 // r11 = argument count (untagged)
636 // Compute the mapped parameter count = min(rbx, rcx) in rbx. 635 // Compute the mapped parameter count = min(rbx, r11) in rbx.
637 __ cmpp(rbx, rcx); 636 __ cmpp(rbx, r11);
638 __ j(less_equal, &try_allocate, Label::kNear); 637 __ j(less_equal, &try_allocate, Label::kNear);
639 __ movp(rbx, rcx); 638 __ movp(rbx, r11);
640 639
641 __ bind(&try_allocate); 640 __ bind(&try_allocate);
642 641
643 // Compute the sizes of backing store, parameter map, and arguments object. 642 // Compute the sizes of backing store, parameter map, and arguments object.
644 // 1. Parameter map, has 2 extra words containing context and backing store. 643 // 1. Parameter map, has 2 extra words containing context and backing store.
645 const int kParameterMapHeaderSize = 644 const int kParameterMapHeaderSize =
646 FixedArray::kHeaderSize + 2 * kPointerSize; 645 FixedArray::kHeaderSize + 2 * kPointerSize;
647 Label no_parameter_map; 646 Label no_parameter_map;
648 __ xorp(r8, r8); 647 __ xorp(r8, r8);
649 __ testp(rbx, rbx); 648 __ testp(rbx, rbx);
650 __ j(zero, &no_parameter_map, Label::kNear); 649 __ j(zero, &no_parameter_map, Label::kNear);
651 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize)); 650 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
652 __ bind(&no_parameter_map); 651 __ bind(&no_parameter_map);
653 652
654 // 2. Backing store. 653 // 2. Backing store.
655 __ leap(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize)); 654 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize));
656 655
657 // 3. Arguments object. 656 // 3. Arguments object.
658 __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize)); 657 __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize));
659 658
660 // Do the allocation of all three objects in one go. 659 // Do the allocation of all three objects in one go.
661 __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT); 660 __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT);
662 661
663 // rax = address of new object(s) (tagged) 662 // rax = address of new object(s) (tagged)
664 // rcx = argument count (untagged) 663 // r11 = argument count (untagged)
665 // Get the arguments map from the current native context into rdi. 664 // Get the arguments map from the current native context into r9.
666 Label has_mapped_parameters, instantiate; 665 Label has_mapped_parameters, instantiate;
667 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 666 __ movp(r9, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
668 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); 667 __ movp(r9, FieldOperand(r9, GlobalObject::kNativeContextOffset));
669 __ testp(rbx, rbx); 668 __ testp(rbx, rbx);
670 __ j(not_zero, &has_mapped_parameters, Label::kNear); 669 __ j(not_zero, &has_mapped_parameters, Label::kNear);
671 670
672 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX; 671 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX;
673 __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex))); 672 __ movp(r9, Operand(r9, Context::SlotOffset(kIndex)));
674 __ jmp(&instantiate, Label::kNear); 673 __ jmp(&instantiate, Label::kNear);
675 674
676 const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX; 675 const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX;
677 __ bind(&has_mapped_parameters); 676 __ bind(&has_mapped_parameters);
678 __ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex))); 677 __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex)));
679 __ bind(&instantiate); 678 __ bind(&instantiate);
680 679
681 // rax = address of new object (tagged) 680 // rax = address of new object (tagged)
682 // rbx = mapped parameter count (untagged) 681 // rbx = mapped parameter count (untagged)
683 // rcx = argument count (untagged) 682 // r11 = argument count (untagged)
684 // rdi = address of arguments map (tagged) 683 // r9 = address of arguments map (tagged)
685 __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi); 684 __ movp(FieldOperand(rax, JSObject::kMapOffset), r9);
686 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); 685 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
687 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); 686 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
688 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); 687 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
689 688
690 // Set up the callee in-object property. 689 // Set up the callee in-object property.
691 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 690 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
692 __ movp(rdx, args.GetArgumentOperand(0)); 691 __ AssertNotSmi(rdi);
693 __ AssertNotSmi(rdx);
694 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 692 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
695 Heap::kArgumentsCalleeIndex * kPointerSize), 693 Heap::kArgumentsCalleeIndex * kPointerSize),
696 rdx); 694 rdi);
697 695
698 // Use the length (smi tagged) and set that as an in-object property too. 696 // Use the length (smi tagged) and set that as an in-object property too.
699 // Note: rcx is tagged from here on. 697 // Note: r11 is tagged from here on.
700 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 698 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
701 __ Integer32ToSmi(rcx, rcx); 699 __ Integer32ToSmi(r11, r11);
702 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 700 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
703 Heap::kArgumentsLengthIndex * kPointerSize), 701 Heap::kArgumentsLengthIndex * kPointerSize),
704 rcx); 702 r11);
705 703
706 // Set up the elements pointer in the allocated arguments object. 704 // Set up the elements pointer in the allocated arguments object.
707 // If we allocated a parameter map, edi will point there, otherwise to the 705 // If we allocated a parameter map, rdi will point there, otherwise to the
708 // backing store. 706 // backing store.
709 __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize)); 707 __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize));
710 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); 708 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
711 709
712 // rax = address of new object (tagged) 710 // rax = address of new object (tagged)
713 // rbx = mapped parameter count (untagged) 711 // rbx = mapped parameter count (untagged)
714 // rcx = argument count (tagged) 712 // r11 = argument count (tagged)
715 // rdi = address of parameter map or backing store (tagged) 713 // rdi = address of parameter map or backing store (tagged)
716 714
717 // Initialize parameter map. If there are no mapped arguments, we're done. 715 // Initialize parameter map. If there are no mapped arguments, we're done.
718 Label skip_parameter_map; 716 Label skip_parameter_map;
719 __ testp(rbx, rbx); 717 __ testp(rbx, rbx);
720 __ j(zero, &skip_parameter_map); 718 __ j(zero, &skip_parameter_map);
721 719
722 __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex); 720 __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex);
723 // rbx contains the untagged argument count. Add 2 and tag to write. 721 // rbx contains the untagged argument count. Add 2 and tag to write.
724 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 722 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
725 __ Integer64PlusConstantToSmi(r9, rbx, 2); 723 __ Integer64PlusConstantToSmi(r9, rbx, 2);
726 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9); 724 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9);
727 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi); 725 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi);
728 __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); 726 __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
729 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9); 727 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9);
730 728
731 // Copy the parameter slots and the holes in the arguments. 729 // Copy the parameter slots and the holes in the arguments.
732 // We need to fill in mapped_parameter_count slots. They index the context, 730 // We need to fill in mapped_parameter_count slots. They index the context,
733 // where parameters are stored in reverse order, at 731 // where parameters are stored in reverse order, at
734 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 732 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
735 // The mapped parameter thus need to get indices 733 // The mapped parameter thus need to get indices
736 // MIN_CONTEXT_SLOTS+parameter_count-1 .. 734 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
737 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count 735 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
738 // We loop from right to left. 736 // We loop from right to left.
739 Label parameters_loop, parameters_test; 737 Label parameters_loop, parameters_test;
740 738
741 // Load tagged parameter count into r9. 739 // Load tagged parameter count into r9.
742 __ Integer32ToSmi(r9, rbx); 740 __ Integer32ToSmi(r9, rbx);
743 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS)); 741 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
744 __ addp(r8, args.GetArgumentOperand(2)); 742 __ addp(r8, rcx);
745 __ subp(r8, r9); 743 __ subp(r8, r9);
746 __ Move(r11, factory->the_hole_value()); 744 __ movp(rcx, rdi);
747 __ movp(rdx, rdi);
748 __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize)); 745 __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
749 // r9 = loop variable (tagged) 746 __ SmiToInteger64(r9, r9);
747 // r9 = loop variable (untagged)
750 // r8 = mapping index (tagged) 748 // r8 = mapping index (tagged)
751 // r11 = the hole value 749 // rcx = address of parameter map (tagged)
752 // rdx = address of parameter map (tagged)
753 // rdi = address of backing store (tagged) 750 // rdi = address of backing store (tagged)
754 __ jmp(&parameters_test, Label::kNear); 751 __ jmp(&parameters_test, Label::kNear);
755 752
756 __ bind(&parameters_loop); 753 __ bind(&parameters_loop);
757 __ SmiSubConstant(r9, r9, Smi::FromInt(1)); 754 __ subp(r9, Immediate(1));
758 __ SmiToInteger64(kScratchRegister, r9); 755 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
759 __ movp(FieldOperand(rdx, kScratchRegister, 756 __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize),
760 times_pointer_size,
761 kParameterMapHeaderSize),
762 r8); 757 r8);
763 __ movp(FieldOperand(rdi, kScratchRegister, 758 __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize),
764 times_pointer_size, 759 kScratchRegister);
765 FixedArray::kHeaderSize),
766 r11);
767 __ SmiAddConstant(r8, r8, Smi::FromInt(1)); 760 __ SmiAddConstant(r8, r8, Smi::FromInt(1));
768 __ bind(&parameters_test); 761 __ bind(&parameters_test);
769 __ SmiTest(r9); 762 __ testp(r9, r9);
770 __ j(not_zero, &parameters_loop, Label::kNear); 763 __ j(not_zero, &parameters_loop, Label::kNear);
771 764
772 __ bind(&skip_parameter_map); 765 __ bind(&skip_parameter_map);
773 766
774 // rcx = argument count (tagged) 767 // r11 = argument count (tagged)
775 // rdi = address of backing store (tagged) 768 // rdi = address of backing store (tagged)
776 // Copy arguments header and remaining slots (if there are any). 769 // Copy arguments header and remaining slots (if there are any).
777 __ Move(FieldOperand(rdi, FixedArray::kMapOffset), 770 __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
778 factory->fixed_array_map()); 771 factory->fixed_array_map());
779 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); 772 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11);
780 773
781 Label arguments_loop, arguments_test; 774 Label arguments_loop, arguments_test;
782 __ movp(r8, rbx); 775 __ movp(r8, rbx);
783 __ movp(rdx, args.GetArgumentOperand(1)); 776 // Untag r11 for the loop below.
784 // Untag rcx for the loop below. 777 __ SmiToInteger64(r11, r11);
785 __ SmiToInteger64(rcx, rcx);
786 __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0)); 778 __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0));
787 __ subp(rdx, kScratchRegister); 779 __ subp(rdx, kScratchRegister);
788 __ jmp(&arguments_test, Label::kNear); 780 __ jmp(&arguments_test, Label::kNear);
789 781
790 __ bind(&arguments_loop); 782 __ bind(&arguments_loop);
791 __ subp(rdx, Immediate(kPointerSize)); 783 __ subp(rdx, Immediate(kPointerSize));
792 __ movp(r9, Operand(rdx, 0)); 784 __ movp(r9, Operand(rdx, 0));
793 __ movp(FieldOperand(rdi, r8, 785 __ movp(FieldOperand(rdi, r8,
794 times_pointer_size, 786 times_pointer_size,
795 FixedArray::kHeaderSize), 787 FixedArray::kHeaderSize),
796 r9); 788 r9);
797 __ addp(r8, Immediate(1)); 789 __ addp(r8, Immediate(1));
798 790
799 __ bind(&arguments_test); 791 __ bind(&arguments_test);
800 __ cmpp(r8, rcx); 792 __ cmpp(r8, r11);
801 __ j(less, &arguments_loop, Label::kNear); 793 __ j(less, &arguments_loop, Label::kNear);
802 794
803 // Return and remove the on-stack parameters. 795 // Return.
804 __ ret(3 * kPointerSize); 796 __ ret(0);
805 797
806 // Do the runtime call to allocate the arguments object. 798 // Do the runtime call to allocate the arguments object.
807 // rcx = argument count (untagged) 799 // r11 = argument count (untagged)
808 __ bind(&runtime); 800 __ bind(&runtime);
809 __ Integer32ToSmi(rcx, rcx); 801 __ Integer32ToSmi(r11, r11);
810 __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count. 802 __ PopReturnAddressTo(rax);
803 __ Push(rdi); // Push function.
804 __ Push(rdx); // Push parameters pointer.
805 __ Push(r11); // Push parameter count.
806 __ PushReturnAddressFrom(rax);
811 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 807 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
812 } 808 }
813 809
814 810
815 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { 811 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
816 // rsp[0] : return address 812 // rcx : number of parameters (tagged)
817 // rsp[8] : number of parameters 813 // rdx : parameters pointer
818 // rsp[16] : receiver displacement 814 // rdi : function
819 // rsp[24] : function 815 // rsp[0] : return address
816
817 DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
818 DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
819 DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
820 820
821 // Check if the calling frame is an arguments adaptor frame. 821 // Check if the calling frame is an arguments adaptor frame.
822 Label runtime; 822 Label runtime;
823 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 823 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
824 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 824 __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset));
825 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 825 __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
826 __ j(not_equal, &runtime); 826 __ j(not_equal, &runtime);
827 827
828 // Patch the arguments.length and the parameters pointer. 828 // Patch the arguments.length and the parameters pointer.
829 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); 829 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
830 __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 830 __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
831 __ movp(args.GetArgumentOperand(2), rcx); 831 __ SmiToInteger64(rax, rcx);
832 __ SmiToInteger64(rcx, rcx); 832 __ leap(rdx, Operand(rbx, rax, times_pointer_size,
833 __ leap(rdx, Operand(rdx, rcx, times_pointer_size, 833 StandardFrameConstants::kCallerSPOffset));
834 StandardFrameConstants::kCallerSPOffset));
835 __ movp(args.GetArgumentOperand(1), rdx);
836 834
837 __ bind(&runtime); 835 __ bind(&runtime);
836 __ PopReturnAddressTo(rax);
837 __ Push(rdi); // Push function.
838 __ Push(rdx); // Push parameters pointer.
839 __ Push(rcx); // Push parameter count.
840 __ PushReturnAddressFrom(rax);
838 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1); 841 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
839 } 842 }
840 843
841 844
842 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { 845 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) {
843 // Return address is on the stack. 846 // Return address is on the stack.
844 Label slow; 847 Label slow;
845 848
846 Register receiver = LoadDescriptor::ReceiverRegister(); 849 Register receiver = LoadDescriptor::ReceiverRegister();
847 Register key = LoadDescriptor::NameRegister(); 850 Register key = LoadDescriptor::NameRegister();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 StubRuntimeCallHelper call_helper; 897 StubRuntimeCallHelper call_helper;
895 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper); 898 char_at_generator.GenerateSlow(masm, PART_OF_IC_HANDLER, call_helper);
896 899
897 __ bind(&miss); 900 __ bind(&miss);
898 PropertyAccessCompiler::TailCallBuiltin( 901 PropertyAccessCompiler::TailCallBuiltin(
899 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); 902 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
900 } 903 }
901 904
902 905
903 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 906 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
904 // rsp[0] : return address 907 // rcx : number of parameters (tagged)
905 // rsp[8] : number of parameters 908 // rdx : parameters pointer
906 // rsp[16] : receiver displacement 909 // rdi : function
907 // rsp[24] : function 910 // rsp[0] : return address
911
912 DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
913 DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
914 DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
908 915
909 // Check if the calling frame is an arguments adaptor frame. 916 // Check if the calling frame is an arguments adaptor frame.
910 Label adaptor_frame, try_allocate, runtime; 917 Label adaptor_frame, try_allocate, runtime;
911 __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 918 __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
912 __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset)); 919 __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset));
913 __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 920 __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
914 __ j(equal, &adaptor_frame); 921 __ j(equal, &adaptor_frame);
915 922
916 // Get the length from the frame. 923 // Get the length from the frame.
917 StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER); 924 __ SmiToInteger64(rax, rcx);
918 __ movp(rcx, args.GetArgumentOperand(2));
919 __ SmiToInteger64(rcx, rcx);
920 __ jmp(&try_allocate); 925 __ jmp(&try_allocate);
921 926
922 // Patch the arguments.length and the parameters pointer. 927 // Patch the arguments.length and the parameters pointer.
923 __ bind(&adaptor_frame); 928 __ bind(&adaptor_frame);
924 __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 929 __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
925 930 __ SmiToInteger64(rax, rcx);
926 __ movp(args.GetArgumentOperand(2), rcx); 931 __ leap(rdx, Operand(rbx, rax, times_pointer_size,
927 __ SmiToInteger64(rcx, rcx); 932 StandardFrameConstants::kCallerSPOffset));
928 __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
929 StandardFrameConstants::kCallerSPOffset));
930 __ movp(args.GetArgumentOperand(1), rdx);
931 933
932 // Try the new space allocation. Start out with computing the size of 934 // Try the new space allocation. Start out with computing the size of
933 // the arguments object and the elements array. 935 // the arguments object and the elements array.
934 Label add_arguments_object; 936 Label add_arguments_object;
935 __ bind(&try_allocate); 937 __ bind(&try_allocate);
936 __ testp(rcx, rcx); 938 __ testp(rax, rax);
937 __ j(zero, &add_arguments_object, Label::kNear); 939 __ j(zero, &add_arguments_object, Label::kNear);
938 __ leap(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize)); 940 __ leap(rax, Operand(rax, times_pointer_size, FixedArray::kHeaderSize));
939 __ bind(&add_arguments_object); 941 __ bind(&add_arguments_object);
940 __ addp(rcx, Immediate(Heap::kStrictArgumentsObjectSize)); 942 __ addp(rax, Immediate(Heap::kStrictArgumentsObjectSize));
941 943
942 // Do the allocation of both objects in one go. 944 // Do the allocation of both objects in one go.
943 __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT); 945 __ Allocate(rax, rax, rbx, no_reg, &runtime, TAG_OBJECT);
944 946
945 // Get the arguments map from the current native context. 947 // Get the arguments map from the current native context.
946 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 948 __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
947 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset)); 949 __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
948 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX); 950 const int offset = Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX);
949 __ movp(rdi, Operand(rdi, offset)); 951 __ movp(rdi, Operand(rdi, offset));
950 952
951 __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi); 953 __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi);
952 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex); 954 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
953 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister); 955 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
954 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister); 956 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
955 957
956 // Get the length (smi tagged) and set that as an in-object property too. 958 // Get the length (smi tagged) and set that as an in-object property too.
957 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 959 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
958 __ movp(rcx, args.GetArgumentOperand(2));
959 __ movp(FieldOperand(rax, JSObject::kHeaderSize + 960 __ movp(FieldOperand(rax, JSObject::kHeaderSize +
960 Heap::kArgumentsLengthIndex * kPointerSize), 961 Heap::kArgumentsLengthIndex * kPointerSize),
961 rcx); 962 rcx);
962 963
963 // If there are no actual arguments, we're done. 964 // If there are no actual arguments, we're done.
964 Label done; 965 Label done;
965 __ testp(rcx, rcx); 966 __ testp(rcx, rcx);
966 __ j(zero, &done); 967 __ j(zero, &done);
967 968
968 // Get the parameters pointer from the stack.
969 __ movp(rdx, args.GetArgumentOperand(1));
970
971 // Set up the elements pointer in the allocated arguments object and 969 // Set up the elements pointer in the allocated arguments object and
972 // initialize the header in the elements fixed array. 970 // initialize the header in the elements fixed array.
973 __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize)); 971 __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize));
974 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi); 972 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
975 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); 973 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
976 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 974 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
975 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
977 976
978
979 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
980 // Untag the length for the loop below. 977 // Untag the length for the loop below.
981 __ SmiToInteger64(rcx, rcx); 978 __ SmiToInteger64(rcx, rcx);
982 979
983 // Copy the fixed array slots. 980 // Copy the fixed array slots.
984 Label loop; 981 Label loop;
985 __ bind(&loop); 982 __ bind(&loop);
986 __ movp(rbx, Operand(rdx, -1 * kPointerSize)); // Skip receiver. 983 __ movp(rbx, Operand(rdx, -1 * kPointerSize)); // Skip receiver.
987 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize), rbx); 984 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize), rbx);
988 __ addp(rdi, Immediate(kPointerSize)); 985 __ addp(rdi, Immediate(kPointerSize));
989 __ subp(rdx, Immediate(kPointerSize)); 986 __ subp(rdx, Immediate(kPointerSize));
990 __ decp(rcx); 987 __ decp(rcx);
991 __ j(not_zero, &loop); 988 __ j(not_zero, &loop);
992 989
993 // Return and remove the on-stack parameters. 990 // Return.
994 __ bind(&done); 991 __ bind(&done);
995 __ ret(3 * kPointerSize); 992 __ ret(0);
996 993
997 // Do the runtime call to allocate the arguments object. 994 // Do the runtime call to allocate the arguments object.
998 __ bind(&runtime); 995 __ bind(&runtime);
996 __ PopReturnAddressTo(rax);
997 __ Push(rdi); // Push function.
998 __ Push(rdx); // Push parameters pointer.
999 __ Push(rcx); // Push parameter count.
1000 __ PushReturnAddressFrom(rax);
999 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1); 1001 __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
1000 } 1002 }
1001 1003
1002 1004
1003 void RegExpExecStub::Generate(MacroAssembler* masm) { 1005 void RegExpExecStub::Generate(MacroAssembler* masm) {
1004 // Just jump directly to runtime if native RegExp is not selected at compile 1006 // Just jump directly to runtime if native RegExp is not selected at compile
1005 // time or if regexp entry in generated code is turned off runtime switch or 1007 // time or if regexp entry in generated code is turned off runtime switch or
1006 // at compilation. 1008 // at compilation.
1007 #ifdef V8_INTERPRETED_REGEXP 1009 #ifdef V8_INTERPRETED_REGEXP
1008 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 1010 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
(...skipping 4563 matching lines...) Expand 10 before | Expand all | Expand 10 after
5572 kStackSpace, nullptr, return_value_operand, NULL); 5574 kStackSpace, nullptr, return_value_operand, NULL);
5573 } 5575 }
5574 5576
5575 5577
5576 #undef __ 5578 #undef __
5577 5579
5578 } // namespace internal 5580 } // namespace internal
5579 } // namespace v8 5581 } // namespace v8
5580 5582
5581 #endif // V8_TARGET_ARCH_X64 5583 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips64/interface-descriptors-mips64.cc ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698