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

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

Issue 2335513004: [Interpreter] Adds stackcheck in InterpreterPushArgsAndCall/Construct builtins. (Closed)
Patch Set: Addressed comments from Ross. Created 4 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 | « 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 1144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 // Push function as argument and compile for baseline. 1155 // Push function as argument and compile for baseline.
1156 __ push(r1); 1156 __ push(r1);
1157 __ CallRuntime(Runtime::kCompileBaseline); 1157 __ CallRuntime(Runtime::kCompileBaseline);
1158 1158
1159 // Restore return value. 1159 // Restore return value.
1160 __ pop(r0); 1160 __ pop(r0);
1161 } 1161 }
1162 __ Jump(lr); 1162 __ Jump(lr);
1163 } 1163 }
1164 1164
1165 static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
1166 Register scratch,
1167 Label* stack_overflow) {
1168 // Check the stack for overflow. We are not trying to catch
1169 // interruptions (e.g. debug break and preemption) here, so the "real stack
1170 // limit" is checked.
1171 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
1172 // Make scratch the space we have left. The stack might already be overflowed
1173 // here which will cause scratch to become negative.
1174 __ sub(scratch, sp, scratch);
1175 // Check if the arguments will overflow the stack.
1176 __ cmp(scratch, Operand(num_args, LSL, kPointerSizeLog2));
1177 __ b(le, stack_overflow); // Signed comparison.
1178 }
1179
1165 static void Generate_InterpreterPushArgs(MacroAssembler* masm, 1180 static void Generate_InterpreterPushArgs(MacroAssembler* masm,
1166 Register num_args, Register index, 1181 Register num_args, Register index,
1167 Register limit, Register scratch) { 1182 Register limit, Register scratch,
1183 Label* stack_overflow) {
1184 // Add a stack check before pushing arguments.
1185 Generate_StackOverflowCheck(masm, num_args, scratch, stack_overflow);
1186
1168 // Find the address of the last argument. 1187 // Find the address of the last argument.
1169 __ mov(limit, num_args); 1188 __ mov(limit, num_args);
1170 __ mov(limit, Operand(limit, LSL, kPointerSizeLog2)); 1189 __ mov(limit, Operand(limit, LSL, kPointerSizeLog2));
1171 __ sub(limit, index, limit); 1190 __ sub(limit, index, limit);
1172 1191
1173 // TODO(mythria): Add a stack check before pushing arguments.
1174 Label loop_header, loop_check; 1192 Label loop_header, loop_check;
1175 __ b(al, &loop_check); 1193 __ b(al, &loop_check);
1176 __ bind(&loop_header); 1194 __ bind(&loop_header);
1177 __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex)); 1195 __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
1178 __ push(scratch); 1196 __ push(scratch);
1179 __ bind(&loop_check); 1197 __ bind(&loop_check);
1180 __ cmp(index, limit); 1198 __ cmp(index, limit);
1181 __ b(gt, &loop_header); 1199 __ b(gt, &loop_header);
1182 } 1200 }
1183 1201
1184 // static 1202 // static
1185 void Builtins::Generate_InterpreterPushArgsAndCallImpl( 1203 void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1186 MacroAssembler* masm, TailCallMode tail_call_mode, 1204 MacroAssembler* masm, TailCallMode tail_call_mode,
1187 CallableType function_type) { 1205 CallableType function_type) {
1188 // ----------- S t a t e ------------- 1206 // ----------- S t a t e -------------
1189 // -- r0 : the number of arguments (not including the receiver) 1207 // -- r0 : the number of arguments (not including the receiver)
1190 // -- r2 : the address of the first argument to be pushed. Subsequent 1208 // -- r2 : the address of the first argument to be pushed. Subsequent
1191 // arguments should be consecutive above this, in the same order as 1209 // arguments should be consecutive above this, in the same order as
1192 // they are to be pushed onto the stack. 1210 // they are to be pushed onto the stack.
1193 // -- r1 : the target to call (can be any Object). 1211 // -- r1 : the target to call (can be any Object).
1194 // ----------------------------------- 1212 // -----------------------------------
1213 Label stack_overflow;
1195 1214
1196 __ add(r3, r0, Operand(1)); // Add one for receiver. 1215 __ add(r3, r0, Operand(1)); // Add one for receiver.
1197 1216
1198 // Push the arguments. r2, r4, r5 will be modified. 1217 // Push the arguments. r2, r4, r5 will be modified.
1199 Generate_InterpreterPushArgs(masm, r3, r2, r4, r5); 1218 Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow);
1200 1219
1201 // Call the target. 1220 // Call the target.
1202 if (function_type == CallableType::kJSFunction) { 1221 if (function_type == CallableType::kJSFunction) {
1203 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, 1222 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
1204 tail_call_mode), 1223 tail_call_mode),
1205 RelocInfo::CODE_TARGET); 1224 RelocInfo::CODE_TARGET);
1206 } else { 1225 } else {
1207 DCHECK_EQ(function_type, CallableType::kAny); 1226 DCHECK_EQ(function_type, CallableType::kAny);
1208 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, 1227 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1209 tail_call_mode), 1228 tail_call_mode),
1210 RelocInfo::CODE_TARGET); 1229 RelocInfo::CODE_TARGET);
1211 } 1230 }
1231
1232 __ bind(&stack_overflow);
1233 {
1234 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1235 // Unreachable code.
1236 __ bkpt(0);
1237 }
1212 } 1238 }
1213 1239
1214 // static 1240 // static
1215 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 1241 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1216 MacroAssembler* masm, CallableType construct_type) { 1242 MacroAssembler* masm, CallableType construct_type) {
1217 // ----------- S t a t e ------------- 1243 // ----------- S t a t e -------------
1218 // -- r0 : argument count (not including receiver) 1244 // -- r0 : argument count (not including receiver)
1219 // -- r3 : new target 1245 // -- r3 : new target
1220 // -- r1 : constructor to call 1246 // -- r1 : constructor to call
1221 // -- r2 : allocation site feedback if available, undefined otherwise. 1247 // -- r2 : allocation site feedback if available, undefined otherwise.
1222 // -- r4 : address of the first argument 1248 // -- r4 : address of the first argument
1223 // ----------------------------------- 1249 // -----------------------------------
1250 Label stack_overflow;
1224 1251
1225 // Push a slot for the receiver to be constructed. 1252 // Push a slot for the receiver to be constructed.
1226 __ mov(ip, Operand::Zero()); 1253 __ mov(ip, Operand::Zero());
1227 __ push(ip); 1254 __ push(ip);
1228 1255
1229 // TODO(mythria): Add a stack check before pushing arguments.
1230 // Push the arguments. r5, r4, r6 will be modified. 1256 // Push the arguments. r5, r4, r6 will be modified.
1231 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6); 1257 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow);
1232 1258
1233 __ AssertUndefinedOrAllocationSite(r2, r5); 1259 __ AssertUndefinedOrAllocationSite(r2, r5);
1234 if (construct_type == CallableType::kJSFunction) { 1260 if (construct_type == CallableType::kJSFunction) {
1235 __ AssertFunction(r1); 1261 __ AssertFunction(r1);
1236 1262
1237 // Tail call to the function-specific construct stub (still in the caller 1263 // Tail call to the function-specific construct stub (still in the caller
1238 // context at this point). 1264 // context at this point).
1239 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1265 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1240 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); 1266 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1241 // Jump to the construct function. 1267 // Jump to the construct function.
1242 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); 1268 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1243 1269
1244 } else { 1270 } else {
1245 DCHECK_EQ(construct_type, CallableType::kAny); 1271 DCHECK_EQ(construct_type, CallableType::kAny);
1246 // Call the constructor with r0, r1, and r3 unmodified. 1272 // Call the constructor with r0, r1, and r3 unmodified.
1247 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1273 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1248 } 1274 }
1275
1276 __ bind(&stack_overflow);
1277 {
1278 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1279 // Unreachable code.
1280 __ bkpt(0);
1281 }
1249 } 1282 }
1250 1283
1251 // static 1284 // static
1252 void Builtins::Generate_InterpreterPushArgsAndConstructArray( 1285 void Builtins::Generate_InterpreterPushArgsAndConstructArray(
1253 MacroAssembler* masm) { 1286 MacroAssembler* masm) {
1254 // ----------- S t a t e ------------- 1287 // ----------- S t a t e -------------
1255 // -- r0 : argument count (not including receiver) 1288 // -- r0 : argument count (not including receiver)
1256 // -- r1 : target to call verified to be Array function 1289 // -- r1 : target to call verified to be Array function
1257 // -- r2 : allocation site feedback if available, undefined otherwise. 1290 // -- r2 : allocation site feedback if available, undefined otherwise.
1258 // -- r3 : address of the first argument 1291 // -- r3 : address of the first argument
1259 // ----------------------------------- 1292 // -----------------------------------
1293 Label stack_overflow;
1260 1294
1261 __ add(r4, r0, Operand(1)); // Add one for receiver. 1295 __ add(r4, r0, Operand(1)); // Add one for receiver.
1262 1296
1263 // TODO(mythria): Add a stack check before pushing arguments. 1297 // TODO(mythria): Add a stack check before pushing arguments.
1264 // Push the arguments. r3, r5, r6 will be modified. 1298 // Push the arguments. r3, r5, r6 will be modified.
1265 Generate_InterpreterPushArgs(masm, r4, r3, r5, r6); 1299 Generate_InterpreterPushArgs(masm, r4, r3, r5, r6, &stack_overflow);
1266 1300
1267 // Array constructor expects constructor in r3. It is same as r1 here. 1301 // Array constructor expects constructor in r3. It is same as r1 here.
1268 __ mov(r3, r1); 1302 __ mov(r3, r1);
1269 1303
1270 ArrayConstructorStub stub(masm->isolate()); 1304 ArrayConstructorStub stub(masm->isolate());
1271 __ TailCallStub(&stub); 1305 __ TailCallStub(&stub);
1306
1307 __ bind(&stack_overflow);
1308 {
1309 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1310 // Unreachable code.
1311 __ bkpt(0);
1312 }
1272 } 1313 }
1273 1314
1274 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { 1315 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1275 // Set the return address to the correct point in the interpreter entry 1316 // Set the return address to the correct point in the interpreter entry
1276 // trampoline. 1317 // trampoline.
1277 Smi* interpreter_entry_return_pc_offset( 1318 Smi* interpreter_entry_return_pc_offset(
1278 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); 1319 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1279 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); 1320 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
1280 __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline()); 1321 __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline());
1281 __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() + 1322 __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() +
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 } 2185 }
2145 2186
2146 // 4c. The new.target is not a constructor, throw an appropriate TypeError. 2187 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2147 __ bind(&new_target_not_constructor); 2188 __ bind(&new_target_not_constructor);
2148 { 2189 {
2149 __ str(r3, MemOperand(sp, 0)); 2190 __ str(r3, MemOperand(sp, 0));
2150 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); 2191 __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2151 } 2192 }
2152 } 2193 }
2153 2194
2154 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
2155 Label* stack_overflow) {
2156 // ----------- S t a t e -------------
2157 // -- r0 : actual number of arguments
2158 // -- r1 : function (passed through to callee)
2159 // -- r2 : expected number of arguments
2160 // -- r3 : new target (passed through to callee)
2161 // -----------------------------------
2162 // Check the stack for overflow. We are not trying to catch
2163 // interruptions (e.g. debug break and preemption) here, so the "real stack
2164 // limit" is checked.
2165 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
2166 // Make r5 the space we have left. The stack might already be overflowed
2167 // here which will cause r5 to become negative.
2168 __ sub(r5, sp, r5);
2169 // Check if the arguments will overflow the stack.
2170 __ cmp(r5, Operand(r2, LSL, kPointerSizeLog2));
2171 __ b(le, stack_overflow); // Signed comparison.
2172 }
2173
2174 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 2195 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2175 __ SmiTag(r0); 2196 __ SmiTag(r0);
2176 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2197 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2177 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | 2198 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
2178 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) | 2199 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
2179 fp.bit() | lr.bit()); 2200 fp.bit() | lr.bit());
2180 __ add(fp, sp, 2201 __ add(fp, sp,
2181 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); 2202 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
2182 } 2203 }
2183 2204
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
2863 2884
2864 Label enough, too_few; 2885 Label enough, too_few;
2865 __ cmp(r0, r2); 2886 __ cmp(r0, r2);
2866 __ b(lt, &too_few); 2887 __ b(lt, &too_few);
2867 __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 2888 __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
2868 __ b(eq, &dont_adapt_arguments); 2889 __ b(eq, &dont_adapt_arguments);
2869 2890
2870 { // Enough parameters: actual >= expected 2891 { // Enough parameters: actual >= expected
2871 __ bind(&enough); 2892 __ bind(&enough);
2872 EnterArgumentsAdaptorFrame(masm); 2893 EnterArgumentsAdaptorFrame(masm);
2873 ArgumentAdaptorStackCheck(masm, &stack_overflow); 2894 Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2874 2895
2875 // Calculate copy start address into r0 and copy end address into r4. 2896 // Calculate copy start address into r0 and copy end address into r4.
2876 // r0: actual number of arguments as a smi 2897 // r0: actual number of arguments as a smi
2877 // r1: function 2898 // r1: function
2878 // r2: expected number of arguments 2899 // r2: expected number of arguments
2879 // r3: new target (passed through to callee) 2900 // r3: new target (passed through to callee)
2880 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 2901 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2881 // adjust for return address and receiver 2902 // adjust for return address and receiver
2882 __ add(r0, r0, Operand(2 * kPointerSize)); 2903 __ add(r0, r0, Operand(2 * kPointerSize));
2883 __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2)); 2904 __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2));
(...skipping 12 matching lines...) Expand all
2896 __ cmp(r0, r4); // Compare before moving to next argument. 2917 __ cmp(r0, r4); // Compare before moving to next argument.
2897 __ sub(r0, r0, Operand(kPointerSize)); 2918 __ sub(r0, r0, Operand(kPointerSize));
2898 __ b(ne, &copy); 2919 __ b(ne, &copy);
2899 2920
2900 __ b(&invoke); 2921 __ b(&invoke);
2901 } 2922 }
2902 2923
2903 { // Too few parameters: Actual < expected 2924 { // Too few parameters: Actual < expected
2904 __ bind(&too_few); 2925 __ bind(&too_few);
2905 EnterArgumentsAdaptorFrame(masm); 2926 EnterArgumentsAdaptorFrame(masm);
2906 ArgumentAdaptorStackCheck(masm, &stack_overflow); 2927 Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2907 2928
2908 // Calculate copy start address into r0 and copy end address is fp. 2929 // Calculate copy start address into r0 and copy end address is fp.
2909 // r0: actual number of arguments as a smi 2930 // r0: actual number of arguments as a smi
2910 // r1: function 2931 // r1: function
2911 // r2: expected number of arguments 2932 // r2: expected number of arguments
2912 // r3: new target (passed through to callee) 2933 // r3: new target (passed through to callee)
2913 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 2934 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2914 2935
2915 // Copy the arguments (including the receiver) to the new stack frame. 2936 // Copy the arguments (including the receiver) to the new stack frame.
2916 // r0: copy start address 2937 // r0: copy start address
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2973 __ bkpt(0); 2994 __ bkpt(0);
2974 } 2995 }
2975 } 2996 }
2976 2997
2977 #undef __ 2998 #undef __
2978 2999
2979 } // namespace internal 3000 } // namespace internal
2980 } // namespace v8 3001 } // namespace v8
2981 3002
2982 #endif // V8_TARGET_ARCH_ARM 3003 #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