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

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

Issue 2938603002: [arm64] Make ArgumentsAdaptorTrampoline maintain 16-byte stack alignment. (Closed)
Patch Set: Created 3 years, 6 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 | no next file » | 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_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/arm64/macro-assembler-arm64-inl.h" 8 #include "src/arm64/macro-assembler-arm64-inl.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/counters.h" 10 #include "src/counters.h"
(...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 2217
2218 // 4c. The new.target is not a constructor, throw an appropriate TypeError. 2218 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2219 __ Bind(&new_target_not_constructor); 2219 __ Bind(&new_target_not_constructor);
2220 { 2220 {
2221 __ Poke(new_target, 0); 2221 __ Poke(new_target, 0);
2222 __ TailCallRuntime(Runtime::kThrowNotConstructor); 2222 __ TailCallRuntime(Runtime::kThrowNotConstructor);
2223 } 2223 }
2224 } 2224 }
2225 2225
2226 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 2226 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2227 __ SmiTag(x10, x0); 2227 __ Push(lr, fp);
2228 __ Mov(x11, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)); 2228 __ Mov(x11, StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR));
2229 __ Push(lr, fp); 2229 __ Push(x11, x1); // x1: function
2230 __ Push(x11, x1, x10); 2230 // We do not yet push the number of arguments, to maintain a 16-byte aligned
2231 __ Add(fp, jssp, 2231 // stack pointer. This is done in step (3) in
2232 StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); 2232 // Generate_ArgumentsAdaptorTrampoline.
2233 __ Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp);
2233 } 2234 }
2234 2235
2235 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { 2236 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
2236 // ----------- S t a t e ------------- 2237 // ----------- S t a t e -------------
2237 // -- x0 : result being passed through 2238 // -- x0 : result being passed through
2238 // ----------------------------------- 2239 // -----------------------------------
2239 // Get the number of arguments passed (as a smi), tear down the frame and 2240 // Get the number of arguments passed (as a smi), tear down the frame and
2240 // then drop the parameters and the receiver. 2241 // then drop the parameters and the receiver.
2241 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 2242 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
2242 kPointerSize))); 2243 kPointerSize)));
2243 __ Mov(jssp, fp); 2244 __ Mov(jssp, fp);
2244 __ Pop(fp, lr); 2245 __ Pop(fp, lr);
2246
2247 // Drop actual parameters and receiver.
2248 // TODO(all): This will need to be rounded up to a multiple of two when using
2249 // the CSP, as we will have claimed an even number of slots in total for the
2250 // parameters.
2245 __ DropBySMI(x10, kXRegSize); 2251 __ DropBySMI(x10, kXRegSize);
2246 __ Drop(1); 2252 __ Drop(1);
2247 } 2253 }
2248 2254
2249 // static 2255 // static
2250 void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm, 2256 void Builtins::Generate_CallOrConstructVarargs(MacroAssembler* masm,
2251 Handle<Code> code) { 2257 Handle<Code> code) {
2252 // ----------- S t a t e ------------- 2258 // ----------- S t a t e -------------
2253 // -- x1 : target 2259 // -- x1 : target
2254 // -- x0 : number of parameters on the stack (not including the receiver) 2260 // -- x0 : number of parameters on the stack (not including the receiver)
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
3057 3063
3058 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 3064 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
3059 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); 3065 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
3060 // ----------- S t a t e ------------- 3066 // ----------- S t a t e -------------
3061 // -- x0 : actual number of arguments 3067 // -- x0 : actual number of arguments
3062 // -- x1 : function (passed through to callee) 3068 // -- x1 : function (passed through to callee)
3063 // -- x2 : expected number of arguments 3069 // -- x2 : expected number of arguments
3064 // -- x3 : new target (passed through to callee) 3070 // -- x3 : new target (passed through to callee)
3065 // ----------------------------------- 3071 // -----------------------------------
3066 3072
3073 // The frame we are about to construct will look like:
3074 //
3075 // slot Adaptor frame
3076 // +-----------------+--------------------------------
3077 // -n-1 | receiver | ^
3078 // | (parameter 0) | |
3079 // |- - - - - - - - -| |
3080 // -n | | Caller
3081 // ... | ... | frame slots --> actual args
3082 // -2 | parameter n-1 | |
3083 // |- - - - - - - - -| |
3084 // -1 | parameter n | v
3085 // -----+-----------------+--------------------------------
3086 // 0 | return addr | ^
3087 // |- - - - - - - - -| |
3088 // 1 | saved frame ptr | <-- frame ptr |
3089 // |- - - - - - - - -| |
3090 // 2 |Frame Type Marker| |
3091 // |- - - - - - - - -| |
3092 // 3 | function | Callee
3093 // |- - - - - - - - -| frame slots
3094 // 4 | num of | |
3095 // | actual args | |
3096 // |- - - - - - - - -| |
3097 // [5] | [padding] | |
3098 // |-----------------+---- |
3099 // 5+pad | receiver | ^ |
3100 // | (parameter 0) | | |
3101 // |- - - - - - - - -| | |
3102 // 6+pad | parameter 1 | | |
3103 // |- - - - - - - - -| Frame slots ----> expected args
3104 // 7+pad | parameter 2 | | |
3105 // |- - - - - - - - -| | |
3106 // | | | |
3107 // ... | ... | | |
3108 // | parameter m | | |
3109 // |- - - - - - - - -| | |
3110 // | [undefined] | | |
3111 // |- - - - - - - - -| | |
3112 // | | | |
3113 // | ... | | |
3114 // | [undefined] | v <-- stack ptr v
3115 // -----+-----------------+---------------------------------
3116 //
3117 // There is an optional slot of padding to ensure stack alignment.
3118 // If the number of expected arguments is larger than the number of actual
3119 // arguments, the remaining expected slots will be filled with undefined.
3120
3067 Register argc_actual = x0; // Excluding the receiver. 3121 Register argc_actual = x0; // Excluding the receiver.
3068 Register argc_expected = x2; // Excluding the receiver. 3122 Register argc_expected = x2; // Excluding the receiver.
3069 Register function = x1; 3123 Register function = x1;
3070 Register code_entry = x10; 3124 Register code_entry = x10;
3071 3125
3072 Label invoke, dont_adapt_arguments, stack_overflow; 3126 Label dont_adapt_arguments, stack_overflow;
3073 3127
3074 Label enough, too_few; 3128 Label enough_arguments;
3075 __ Cmp(argc_actual, argc_expected);
3076 __ B(lt, &too_few);
3077 __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel); 3129 __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
3078 __ B(eq, &dont_adapt_arguments); 3130 __ B(eq, &dont_adapt_arguments);
3079 3131
3080 { // Enough parameters: actual >= expected 3132 EnterArgumentsAdaptorFrame(masm);
3081 EnterArgumentsAdaptorFrame(masm);
3082 Generate_StackOverflowCheck(masm, x2, x10, &stack_overflow);
3083 3133
3084 Register copy_start = x10; 3134 Register copy_from = x10;
3085 Register copy_end = x11; 3135 Register copy_end = x11;
3086 Register copy_to = x12; 3136 Register copy_to = x12;
3087 Register scratch1 = x13, scratch2 = x14; 3137 Register argc_to_copy = x13;
3138 Register argc_unused_actual = x14;
3139 Register scratch1 = x15, scratch2 = x16;
3088 3140
3089 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); 3141 // We need slots for the expected arguments, with two extra slots for the
3142 // number of actual arguments and the receiver.
3143 __ RecordComment("-- Stack check --");
3144 __ Add(scratch1, argc_expected, 2);
3145 Generate_StackOverflowCheck(masm, scratch1, scratch2, &stack_overflow);
3090 3146
3091 // Adjust for fp, lr, and the receiver. 3147 // Round up number of slots to be even, to maintain stack alignment.
3092 __ Add(copy_start, fp, 3 * kPointerSize); 3148 __ RecordComment("-- Allocate callee frame slots --");
3093 __ Add(copy_start, copy_start, Operand(argc_actual, LSL, kPointerSizeLog2)); 3149 __ Add(scratch1, scratch1, 1);
3094 __ Sub(copy_end, copy_start, scratch2); 3150 __ Bic(scratch1, scratch1, 1);
3095 __ Sub(copy_end, copy_end, kPointerSize); 3151 __ Claim(scratch1, kPointerSize);
3096 __ Mov(copy_to, jssp);
3097 3152
3098 // Claim space for the arguments, the receiver, and one extra slot. 3153 __ Mov(copy_to, jssp);
3099 // The extra slot ensures we do not write under jssp. It will be popped
3100 // later.
3101 __ Add(scratch1, scratch2, 2 * kPointerSize);
3102 __ Claim(scratch1, 1);
3103 3154
3104 // Copy the arguments (including the receiver) to the new stack frame. 3155 // Preparing the expected arguments is done in four steps, the order of
3105 Label copy_2_by_2; 3156 // which is chosen so we can use LDP/STP and avoid conditional branches as
3106 __ Bind(&copy_2_by_2); 3157 // much as possible.
3107 __ Ldp(scratch1, scratch2,
3108 MemOperand(copy_start, -2 * kPointerSize, PreIndex));
3109 __ Stp(scratch1, scratch2,
3110 MemOperand(copy_to, -2 * kPointerSize, PreIndex));
3111 __ Cmp(copy_start, copy_end);
3112 __ B(hi, &copy_2_by_2);
3113 3158
3114 // Correct the space allocated for the extra slot. 3159 // (1) If we don't have enough arguments, fill the remaining expected
3115 __ Drop(1); 3160 // arguments with undefined, otherwise skip this step.
3161 __ Subs(scratch1, argc_actual, argc_expected);
3162 __ Csel(argc_unused_actual, xzr, scratch1, lt);
3163 __ Csel(argc_to_copy, argc_expected, argc_actual, ge);
3164 __ B(ge, &enough_arguments);
3116 3165
3117 __ B(&invoke); 3166 // Fill the remaining expected arguments with undefined.
3118 } 3167 __ RecordComment("-- Fill slots with undefined --");
3168 __ Sub(copy_end, copy_to, Operand(scratch1, LSL, kPointerSizeLog2));
3169 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
3119 3170
3120 { // Too few parameters: Actual < expected 3171 Label fill;
3121 __ Bind(&too_few); 3172 __ Bind(&fill);
3173 __ Stp(scratch1, scratch1, MemOperand(copy_to, 2 * kPointerSize, PostIndex));
3174 // We might write one slot extra, but that is ok because we'll overwrite it
3175 // below.
3176 __ Cmp(copy_end, copy_to);
3177 __ B(hi, &fill);
3122 3178
3123 Register copy_from = x10; 3179 // Correct copy_to, for the case where we wrote one additional slot.
3124 Register copy_end = x11; 3180 __ Mov(copy_to, copy_end);
3125 Register copy_to = x12;
3126 Register scratch1 = x13, scratch2 = x14;
3127 3181
3128 EnterArgumentsAdaptorFrame(masm); 3182 __ Bind(&enough_arguments);
3129 Generate_StackOverflowCheck(masm, x2, x10, &stack_overflow); 3183 // (2) Copy all of the actual arguments, or as many as we need.
3184 __ RecordComment("-- Copy actual arguments --");
3185 __ Add(copy_end, copy_to, Operand(argc_to_copy, LSL, kPointerSizeLog2));
3186 __ Add(copy_from, fp, 2 * kPointerSize);
3187 // Adjust for difference between actual and expected arguments.
3188 __ Add(copy_from, copy_from,
3189 Operand(argc_unused_actual, LSL, kPointerSizeLog2));
3130 3190
3131 __ Lsl(scratch2, argc_expected, kPointerSizeLog2); 3191 // Copy arguments. We use load/store pair instructions, so we might overshoot
3132 __ Lsl(argc_actual, argc_actual, kPointerSizeLog2); 3192 // by one slot, but since we copy the arguments starting from the last one, if
3193 // we do overshoot, the extra slot will be overwritten later by the receiver.
3194 Label copy_2_by_2;
3195 __ Bind(&copy_2_by_2);
3196 __ Ldp(scratch1, scratch2,
3197 MemOperand(copy_from, 2 * kPointerSize, PostIndex));
3198 __ Stp(scratch1, scratch2, MemOperand(copy_to, 2 * kPointerSize, PostIndex));
3199 __ Cmp(copy_end, copy_to);
3200 __ B(hi, &copy_2_by_2);
3133 3201
3134 // Adjust for fp, lr, and the receiver. 3202 // (3) Store number of actual arguments and padding. The padding might be
3135 __ Add(copy_from, fp, 3 * kPointerSize); 3203 // unnecessary, in which case it will be overwritten by the receiver.
3136 __ Add(copy_from, copy_from, argc_actual); 3204 __ RecordComment("-- Store number of args and padding --");
3137 __ Mov(copy_to, jssp); 3205 __ SmiTag(scratch1, argc_actual);
3138 __ Sub(copy_end, copy_to, 1 * kPointerSize); // Adjust for the receiver. 3206 __ Stp(xzr, scratch1, MemOperand(fp, -4 * kPointerSize));
3139 __ Sub(copy_end, copy_end, argc_actual);
3140 3207
3141 // Claim space for the arguments, the receiver, and one extra slot. 3208 // (4) Store receiver. Calculate target address from jssp to avoid checking
3142 // The extra slot ensures we do not write under jssp. It will be popped 3209 // for padding. Storing the receiver will overwrite either the extra slot
3143 // later. 3210 // we copied with the actual arguments, if we did copy one, or the padding we
3144 __ Add(scratch1, scratch2, 2 * kPointerSize); 3211 // stored above.
3145 __ Claim(scratch1, 1); 3212 __ RecordComment("-- Store receiver --");
3146 3213 __ Add(copy_from, fp, 2 * kPointerSize);
3147 // Copy the arguments (including the receiver) to the new stack frame. 3214 __ Ldr(scratch1, MemOperand(copy_from, argc_actual, LSL, kPointerSizeLog2));
3148 Label copy_2_by_2; 3215 __ Str(scratch1, MemOperand(jssp, argc_expected, LSL, kPointerSizeLog2));
3149 __ Bind(&copy_2_by_2);
3150 __ Ldp(scratch1, scratch2,
3151 MemOperand(copy_from, -2 * kPointerSize, PreIndex));
3152 __ Stp(scratch1, scratch2,
3153 MemOperand(copy_to, -2 * kPointerSize, PreIndex));
3154 __ Cmp(copy_to, copy_end);
3155 __ B(hi, &copy_2_by_2);
3156
3157 __ Mov(copy_to, copy_end);
3158
3159 // Fill the remaining expected arguments with undefined.
3160 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
3161 __ Add(copy_end, jssp, kPointerSize);
3162
3163 Label fill;
3164 __ Bind(&fill);
3165 __ Stp(scratch1, scratch1,
3166 MemOperand(copy_to, -2 * kPointerSize, PreIndex));
3167 __ Cmp(copy_to, copy_end);
3168 __ B(hi, &fill);
3169
3170 // Correct the space allocated for the extra slot.
3171 __ Drop(1);
3172 }
3173 3216
3174 // Arguments have been adapted. Now call the entry point. 3217 // Arguments have been adapted. Now call the entry point.
3175 __ Bind(&invoke); 3218 __ RecordComment("-- Call entry point --");
3176 __ Mov(argc_actual, argc_expected); 3219 __ Mov(argc_actual, argc_expected);
3177 // x0 : expected number of arguments 3220 // x0 : expected number of arguments
3178 // x1 : function (passed through to callee) 3221 // x1 : function (passed through to callee)
3179 // x3 : new target (passed through to callee) 3222 // x3 : new target (passed through to callee)
3180 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); 3223 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
3181 __ Call(code_entry); 3224 __ Call(code_entry);
3182 3225
3183 // Store offset of return address for deoptimizer. 3226 // Store offset of return address for deoptimizer.
3184 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); 3227 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
3185 3228
3186 // Exit frame and return. 3229 // Exit frame and return.
3187 LeaveArgumentsAdaptorFrame(masm); 3230 LeaveArgumentsAdaptorFrame(masm);
3188 __ Ret(); 3231 __ Ret();
3189 3232
3190 // Call the entry point without adapting the arguments. 3233 // Call the entry point without adapting the arguments.
3234 __ RecordComment("-- Call without adapting args --");
3191 __ Bind(&dont_adapt_arguments); 3235 __ Bind(&dont_adapt_arguments);
3192 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); 3236 __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
3193 __ Jump(code_entry); 3237 __ Jump(code_entry);
3194 3238
3195 __ Bind(&stack_overflow); 3239 __ Bind(&stack_overflow);
3240 __ RecordComment("-- Stack overflow --");
3196 { 3241 {
3197 FrameScope frame(masm, StackFrame::MANUAL); 3242 FrameScope frame(masm, StackFrame::MANUAL);
3198 __ CallRuntime(Runtime::kThrowStackOverflow); 3243 __ CallRuntime(Runtime::kThrowStackOverflow);
3199 __ Unreachable(); 3244 __ Unreachable();
3200 } 3245 }
3201 } 3246 }
3202 3247
3203 void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) { 3248 void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
3204 // Wasm code uses the csp. This builtin excepts to use the jssp. 3249 // Wasm code uses the csp. This builtin excepts to use the jssp.
3205 // Thus, move csp to jssp when entering this builtin (called from wasm). 3250 // Thus, move csp to jssp when entering this builtin (called from wasm).
(...skipping 29 matching lines...) Expand all
3235 // Now jump to the instructions of the returned code object. 3280 // Now jump to the instructions of the returned code object.
3236 __ Jump(x8); 3281 __ Jump(x8);
3237 } 3282 }
3238 3283
3239 #undef __ 3284 #undef __
3240 3285
3241 } // namespace internal 3286 } // namespace internal
3242 } // namespace v8 3287 } // namespace v8
3243 3288
3244 #endif // V8_TARGET_ARCH_ARM 3289 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698