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

Side by Side Diff: src/builtins/ia32/builtins-ia32.cc

Issue 2649143002: [Turbofan] Implement call with spread bytecode in assembly code. (Closed)
Patch Set: Rename PushArgsMode to InterpreterPushArgsMode Created 3 years, 11 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/builtins/builtins-interpreter.cc ('k') | src/builtins/mips/builtins-mips.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 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 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 __ Push(Operand(start_address, 0)); 686 __ Push(Operand(start_address, 0));
687 __ sub(start_address, Immediate(kPointerSize)); 687 __ sub(start_address, Immediate(kPointerSize));
688 __ bind(&loop_check); 688 __ bind(&loop_check);
689 __ cmp(start_address, array_limit); 689 __ cmp(start_address, array_limit);
690 __ j(greater, &loop_header, Label::kNear); 690 __ j(greater, &loop_header, Label::kNear);
691 } 691 }
692 692
693 // static 693 // static
694 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 694 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
695 MacroAssembler* masm, TailCallMode tail_call_mode, 695 MacroAssembler* masm, TailCallMode tail_call_mode,
696 CallableType function_type) { 696 InterpreterPushArgsMode mode) {
697 // ----------- S t a t e ------------- 697 // ----------- S t a t e -------------
698 // -- eax : the number of arguments (not including the receiver) 698 // -- eax : the number of arguments (not including the receiver)
699 // -- ebx : the address of the first argument to be pushed. Subsequent 699 // -- ebx : the address of the first argument to be pushed. Subsequent
700 // arguments should be consecutive above this, in the same order as 700 // arguments should be consecutive above this, in the same order as
701 // they are to be pushed onto the stack. 701 // they are to be pushed onto the stack.
702 // -- edi : the target to call (can be any Object). 702 // -- edi : the target to call (can be any Object).
703 // ----------------------------------- 703 // -----------------------------------
704 Label stack_overflow; 704 Label stack_overflow;
705 // Compute the expected number of arguments. 705 // Compute the expected number of arguments.
706 __ mov(ecx, eax); 706 __ mov(ecx, eax);
(...skipping 11 matching lines...) Expand all
718 718
719 // Find the address of the last argument. 719 // Find the address of the last argument.
720 __ shl(ecx, kPointerSizeLog2); 720 __ shl(ecx, kPointerSizeLog2);
721 __ neg(ecx); 721 __ neg(ecx);
722 __ add(ecx, ebx); 722 __ add(ecx, ebx);
723 Generate_InterpreterPushArgs(masm, ecx, ebx); 723 Generate_InterpreterPushArgs(masm, ecx, ebx);
724 724
725 // Call the target. 725 // Call the target.
726 __ Push(edx); // Re-push return address. 726 __ Push(edx); // Re-push return address.
727 727
728 if (function_type == CallableType::kJSFunction) { 728 if (mode == InterpreterPushArgsMode::kJSFunction) {
729 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 729 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
730 tail_call_mode), 730 tail_call_mode),
731 RelocInfo::CODE_TARGET); 731 RelocInfo::CODE_TARGET);
732 } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
733 __ Jump(masm->isolate()->builtins()->CallWithSpread(),
734 RelocInfo::CODE_TARGET);
732 } else { 735 } else {
733 DCHECK_EQ(function_type, CallableType::kAny);
734 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 736 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
735 tail_call_mode), 737 tail_call_mode),
736 RelocInfo::CODE_TARGET); 738 RelocInfo::CODE_TARGET);
737 } 739 }
738 740
739 __ bind(&stack_overflow); 741 __ bind(&stack_overflow);
740 { 742 {
741 // Pop the temporary registers, so that return address is on top of stack. 743 // Pop the temporary registers, so that return address is on top of stack.
742 __ Pop(edi); 744 __ Pop(edi);
743 745
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 __ sub(scratch1, Immediate(1)); 838 __ sub(scratch1, Immediate(1));
837 __ bind(&loop_check); 839 __ bind(&loop_check);
838 __ cmp(scratch1, Immediate(0)); 840 __ cmp(scratch1, Immediate(0));
839 __ j(greater, &loop_header, Label::kNear); 841 __ j(greater, &loop_header, Label::kNear);
840 } 842 }
841 843
842 } // end anonymous namespace 844 } // end anonymous namespace
843 845
844 // static 846 // static
845 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 847 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
846 MacroAssembler* masm, PushArgsConstructMode mode) { 848 MacroAssembler* masm, InterpreterPushArgsMode mode) {
847 // ----------- S t a t e ------------- 849 // ----------- S t a t e -------------
848 // -- eax : the number of arguments (not including the receiver) 850 // -- eax : the number of arguments (not including the receiver)
849 // -- edx : the new target 851 // -- edx : the new target
850 // -- edi : the constructor 852 // -- edi : the constructor
851 // -- ebx : allocation site feedback (if available or undefined) 853 // -- ebx : allocation site feedback (if available or undefined)
852 // -- ecx : the address of the first argument to be pushed. Subsequent 854 // -- ecx : the address of the first argument to be pushed. Subsequent
853 // arguments should be consecutive above this, in the same order as 855 // arguments should be consecutive above this, in the same order as
854 // they are to be pushed onto the stack. 856 // they are to be pushed onto the stack.
855 // ----------------------------------- 857 // -----------------------------------
856 Label stack_overflow; 858 Label stack_overflow;
857 // We need two scratch registers. Push edi and edx onto stack. 859 // We need two scratch registers. Push edi and edx onto stack.
858 __ Push(edi); 860 __ Push(edi);
859 __ Push(edx); 861 __ Push(edx);
860 862
861 // Push arguments and move return address to the top of stack. 863 // Push arguments and move return address to the top of stack.
862 // The eax register is readonly. The ecx register will be modified. The edx 864 // The eax register is readonly. The ecx register will be modified. The edx
863 // and edi registers will be modified but restored to their original values. 865 // and edi registers will be modified but restored to their original values.
864 Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false, 866 Generate_InterpreterPushArgsAndReturnAddress(masm, eax, ecx, edx, edi, false,
865 2, &stack_overflow); 867 2, &stack_overflow);
866 868
867 // Restore edi and edx 869 // Restore edi and edx
868 __ Pop(edx); 870 __ Pop(edx);
869 __ Pop(edi); 871 __ Pop(edi);
870 872
871 __ AssertUndefinedOrAllocationSite(ebx); 873 __ AssertUndefinedOrAllocationSite(ebx);
872 if (mode == PushArgsConstructMode::kJSFunction) { 874 if (mode == InterpreterPushArgsMode::kJSFunction) {
873 // Tail call to the function-specific construct stub (still in the caller 875 // Tail call to the function-specific construct stub (still in the caller
874 // context at this point). 876 // context at this point).
875 __ AssertFunction(edi); 877 __ AssertFunction(edi);
876 878
877 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 879 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
878 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset)); 880 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
879 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize)); 881 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
880 __ jmp(ecx); 882 __ jmp(ecx);
881 } else if (mode == PushArgsConstructMode::kWithFinalSpread) { 883 } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
882 // Call the constructor with unmodified eax, edi, edx values. 884 // Call the constructor with unmodified eax, edi, edx values.
883 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(), 885 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
884 RelocInfo::CODE_TARGET); 886 RelocInfo::CODE_TARGET);
885 } else { 887 } else {
886 DCHECK_EQ(PushArgsConstructMode::kOther, mode); 888 DCHECK_EQ(InterpreterPushArgsMode::kOther, mode);
887 // Call the constructor with unmodified eax, edi, edx values. 889 // Call the constructor with unmodified eax, edi, edx values.
888 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 890 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
889 } 891 }
890 892
891 __ bind(&stack_overflow); 893 __ bind(&stack_overflow);
892 { 894 {
893 // Pop the temporary registers, so that return address is on top of stack. 895 // Pop the temporary registers, so that return address is on top of stack.
894 __ Pop(edx); 896 __ Pop(edx);
895 __ Pop(edi); 897 __ Pop(edi);
896 898
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 2668
2667 // 3. Call to something that is not callable. 2669 // 3. Call to something that is not callable.
2668 __ bind(&non_callable); 2670 __ bind(&non_callable);
2669 { 2671 {
2670 FrameScope scope(masm, StackFrame::INTERNAL); 2672 FrameScope scope(masm, StackFrame::INTERNAL);
2671 __ Push(edi); 2673 __ Push(edi);
2672 __ CallRuntime(Runtime::kThrowCalledNonCallable); 2674 __ CallRuntime(Runtime::kThrowCalledNonCallable);
2673 } 2675 }
2674 } 2676 }
2675 2677
2676 // static 2678 static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
2677 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2678 // ----------- S t a t e -------------
2679 // -- eax : the number of arguments (not including the receiver)
2680 // -- edx : the new target (checked to be a constructor)
2681 // -- edi : the constructor to call (checked to be a JSFunction)
2682 // -----------------------------------
2683 __ AssertFunction(edi);
2684
2685 // Calling convention for function specific ConstructStubs require
2686 // ebx to contain either an AllocationSite or undefined.
2687 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
2688
2689 // Tail call to the function-specific construct stub (still in the caller
2690 // context at this point).
2691 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2692 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
2693 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2694 __ jmp(ecx);
2695 }
2696
2697 // static
2698 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2699 // ----------- S t a t e -------------
2700 // -- eax : the number of arguments (not including the receiver)
2701 // -- edx : the new target (checked to be a constructor)
2702 // -- edi : the constructor to call (checked to be a JSBoundFunction)
2703 // -----------------------------------
2704 __ AssertBoundFunction(edi);
2705
2706 // Push the [[BoundArguments]] onto the stack.
2707 Generate_PushBoundArguments(masm);
2708
2709 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2710 {
2711 Label done;
2712 __ cmp(edi, edx);
2713 __ j(not_equal, &done, Label::kNear);
2714 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2715 __ bind(&done);
2716 }
2717
2718 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2719 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2720 __ mov(ecx, Operand::StaticVariable(
2721 ExternalReference(Builtins::kConstruct, masm->isolate())));
2722 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2723 __ jmp(ecx);
2724 }
2725
2726 // static
2727 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2728 // ----------- S t a t e -------------
2729 // -- eax : the number of arguments (not including the receiver)
2730 // -- edi : the constructor to call (checked to be a JSProxy)
2731 // -- edx : the new target (either the same as the constructor or
2732 // the JSFunction on which new was invoked initially)
2733 // -----------------------------------
2734
2735 // Call into the Runtime for Proxy [[Construct]].
2736 __ PopReturnAddressTo(ecx);
2737 __ Push(edi);
2738 __ Push(edx);
2739 __ PushReturnAddressFrom(ecx);
2740 // Include the pushed new_target, constructor and the receiver.
2741 __ add(eax, Immediate(3));
2742 // Tail-call to the runtime.
2743 __ JumpToExternalReference(
2744 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2745 }
2746
2747 // static
2748 void Builtins::Generate_Construct(MacroAssembler* masm) {
2749 // ----------- S t a t e -------------
2750 // -- eax : the number of arguments (not including the receiver)
2751 // -- edx : the new target (either the same as the constructor or
2752 // the JSFunction on which new was invoked initially)
2753 // -- edi : the constructor to call (can be any Object)
2754 // -----------------------------------
2755
2756 // Check if target is a Smi.
2757 Label non_constructor;
2758 __ JumpIfSmi(edi, &non_constructor, Label::kNear);
2759
2760 // Dispatch based on instance type.
2761 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2762 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2763 RelocInfo::CODE_TARGET);
2764
2765 // Check if target has a [[Construct]] internal method.
2766 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2767 Immediate(1 << Map::kIsConstructor));
2768 __ j(zero, &non_constructor, Label::kNear);
2769
2770 // Only dispatch to bound functions after checking whether they are
2771 // constructors.
2772 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2773 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2774 RelocInfo::CODE_TARGET);
2775
2776 // Only dispatch to proxies after checking whether they are constructors.
2777 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2778 __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2779 RelocInfo::CODE_TARGET);
2780
2781 // Called Construct on an exotic Object with a [[Construct]] internal method.
2782 {
2783 // Overwrite the original receiver with the (original) target.
2784 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2785 // Let the "call_as_constructor_delegate" take care of the rest.
2786 __ LoadGlobalFunction(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, edi);
2787 __ Jump(masm->isolate()->builtins()->CallFunction(),
2788 RelocInfo::CODE_TARGET);
2789 }
2790
2791 // Called Construct on an Object that doesn't have a [[Construct]] internal
2792 // method.
2793 __ bind(&non_constructor);
2794 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2795 RelocInfo::CODE_TARGET);
2796 }
2797
2798 // static
2799 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2800 // ----------- S t a t e -------------
2801 // -- eax : the number of arguments (not including the receiver)
2802 // -- edx : the new target (either the same as the constructor or
2803 // the JSFunction on which new was invoked initially)
2804 // -- edi : the constructor to call (can be any Object)
2805 // -----------------------------------
2806
2807 // Free up some registers. 2679 // Free up some registers.
2808 __ movd(xmm0, edx); 2680 __ movd(xmm0, edx);
2809 __ movd(xmm1, edi); 2681 __ movd(xmm1, edi);
2810 2682
2811 Register argc = eax; 2683 Register argc = eax;
2812 2684
2813 Register scratch = ecx; 2685 Register scratch = ecx;
2814 Register scratch2 = edi; 2686 Register scratch2 = edi;
2815 2687
2816 Register spread = ebx; 2688 Register spread = ebx;
2817 Register spread_map = edx; 2689 Register spread_map = edx;
2818 2690
2691 Register spread_len = edx;
2692
2819 __ mov(spread, Operand(esp, kPointerSize)); 2693 __ mov(spread, Operand(esp, kPointerSize));
2820 __ mov(spread_map, FieldOperand(spread, HeapObject::kMapOffset)); 2694 __ mov(spread_map, FieldOperand(spread, HeapObject::kMapOffset));
2821 2695
2822 Label runtime_call, push_args; 2696 Label runtime_call, push_args;
2823 // Check that the spread is an array. 2697 // Check that the spread is an array.
2824 __ CmpInstanceType(spread_map, JS_ARRAY_TYPE); 2698 __ CmpInstanceType(spread_map, JS_ARRAY_TYPE);
2825 __ j(not_equal, &runtime_call); 2699 __ j(not_equal, &runtime_call);
2826 2700
2827 // Check that we have the original ArrayPrototype. 2701 // Check that we have the original ArrayPrototype.
2828 __ mov(scratch, FieldOperand(spread_map, Map::kPrototypeOffset)); 2702 __ mov(scratch, FieldOperand(spread_map, Map::kPrototypeOffset));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2861 __ j(equal, &no_protector_check); 2735 __ j(equal, &no_protector_check);
2862 __ cmp(scratch, Immediate(FAST_ELEMENTS)); 2736 __ cmp(scratch, Immediate(FAST_ELEMENTS));
2863 __ j(equal, &no_protector_check); 2737 __ j(equal, &no_protector_check);
2864 // Check the ArrayProtector cell. 2738 // Check the ArrayProtector cell.
2865 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex); 2739 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex);
2866 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset), 2740 __ cmp(FieldOperand(scratch, PropertyCell::kValueOffset),
2867 Immediate(Smi::FromInt(Isolate::kProtectorValid))); 2741 Immediate(Smi::FromInt(Isolate::kProtectorValid)));
2868 __ j(not_equal, &runtime_call); 2742 __ j(not_equal, &runtime_call);
2869 2743
2870 __ bind(&no_protector_check); 2744 __ bind(&no_protector_check);
2871 // Load the FixedArray backing store. 2745 // Load the FixedArray backing store, but use the length from the array.
2746 __ mov(spread_len, FieldOperand(spread, JSArray::kLengthOffset));
2747 __ SmiUntag(spread_len);
2872 __ mov(spread, FieldOperand(spread, JSArray::kElementsOffset)); 2748 __ mov(spread, FieldOperand(spread, JSArray::kElementsOffset));
2873 // Free up some registers.
2874 __ jmp(&push_args); 2749 __ jmp(&push_args);
2875 2750
2876 __ bind(&runtime_call); 2751 __ bind(&runtime_call);
2877 { 2752 {
2878 // Call the builtin for the result of the spread. 2753 // Call the builtin for the result of the spread.
2879 FrameScope scope(masm, StackFrame::INTERNAL); 2754 FrameScope scope(masm, StackFrame::INTERNAL);
2880 // Need to save these on the stack. 2755 // Need to save these on the stack.
2881 __ movd(edi, xmm1); 2756 __ movd(edi, xmm1);
2882 __ movd(edx, xmm0); 2757 __ movd(edx, xmm0);
2883 __ Push(edi); 2758 __ Push(edi);
2884 __ Push(edx); 2759 __ Push(edx);
2885 __ SmiTag(argc); 2760 __ SmiTag(argc);
2886 __ Push(argc); 2761 __ Push(argc);
2887 __ Push(spread); 2762 __ Push(spread);
2888 __ CallRuntime(Runtime::kSpreadIterableFixed); 2763 __ CallRuntime(Runtime::kSpreadIterableFixed);
2889 __ mov(spread, eax); 2764 __ mov(spread, eax);
2890 __ Pop(argc); 2765 __ Pop(argc);
2891 __ SmiUntag(argc); 2766 __ SmiUntag(argc);
2892 __ Pop(edx); 2767 __ Pop(edx);
2893 __ Pop(edi); 2768 __ Pop(edi);
2894 // Free up some registers. 2769 // Free up some registers.
2895 __ movd(xmm0, edx); 2770 __ movd(xmm0, edx);
2896 __ movd(xmm1, edi); 2771 __ movd(xmm1, edi);
2897 } 2772 }
2898 2773
2899 Register spread_len = edx;
2900 Register return_address = edi; 2774 Register return_address = edi;
2901 __ bind(&push_args);
2902 { 2775 {
2776 // Calculate the new nargs including the result of the spread.
2777 __ mov(spread_len, FieldOperand(spread, FixedArray::kLengthOffset));
2778 __ SmiUntag(spread_len);
2779
2780 __ bind(&push_args);
2781 // argc += spread_len - 1. Subtract 1 for the spread itself.
2782 __ lea(argc, Operand(argc, spread_len, times_1, -1));
2783
2903 // Pop the return address and spread argument. 2784 // Pop the return address and spread argument.
2904 __ PopReturnAddressTo(return_address); 2785 __ PopReturnAddressTo(return_address);
2905 __ Pop(scratch); 2786 __ Pop(scratch);
2906
2907 // Calculate the new nargs including the result of the spread.
2908 __ mov(spread_len, FieldOperand(spread, FixedArray::kLengthOffset));
2909 __ SmiUntag(spread_len);
2910 // argc += spread_len - 1. Subtract 1 for the spread itself.
2911 __ lea(argc, Operand(argc, spread_len, times_1, -1));
2912 } 2787 }
2913 2788
2914 // Check for stack overflow. 2789 // Check for stack overflow.
2915 { 2790 {
2916 // Check the stack for overflow. We are not trying to catch interruptions 2791 // Check the stack for overflow. We are not trying to catch interruptions
2917 // (i.e. debug break and preemption) here, so check the "real stack limit". 2792 // (i.e. debug break and preemption) here, so check the "real stack limit".
2918 Label done; 2793 Label done;
2919 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex); 2794 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
2920 // Make scratch the space we have left. The stack might already be 2795 // Make scratch the space we have left. The stack might already be
2921 // overflowed here which will cause scratch to become negative. 2796 // overflowed here which will cause scratch to become negative.
(...skipping 21 matching lines...) Expand all
2943 FixedArray::kHeaderSize)); 2818 FixedArray::kHeaderSize));
2944 __ Push(scratch2); 2819 __ Push(scratch2);
2945 __ inc(scratch); 2820 __ inc(scratch);
2946 __ jmp(&loop); 2821 __ jmp(&loop);
2947 __ bind(&done); 2822 __ bind(&done);
2948 __ PushReturnAddressFrom(return_address); 2823 __ PushReturnAddressFrom(return_address);
2949 __ movd(esi, xmm2); 2824 __ movd(esi, xmm2);
2950 __ movd(edi, xmm1); 2825 __ movd(edi, xmm1);
2951 __ movd(edx, xmm0); 2826 __ movd(edx, xmm0);
2952 } 2827 }
2828 }
2953 2829
2954 // Dispatch. 2830 // static
2831 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) {
2832 // ----------- S t a t e -------------
2833 // -- eax : the number of arguments (not including the receiver)
2834 // -- edi : the target to call (can be any Object)
2835 // -----------------------------------
2836
2837 // CheckSpreadAndPushToStack will push edx to save it.
2838 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
2839 CheckSpreadAndPushToStack(masm);
2840 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2841 TailCallMode::kDisallow),
2842 RelocInfo::CODE_TARGET);
2843 }
2844
2845 // static
2846 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2847 // ----------- S t a t e -------------
2848 // -- eax : the number of arguments (not including the receiver)
2849 // -- edx : the new target (checked to be a constructor)
2850 // -- edi : the constructor to call (checked to be a JSFunction)
2851 // -----------------------------------
2852 __ AssertFunction(edi);
2853
2854 // Calling convention for function specific ConstructStubs require
2855 // ebx to contain either an AllocationSite or undefined.
2856 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
2857
2858 // Tail call to the function-specific construct stub (still in the caller
2859 // context at this point).
2860 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2861 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
2862 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2863 __ jmp(ecx);
2864 }
2865
2866 // static
2867 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2868 // ----------- S t a t e -------------
2869 // -- eax : the number of arguments (not including the receiver)
2870 // -- edx : the new target (checked to be a constructor)
2871 // -- edi : the constructor to call (checked to be a JSBoundFunction)
2872 // -----------------------------------
2873 __ AssertBoundFunction(edi);
2874
2875 // Push the [[BoundArguments]] onto the stack.
2876 Generate_PushBoundArguments(masm);
2877
2878 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2879 {
2880 Label done;
2881 __ cmp(edi, edx);
2882 __ j(not_equal, &done, Label::kNear);
2883 __ mov(edx, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2884 __ bind(&done);
2885 }
2886
2887 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2888 __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
2889 __ mov(ecx, Operand::StaticVariable(
2890 ExternalReference(Builtins::kConstruct, masm->isolate())));
2891 __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
2892 __ jmp(ecx);
2893 }
2894
2895 // static
2896 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2897 // ----------- S t a t e -------------
2898 // -- eax : the number of arguments (not including the receiver)
2899 // -- edi : the constructor to call (checked to be a JSProxy)
2900 // -- edx : the new target (either the same as the constructor or
2901 // the JSFunction on which new was invoked initially)
2902 // -----------------------------------
2903
2904 // Call into the Runtime for Proxy [[Construct]].
2905 __ PopReturnAddressTo(ecx);
2906 __ Push(edi);
2907 __ Push(edx);
2908 __ PushReturnAddressFrom(ecx);
2909 // Include the pushed new_target, constructor and the receiver.
2910 __ add(eax, Immediate(3));
2911 // Tail-call to the runtime.
2912 __ JumpToExternalReference(
2913 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2914 }
2915
2916 // static
2917 void Builtins::Generate_Construct(MacroAssembler* masm) {
2918 // ----------- S t a t e -------------
2919 // -- eax : the number of arguments (not including the receiver)
2920 // -- edx : the new target (either the same as the constructor or
2921 // the JSFunction on which new was invoked initially)
2922 // -- edi : the constructor to call (can be any Object)
2923 // -----------------------------------
2924
2925 // Check if target is a Smi.
2926 Label non_constructor;
2927 __ JumpIfSmi(edi, &non_constructor, Label::kNear);
2928
2929 // Dispatch based on instance type.
2930 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2931 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2932 RelocInfo::CODE_TARGET);
2933
2934 // Check if target has a [[Construct]] internal method.
2935 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2936 Immediate(1 << Map::kIsConstructor));
2937 __ j(zero, &non_constructor, Label::kNear);
2938
2939 // Only dispatch to bound functions after checking whether they are
2940 // constructors.
2941 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2942 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2943 RelocInfo::CODE_TARGET);
2944
2945 // Only dispatch to proxies after checking whether they are constructors.
2946 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2947 __ j(equal, masm->isolate()->builtins()->ConstructProxy(),
2948 RelocInfo::CODE_TARGET);
2949
2950 // Called Construct on an exotic Object with a [[Construct]] internal method.
2951 {
2952 // Overwrite the original receiver with the (original) target.
2953 __ mov(Operand(esp, eax, times_pointer_size, kPointerSize), edi);
2954 // Let the "call_as_constructor_delegate" take care of the rest.
2955 __ LoadGlobalFunction(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, edi);
2956 __ Jump(masm->isolate()->builtins()->CallFunction(),
2957 RelocInfo::CODE_TARGET);
2958 }
2959
2960 // Called Construct on an Object that doesn't have a [[Construct]] internal
2961 // method.
2962 __ bind(&non_constructor);
2963 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2964 RelocInfo::CODE_TARGET);
2965 }
2966
2967 // static
2968 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2969 // ----------- S t a t e -------------
2970 // -- eax : the number of arguments (not including the receiver)
2971 // -- edx : the new target (either the same as the constructor or
2972 // the JSFunction on which new was invoked initially)
2973 // -- edi : the constructor to call (can be any Object)
2974 // -----------------------------------
2975
2976 CheckSpreadAndPushToStack(masm);
2955 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2977 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2956 } 2978 }
2957 2979
2958 // static 2980 // static
2959 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) { 2981 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
2960 // ----------- S t a t e ------------- 2982 // ----------- S t a t e -------------
2961 // -- edx : requested object size (untagged) 2983 // -- edx : requested object size (untagged)
2962 // -- esp[0] : return address 2984 // -- esp[0] : return address
2963 // ----------------------------------- 2985 // -----------------------------------
2964 __ SmiTag(edx); 2986 __ SmiTag(edx);
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
3270 3292
3271 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) { 3293 void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
3272 Generate_OnStackReplacementHelper(masm, true); 3294 Generate_OnStackReplacementHelper(masm, true);
3273 } 3295 }
3274 3296
3275 #undef __ 3297 #undef __
3276 } // namespace internal 3298 } // namespace internal
3277 } // namespace v8 3299 } // namespace v8
3278 3300
3279 #endif // V8_TARGET_ARCH_IA32 3301 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/builtins/builtins-interpreter.cc ('k') | src/builtins/mips/builtins-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698