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

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

Issue 2335513004: [Interpreter] Adds stackcheck in InterpreterPushArgsAndCall/Construct builtins. (Closed)
Patch Set: fix for ia32 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') | src/builtins/ia32/builtins-ia32.cc » ('J')
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 __ bkpt(0);
rmcilroy 2016/09/12 14:43:17 Comment that this should be unreachable (all arche
mythria 2016/09/13 09:53:33 Done.
1236 }
1212 } 1237 }
1213 1238
1214 // static 1239 // static
1215 void Builtins::Generate_InterpreterPushArgsAndConstructImpl( 1240 void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1216 MacroAssembler* masm, CallableType construct_type) { 1241 MacroAssembler* masm, CallableType construct_type) {
1217 // ----------- S t a t e ------------- 1242 // ----------- S t a t e -------------
1218 // -- r0 : argument count (not including receiver) 1243 // -- r0 : argument count (not including receiver)
1219 // -- r3 : new target 1244 // -- r3 : new target
1220 // -- r1 : constructor to call 1245 // -- r1 : constructor to call
1221 // -- r2 : allocation site feedback if available, undefined otherwise. 1246 // -- r2 : allocation site feedback if available, undefined otherwise.
1222 // -- r4 : address of the first argument 1247 // -- r4 : address of the first argument
1223 // ----------------------------------- 1248 // -----------------------------------
1249 Label stack_overflow;
1224 1250
1225 // Push a slot for the receiver to be constructed. 1251 // Push a slot for the receiver to be constructed.
1226 __ mov(ip, Operand::Zero()); 1252 __ mov(ip, Operand::Zero());
1227 __ push(ip); 1253 __ push(ip);
1228 1254
1229 // TODO(mythria): Add a stack check before pushing arguments.
1230 // Push the arguments. r5, r4, r6 will be modified. 1255 // Push the arguments. r5, r4, r6 will be modified.
1231 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6); 1256 Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow);
1232 1257
1233 __ AssertUndefinedOrAllocationSite(r2, r5); 1258 __ AssertUndefinedOrAllocationSite(r2, r5);
1234 if (construct_type == CallableType::kJSFunction) { 1259 if (construct_type == CallableType::kJSFunction) {
1235 __ AssertFunction(r1); 1260 __ AssertFunction(r1);
1236 1261
1237 // Tail call to the function-specific construct stub (still in the caller 1262 // Tail call to the function-specific construct stub (still in the caller
1238 // context at this point). 1263 // context at this point).
1239 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1264 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1240 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset)); 1265 __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1241 // Jump to the construct function. 1266 // Jump to the construct function.
1242 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag)); 1267 __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1243 1268
1244 } else { 1269 } else {
1245 DCHECK_EQ(construct_type, CallableType::kAny); 1270 DCHECK_EQ(construct_type, CallableType::kAny);
1246 // Call the constructor with r0, r1, and r3 unmodified. 1271 // Call the constructor with r0, r1, and r3 unmodified.
1247 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); 1272 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1248 } 1273 }
1274
1275 __ bind(&stack_overflow);
1276 {
1277 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1278 __ bkpt(0);
1279 }
1249 } 1280 }
1250 1281
1251 // static 1282 // static
1252 void Builtins::Generate_InterpreterPushArgsAndConstructArray( 1283 void Builtins::Generate_InterpreterPushArgsAndConstructArray(
1253 MacroAssembler* masm) { 1284 MacroAssembler* masm) {
1254 // ----------- S t a t e ------------- 1285 // ----------- S t a t e -------------
1255 // -- r0 : argument count (not including receiver) 1286 // -- r0 : argument count (not including receiver)
1256 // -- r1 : target to call verified to be Array function 1287 // -- r1 : target to call verified to be Array function
1257 // -- r2 : allocation site feedback if available, undefined otherwise. 1288 // -- r2 : allocation site feedback if available, undefined otherwise.
1258 // -- r3 : address of the first argument 1289 // -- r3 : address of the first argument
1259 // ----------------------------------- 1290 // -----------------------------------
1291 Label stack_overflow;
1260 1292
1261 __ add(r4, r0, Operand(1)); // Add one for receiver. 1293 __ add(r4, r0, Operand(1)); // Add one for receiver.
1262 1294
1263 // TODO(mythria): Add a stack check before pushing arguments. 1295 // TODO(mythria): Add a stack check before pushing arguments.
1264 // Push the arguments. r3, r5, r6 will be modified. 1296 // Push the arguments. r3, r5, r6 will be modified.
1265 Generate_InterpreterPushArgs(masm, r4, r3, r5, r6); 1297 Generate_InterpreterPushArgs(masm, r4, r3, r5, r6, &stack_overflow);
1266 1298
1267 // Array constructor expects constructor in r3. It is same as r1 here. 1299 // Array constructor expects constructor in r3. It is same as r1 here.
1268 __ mov(r3, r1); 1300 __ mov(r3, r1);
1269 1301
1270 ArrayConstructorStub stub(masm->isolate()); 1302 ArrayConstructorStub stub(masm->isolate());
1271 __ TailCallStub(&stub); 1303 __ TailCallStub(&stub);
1304
1305 __ bind(&stack_overflow);
1306 {
1307 __ TailCallRuntime(Runtime::kThrowStackOverflow);
1308 __ bkpt(0);
1309 }
1272 } 1310 }
1273 1311
1274 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) { 1312 void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1275 // Set the return address to the correct point in the interpreter entry 1313 // Set the return address to the correct point in the interpreter entry
1276 // trampoline. 1314 // trampoline.
1277 Smi* interpreter_entry_return_pc_offset( 1315 Smi* interpreter_entry_return_pc_offset(
1278 masm->isolate()->heap()->interpreter_entry_return_pc_offset()); 1316 masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1279 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0)); 1317 DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
1280 __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline()); 1318 __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline());
1281 __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() + 1319 __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() +
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 } 2182 }
2145 2183
2146 // 4c. The new.target is not a constructor, throw an appropriate TypeError. 2184 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2147 __ bind(&new_target_not_constructor); 2185 __ bind(&new_target_not_constructor);
2148 { 2186 {
2149 __ str(r3, MemOperand(sp, 0)); 2187 __ str(r3, MemOperand(sp, 0));
2150 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); 2188 __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2151 } 2189 }
2152 } 2190 }
2153 2191
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) { 2192 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2175 __ SmiTag(r0); 2193 __ SmiTag(r0);
2176 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 2194 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2177 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | 2195 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
2178 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) | 2196 (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
2179 fp.bit() | lr.bit()); 2197 fp.bit() | lr.bit());
2180 __ add(fp, sp, 2198 __ add(fp, sp,
2181 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); 2199 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
2182 } 2200 }
2183 2201
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
2863 2881
2864 Label enough, too_few; 2882 Label enough, too_few;
2865 __ cmp(r0, r2); 2883 __ cmp(r0, r2);
2866 __ b(lt, &too_few); 2884 __ b(lt, &too_few);
2867 __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 2885 __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
2868 __ b(eq, &dont_adapt_arguments); 2886 __ b(eq, &dont_adapt_arguments);
2869 2887
2870 { // Enough parameters: actual >= expected 2888 { // Enough parameters: actual >= expected
2871 __ bind(&enough); 2889 __ bind(&enough);
2872 EnterArgumentsAdaptorFrame(masm); 2890 EnterArgumentsAdaptorFrame(masm);
2873 ArgumentAdaptorStackCheck(masm, &stack_overflow); 2891 Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2874 2892
2875 // Calculate copy start address into r0 and copy end address into r4. 2893 // Calculate copy start address into r0 and copy end address into r4.
2876 // r0: actual number of arguments as a smi 2894 // r0: actual number of arguments as a smi
2877 // r1: function 2895 // r1: function
2878 // r2: expected number of arguments 2896 // r2: expected number of arguments
2879 // r3: new target (passed through to callee) 2897 // r3: new target (passed through to callee)
2880 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 2898 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2881 // adjust for return address and receiver 2899 // adjust for return address and receiver
2882 __ add(r0, r0, Operand(2 * kPointerSize)); 2900 __ add(r0, r0, Operand(2 * kPointerSize));
2883 __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2)); 2901 __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2));
(...skipping 12 matching lines...) Expand all
2896 __ cmp(r0, r4); // Compare before moving to next argument. 2914 __ cmp(r0, r4); // Compare before moving to next argument.
2897 __ sub(r0, r0, Operand(kPointerSize)); 2915 __ sub(r0, r0, Operand(kPointerSize));
2898 __ b(ne, &copy); 2916 __ b(ne, &copy);
2899 2917
2900 __ b(&invoke); 2918 __ b(&invoke);
2901 } 2919 }
2902 2920
2903 { // Too few parameters: Actual < expected 2921 { // Too few parameters: Actual < expected
2904 __ bind(&too_few); 2922 __ bind(&too_few);
2905 EnterArgumentsAdaptorFrame(masm); 2923 EnterArgumentsAdaptorFrame(masm);
2906 ArgumentAdaptorStackCheck(masm, &stack_overflow); 2924 Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2907 2925
2908 // Calculate copy start address into r0 and copy end address is fp. 2926 // Calculate copy start address into r0 and copy end address is fp.
2909 // r0: actual number of arguments as a smi 2927 // r0: actual number of arguments as a smi
2910 // r1: function 2928 // r1: function
2911 // r2: expected number of arguments 2929 // r2: expected number of arguments
2912 // r3: new target (passed through to callee) 2930 // r3: new target (passed through to callee)
2913 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 2931 __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2914 2932
2915 // Copy the arguments (including the receiver) to the new stack frame. 2933 // Copy the arguments (including the receiver) to the new stack frame.
2916 // r0: copy start address 2934 // r0: copy start address
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2973 __ bkpt(0); 2991 __ bkpt(0);
2974 } 2992 }
2975 } 2993 }
2976 2994
2977 #undef __ 2995 #undef __
2978 2996
2979 } // namespace internal 2997 } // namespace internal
2980 } // namespace v8 2998 } // namespace v8
2981 2999
2982 #endif // V8_TARGET_ARCH_ARM 3000 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/builtins/arm64/builtins-arm64.cc » ('j') | src/builtins/ia32/builtins-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698