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

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

Issue 2649143002: [Turbofan] Implement call with spread bytecode in assembly code. (Closed)
Patch Set: Mips ports 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 | « no previous file | src/builtins/arm64/builtins-arm64.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_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/debug/debug.h" 8 #include "src/debug/debug.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 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 __ bind(&loop_header); 1140 __ bind(&loop_header);
1141 __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex)); 1141 __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
1142 __ push(scratch); 1142 __ push(scratch);
1143 __ bind(&loop_check); 1143 __ bind(&loop_check);
1144 __ cmp(index, limit); 1144 __ cmp(index, limit);
1145 __ b(gt, &loop_header); 1145 __ b(gt, &loop_header);
1146 } 1146 }
1147 1147
1148 // static 1148 // static
1149 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 1149 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1150 MacroAssembler* masm, TailCallMode tail_call_mode, 1150 MacroAssembler* masm, TailCallMode tail_call_mode, PushArgsMode mode) {
rmcilroy 2017/01/23 15:38:44 nit - I'm not sure on the name, it seems a bit too
1151 CallableType function_type) {
1152 // ----------- S t a t e ------------- 1151 // ----------- S t a t e -------------
1153 // -- r0 : the number of arguments (not including the receiver) 1152 // -- r0 : the number of arguments (not including the receiver)
1154 // -- r2 : the address of the first argument to be pushed. Subsequent 1153 // -- r2 : the address of the first argument to be pushed. Subsequent
1155 // arguments should be consecutive above this, in the same order as 1154 // arguments should be consecutive above this, in the same order as
1156 // they are to be pushed onto the stack. 1155 // they are to be pushed onto the stack.
1157 // -- r1 : the target to call (can be any Object). 1156 // -- r1 : the target to call (can be any Object).
1158 // ----------------------------------- 1157 // -----------------------------------
1159 Label stack_overflow; 1158 Label stack_overflow;
1160 1159
1161 __ add(r3, r0, Operand(1)); // Add one for receiver. 1160 __ add(r3, r0, Operand(1)); // Add one for receiver.
1162 1161
1163 // Push the arguments. r2, r4, r5 will be modified. 1162 // Push the arguments. r2, r4, r5 will be modified.
1164 Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow); 1163 Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow);
1165 1164
1166 // Call the target. 1165 // Call the target.
1167 if (function_type == CallableType::kJSFunction) { 1166 if (mode == PushArgsMode::kJSFunction) {
1168 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 1167 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
1169 tail_call_mode), 1168 tail_call_mode),
1170 RelocInfo::CODE_TARGET); 1169 RelocInfo::CODE_TARGET);
1170 } else if (mode == PushArgsMode::kWithFinalSpread) {
1171 __ Jump(masm->isolate()->builtins()->CallWithSpread(),
1172 RelocInfo::CODE_TARGET);
1171 } else { 1173 } else {
1172 DCHECK_EQ(function_type, CallableType::kAny);
1173 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 1174 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1174 tail_call_mode), 1175 tail_call_mode),
1175 RelocInfo::CODE_TARGET); 1176 RelocInfo::CODE_TARGET);
1176 } 1177 }
1177 1178
1178 __ bind(&stack_overflow); 1179 __ bind(&stack_overflow);
1179 { 1180 {
1180 __ TailCallRuntime(Runtime::kThrowStackOverflow); 1181 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1181 // Unreachable code. 1182 // Unreachable code.
1182 __ bkpt(0); 1183 __ bkpt(0);
1183 } 1184 }
1184 } 1185 }
1185 1186
1186 // static 1187 // static
1187 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 1188 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1188 MacroAssembler* masm, PushArgsConstructMode mode) { 1189 MacroAssembler* masm, PushArgsMode mode) {
1189 // ----------- S t a t e ------------- 1190 // ----------- S t a t e -------------
1190 // -- r0 : argument count (not including receiver) 1191 // -- r0 : argument count (not including receiver)
1191 // -- r3 : new target 1192 // -- r3 : new target
1192 // -- r1 : constructor to call 1193 // -- r1 : constructor to call
1193 // -- r2 : allocation site feedback if available, undefined otherwise. 1194 // -- r2 : allocation site feedback if available, undefined otherwise.
1194 // -- r4 : address of the first argument 1195 // -- r4 : address of the first argument
1195 // ----------------------------------- 1196 // -----------------------------------
1196 Label stack_overflow; 1197 Label stack_overflow;
1197 1198
1198 // Push a slot for the receiver to be constructed. 1199 // Push a slot for the receiver to be constructed.
1199 __ mov(ip, Operand::Zero()); 1200 __ mov(ip, Operand::Zero());
1200 __ push(ip); 1201 __ push(ip);
1201 1202
1202 // Push the arguments. r5, r4, r6 will be modified. 1203 // Push the arguments. r5, r4, r6 will be modified.
1203 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow); 1204 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow);
1204 1205
1205 __ AssertUndefinedOrAllocationSite(r2, r5); 1206 __ AssertUndefinedOrAllocationSite(r2, r5);
1206 if (mode == PushArgsConstructMode::kJSFunction) { 1207 if (mode == PushArgsMode::kJSFunction) {
1207 __ AssertFunction(r1); 1208 __ AssertFunction(r1);
1208 1209
1209 // Tail call to the function-specific construct stub (still in the caller 1210 // Tail call to the function-specific construct stub (still in the caller
1210 // context at this point). 1211 // context at this point).
1211 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1212 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1212 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); 1213 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1213 // Jump to the construct function. 1214 // Jump to the construct function.
1214 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); 1215 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1215 } else if (mode == PushArgsConstructMode::kWithFinalSpread) { 1216 } else if (mode == PushArgsMode::kWithFinalSpread) {
1216 // Call the constructor with r0, r1, and r3 unmodified. 1217 // Call the constructor with r0, r1, and r3 unmodified.
1217 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(), 1218 __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
1218 RelocInfo::CODE_TARGET); 1219 RelocInfo::CODE_TARGET);
1219 } else { 1220 } else {
1220 DCHECK_EQ(PushArgsConstructMode::kOther, mode); 1221 DCHECK_EQ(PushArgsMode::kOther, mode);
1221 // Call the constructor with r0, r1, and r3 unmodified. 1222 // Call the constructor with r0, r1, and r3 unmodified.
1222 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1223 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1223 } 1224 }
1224 1225
1225 __ bind(&stack_overflow); 1226 __ bind(&stack_overflow);
1226 { 1227 {
1227 __ TailCallRuntime(Runtime::kThrowStackOverflow); 1228 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1228 // Unreachable code. 1229 // Unreachable code.
1229 __ bkpt(0); 1230 __ bkpt(0);
1230 } 1231 }
(...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after
2610 2611
2611 // 3. Call to something that is not callable. 2612 // 3. Call to something that is not callable.
2612 __ bind(&non_callable); 2613 __ bind(&non_callable);
2613 { 2614 {
2614 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 2615 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2615 __ Push(r1); 2616 __ Push(r1);
2616 __ CallRuntime(Runtime::kThrowCalledNonCallable); 2617 __ CallRuntime(Runtime::kThrowCalledNonCallable);
2617 } 2618 }
2618 } 2619 }
2619 2620
2620 // static 2621 static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
2621 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2622 // ----------- S t a t e -------------
2623 // -- r0 : the number of arguments (not including the receiver)
2624 // -- r1 : the constructor to call (checked to be a JSFunction)
2625 // -- r3 : the new target (checked to be a constructor)
2626 // -----------------------------------
2627 __ AssertFunction(r1);
2628
2629 // Calling convention for function specific ConstructStubs require
2630 // r2 to contain either an AllocationSite or undefined.
2631 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2632
2633 // Tail call to the function-specific construct stub (still in the caller
2634 // context at this point).
2635 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2636 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
2637 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
2638 }
2639
2640 // static
2641 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2642 // ----------- S t a t e -------------
2643 // -- r0 : the number of arguments (not including the receiver)
2644 // -- r1 : the function to call (checked to be a JSBoundFunction)
2645 // -- r3 : the new target (checked to be a constructor)
2646 // -----------------------------------
2647 __ AssertBoundFunction(r1);
2648
2649 // Push the [[BoundArguments]] onto the stack.
2650 Generate_PushBoundArguments(masm);
2651
2652 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2653 __ cmp(r1, r3);
2654 __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset),
2655 eq);
2656
2657 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2658 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2659 __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
2660 __ ldr(ip, MemOperand(ip));
2661 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2662 }
2663
2664 // static
2665 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2666 // ----------- S t a t e -------------
2667 // -- r0 : the number of arguments (not including the receiver)
2668 // -- r1 : the constructor to call (checked to be a JSProxy)
2669 // -- r3 : the new target (either the same as the constructor or
2670 // the JSFunction on which new was invoked initially)
2671 // -----------------------------------
2672
2673 // Call into the Runtime for Proxy [[Construct]].
2674 __ Push(r1);
2675 __ Push(r3);
2676 // Include the pushed new_target, constructor and the receiver.
2677 __ add(r0, r0, Operand(3));
2678 // Tail-call to the runtime.
2679 __ JumpToExternalReference(
2680 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2681 }
2682
2683 // static
2684 void Builtins::Generate_Construct(MacroAssembler* masm) {
2685 // ----------- S t a t e -------------
2686 // -- r0 : the number of arguments (not including the receiver)
2687 // -- r1 : the constructor to call (can be any Object)
2688 // -- r3 : the new target (either the same as the constructor or
2689 // the JSFunction on which new was invoked initially)
2690 // -----------------------------------
2691
2692 // Check if target is a Smi.
2693 Label non_constructor;
2694 __ JumpIfSmi(r1, &non_constructor);
2695
2696 // Dispatch based on instance type.
2697 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2698 __ Jump(masm->isolate()->builtins()->ConstructFunction(),
2699 RelocInfo::CODE_TARGET, eq);
2700
2701 // Check if target has a [[Construct]] internal method.
2702 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
2703 __ tst(r2, Operand(1 << Map::kIsConstructor));
2704 __ b(eq, &non_constructor);
2705
2706 // Only dispatch to bound functions after checking whether they are
2707 // constructors.
2708 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2709 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
2710 RelocInfo::CODE_TARGET, eq);
2711
2712 // Only dispatch to proxies after checking whether they are constructors.
2713 __ cmp(r5, Operand(JS_PROXY_TYPE));
2714 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
2715 eq);
2716
2717 // Called Construct on an exotic Object with a [[Construct]] internal method.
2718 {
2719 // Overwrite the original receiver with the (original) target.
2720 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2721 // Let the "call_as_constructor_delegate" take care of the rest.
2722 __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, r1);
2723 __ Jump(masm->isolate()->builtins()->CallFunction(),
2724 RelocInfo::CODE_TARGET);
2725 }
2726
2727 // Called Construct on an Object that doesn't have a [[Construct]] internal
2728 // method.
2729 __ bind(&non_constructor);
2730 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2731 RelocInfo::CODE_TARGET);
2732 }
2733
2734 // static
2735 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2736 // ----------- S t a t e -------------
2737 // -- r0 : the number of arguments (not including the receiver)
2738 // -- r1 : the constructor to call (can be any Object)
2739 // -- r3 : the new target (either the same as the constructor or
2740 // the JSFunction on which new was invoked initially)
2741 // -----------------------------------
2742
2743 Register argc = r0; 2622 Register argc = r0;
2744 Register constructor = r1; 2623 Register constructor = r1;
2745 Register new_target = r3; 2624 Register new_target = r3;
2746 2625
2747 Register scratch = r2; 2626 Register scratch = r2;
2748 Register scratch2 = r6; 2627 Register scratch2 = r6;
2749 2628
2750 Register spread = r4; 2629 Register spread = r4;
2751 Register spread_map = r5; 2630 Register spread_map = r5;
2631
2632 Register spread_len = r5;
2633
2752 __ ldr(spread, MemOperand(sp, 0)); 2634 __ ldr(spread, MemOperand(sp, 0));
2753 __ ldr(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset)); 2635 __ ldr(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
2754 2636
2755 Label runtime_call, push_args; 2637 Label runtime_call, push_args;
2756 // Check that the spread is an array. 2638 // Check that the spread is an array.
2757 __ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE); 2639 __ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE);
2758 __ b(ne, &runtime_call); 2640 __ b(ne, &runtime_call);
2759 2641
2760 // Check that we have the original ArrayPrototype. 2642 // Check that we have the original ArrayPrototype.
2761 __ ldr(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset)); 2643 __ ldr(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2796 __ b(eq, &no_protector_check); 2678 __ b(eq, &no_protector_check);
2797 __ cmp(scratch, Operand(FAST_ELEMENTS)); 2679 __ cmp(scratch, Operand(FAST_ELEMENTS));
2798 __ b(eq, &no_protector_check); 2680 __ b(eq, &no_protector_check);
2799 // Check the ArrayProtector cell. 2681 // Check the ArrayProtector cell.
2800 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex); 2682 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex);
2801 __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); 2683 __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
2802 __ cmp(scratch, Operand(Smi::FromInt(Isolate::kProtectorValid))); 2684 __ cmp(scratch, Operand(Smi::FromInt(Isolate::kProtectorValid)));
2803 __ b(ne, &runtime_call); 2685 __ b(ne, &runtime_call);
2804 2686
2805 __ bind(&no_protector_check); 2687 __ bind(&no_protector_check);
2806 // Load the FixedArray backing store. 2688 // Load the FixedArray backing store, but use the length from the array.
2689 __ ldr(spread_len, FieldMemOperand(spread, JSArray::kLengthOffset));
2690 __ SmiUntag(spread_len);
2807 __ ldr(spread, FieldMemOperand(spread, JSArray::kElementsOffset)); 2691 __ ldr(spread, FieldMemOperand(spread, JSArray::kElementsOffset));
2808 __ b(&push_args); 2692 __ b(&push_args);
2809 2693
2810 __ bind(&runtime_call); 2694 __ bind(&runtime_call);
2811 { 2695 {
2812 // Call the builtin for the result of the spread. 2696 // Call the builtin for the result of the spread.
2813 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 2697 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2814 __ SmiTag(argc); 2698 __ SmiTag(argc);
2815 __ Push(constructor); 2699 __ Push(constructor);
2816 __ Push(new_target); 2700 __ Push(new_target);
2817 __ Push(argc); 2701 __ Push(argc);
2818 __ Push(spread); 2702 __ Push(spread);
2819 __ CallRuntime(Runtime::kSpreadIterableFixed); 2703 __ CallRuntime(Runtime::kSpreadIterableFixed);
2820 __ mov(spread, r0); 2704 __ mov(spread, r0);
2821 __ Pop(argc); 2705 __ Pop(argc);
2822 __ Pop(new_target); 2706 __ Pop(new_target);
2823 __ Pop(constructor); 2707 __ Pop(constructor);
2824 __ SmiUntag(argc); 2708 __ SmiUntag(argc);
2825 } 2709 }
2826 2710
2827 Register spread_len = r5;
2828 __ bind(&push_args);
2829 { 2711 {
2830 // Pop the spread argument off the stack.
2831 __ Pop(scratch);
2832 // Calculate the new nargs including the result of the spread. 2712 // Calculate the new nargs including the result of the spread.
2833 __ ldr(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset)); 2713 __ ldr(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset));
2834 __ SmiUntag(spread_len); 2714 __ SmiUntag(spread_len);
2715
2716 __ bind(&push_args);
2835 // argc += spread_len - 1. Subtract 1 for the spread itself. 2717 // argc += spread_len - 1. Subtract 1 for the spread itself.
2836 __ add(argc, argc, spread_len); 2718 __ add(argc, argc, spread_len);
2837 __ sub(argc, argc, Operand(1)); 2719 __ sub(argc, argc, Operand(1));
2720
2721 // Pop the spread argument off the stack.
2722 __ Pop(scratch);
2838 } 2723 }
2839 2724
2840 // Check for stack overflow. 2725 // Check for stack overflow.
2841 { 2726 {
2842 // Check the stack for overflow. We are not trying to catch interruptions 2727 // Check the stack for overflow. We are not trying to catch interruptions
2843 // (i.e. debug break and preemption) here, so check the "real stack limit". 2728 // (i.e. debug break and preemption) here, so check the "real stack limit".
2844 Label done; 2729 Label done;
2845 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex); 2730 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
2846 // Make scratch the space we have left. The stack might already be 2731 // Make scratch the space we have left. The stack might already be
2847 // overflowed here which will cause scratch to become negative. 2732 // overflowed here which will cause scratch to become negative.
(...skipping 12 matching lines...) Expand all
2860 __ bind(&loop); 2745 __ bind(&loop);
2861 __ cmp(scratch, spread_len); 2746 __ cmp(scratch, spread_len);
2862 __ b(eq, &done); 2747 __ b(eq, &done);
2863 __ add(scratch2, spread, Operand(scratch, LSL, kPointerSizeLog2)); 2748 __ add(scratch2, spread, Operand(scratch, LSL, kPointerSizeLog2));
2864 __ ldr(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize)); 2749 __ ldr(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize));
2865 __ Push(scratch2); 2750 __ Push(scratch2);
2866 __ add(scratch, scratch, Operand(1)); 2751 __ add(scratch, scratch, Operand(1));
2867 __ b(&loop); 2752 __ b(&loop);
2868 __ bind(&done); 2753 __ bind(&done);
2869 } 2754 }
2755 }
2870 2756
2871 // Dispatch. 2757 // static
2758 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) {
2759 // ----------- S t a t e -------------
2760 // -- r0 : the number of arguments (not including the receiver)
2761 // -- r1 : the constructor to call (can be any Object)
2762 // -----------------------------------
2763
2764 // CheckSpreadAndPushToStack will push r3 to save it.
2765 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
2766 CheckSpreadAndPushToStack(masm);
2767 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2768 TailCallMode::kDisallow),
2769 RelocInfo::CODE_TARGET);
2770 }
2771
2772 // static
2773 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2774 // ----------- S t a t e -------------
2775 // -- r0 : the number of arguments (not including the receiver)
2776 // -- r1 : the constructor to call (checked to be a JSFunction)
2777 // -- r3 : the new target (checked to be a constructor)
2778 // -----------------------------------
2779 __ AssertFunction(r1);
2780
2781 // Calling convention for function specific ConstructStubs require
2782 // r2 to contain either an AllocationSite or undefined.
2783 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2784
2785 // Tail call to the function-specific construct stub (still in the caller
2786 // context at this point).
2787 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2788 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
2789 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
2790 }
2791
2792 // static
2793 void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2794 // ----------- S t a t e -------------
2795 // -- r0 : the number of arguments (not including the receiver)
2796 // -- r1 : the function to call (checked to be a JSBoundFunction)
2797 // -- r3 : the new target (checked to be a constructor)
2798 // -----------------------------------
2799 __ AssertBoundFunction(r1);
2800
2801 // Push the [[BoundArguments]] onto the stack.
2802 Generate_PushBoundArguments(masm);
2803
2804 // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2805 __ cmp(r1, r3);
2806 __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset),
2807 eq);
2808
2809 // Construct the [[BoundTargetFunction]] via the Construct builtin.
2810 __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2811 __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
2812 __ ldr(ip, MemOperand(ip));
2813 __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2814 }
2815
2816 // static
2817 void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2818 // ----------- S t a t e -------------
2819 // -- r0 : the number of arguments (not including the receiver)
2820 // -- r1 : the constructor to call (checked to be a JSProxy)
2821 // -- r3 : the new target (either the same as the constructor or
2822 // the JSFunction on which new was invoked initially)
2823 // -----------------------------------
2824
2825 // Call into the Runtime for Proxy [[Construct]].
2826 __ Push(r1);
2827 __ Push(r3);
2828 // Include the pushed new_target, constructor and the receiver.
2829 __ add(r0, r0, Operand(3));
2830 // Tail-call to the runtime.
2831 __ JumpToExternalReference(
2832 ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2833 }
2834
2835 // static
2836 void Builtins::Generate_Construct(MacroAssembler* masm) {
2837 // ----------- S t a t e -------------
2838 // -- r0 : the number of arguments (not including the receiver)
2839 // -- r1 : the constructor to call (can be any Object)
2840 // -- r3 : the new target (either the same as the constructor or
2841 // the JSFunction on which new was invoked initially)
2842 // -----------------------------------
2843
2844 // Check if target is a Smi.
2845 Label non_constructor;
2846 __ JumpIfSmi(r1, &non_constructor);
2847
2848 // Dispatch based on instance type.
2849 __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2850 __ Jump(masm->isolate()->builtins()->ConstructFunction(),
2851 RelocInfo::CODE_TARGET, eq);
2852
2853 // Check if target has a [[Construct]] internal method.
2854 __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
2855 __ tst(r2, Operand(1 << Map::kIsConstructor));
2856 __ b(eq, &non_constructor);
2857
2858 // Only dispatch to bound functions after checking whether they are
2859 // constructors.
2860 __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2861 __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
2862 RelocInfo::CODE_TARGET, eq);
2863
2864 // Only dispatch to proxies after checking whether they are constructors.
2865 __ cmp(r5, Operand(JS_PROXY_TYPE));
2866 __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
2867 eq);
2868
2869 // Called Construct on an exotic Object with a [[Construct]] internal method.
2870 {
2871 // Overwrite the original receiver with the (original) target.
2872 __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2873 // Let the "call_as_constructor_delegate" take care of the rest.
2874 __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, r1);
2875 __ Jump(masm->isolate()->builtins()->CallFunction(),
2876 RelocInfo::CODE_TARGET);
2877 }
2878
2879 // Called Construct on an Object that doesn't have a [[Construct]] internal
2880 // method.
2881 __ bind(&non_constructor);
2882 __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2883 RelocInfo::CODE_TARGET);
2884 }
2885
2886 // static
2887 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2888 // ----------- S t a t e -------------
2889 // -- r0 : the number of arguments (not including the receiver)
2890 // -- r1 : the constructor to call (can be any Object)
2891 // -- r3 : the new target (either the same as the constructor or
2892 // the JSFunction on which new was invoked initially)
2893 // -----------------------------------
2894
2895 CheckSpreadAndPushToStack(masm);
2872 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 2896 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2873 } 2897 }
2874 2898
2875 // static 2899 // static
2876 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) { 2900 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
2877 // ----------- S t a t e ------------- 2901 // ----------- S t a t e -------------
2878 // -- r1 : requested object size (untagged) 2902 // -- r1 : requested object size (untagged)
2879 // -- lr : return address 2903 // -- lr : return address
2880 // ----------------------------------- 2904 // -----------------------------------
2881 __ SmiTag(r1); 2905 __ SmiTag(r1);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
3030 __ bkpt(0); 3054 __ bkpt(0);
3031 } 3055 }
3032 } 3056 }
3033 3057
3034 #undef __ 3058 #undef __
3035 3059
3036 } // namespace internal 3060 } // namespace internal
3037 } // namespace v8 3061 } // namespace v8
3038 3062
3039 #endif // V8_TARGET_ARCH_ARM 3063 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/builtins/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698