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

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

Issue 1056913003: JSEntryTrampoline: check for stack space before pushing arguments (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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/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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 823
824 // Leave construct frame. 824 // Leave construct frame.
825 } 825 }
826 826
827 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); 827 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
828 __ add(sp, sp, Operand(kPointerSize)); 828 __ add(sp, sp, Operand(kPointerSize));
829 __ Jump(lr); 829 __ Jump(lr);
830 } 830 }
831 831
832 832
833 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
834
835
836 // Clobbers r2; preserves all other registers.
837 static void Generate_CheckStackOverflow(MacroAssembler* masm,
838 const int calleeOffset, Register argc,
839 IsTagged argc_is_tagged) {
840 // Check the stack for overflow. We are not trying to catch
841 // interruptions (e.g. debug break and preemption) here, so the "real stack
842 // limit" is checked.
843 Label okay;
844 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
845 // Make r2 the space we have left. The stack might already be overflowed
846 // here which will cause r2 to become negative.
847 __ sub(r2, sp, r2);
848 // Check if the arguments will overflow the stack.
849 if (argc_is_tagged == kArgcIsSmiTagged) {
850 __ cmp(r2, Operand::PointerOffsetFromSmiKey(argc));
851 } else {
852 DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
853 __ cmp(r2, Operand(argc, LSL, kPointerSizeLog2));
854 }
855 __ b(gt, &okay); // Signed comparison.
856
857 // Out of stack space.
858 __ ldr(r1, MemOperand(fp, calleeOffset));
859 __ Push(r1, argc);
860 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
861
862 __ bind(&okay);
863 }
864
865
833 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 866 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
834 bool is_construct) { 867 bool is_construct) {
835 // Called from Generate_JS_Entry 868 // Called from Generate_JS_Entry
836 // r0: code entry 869 // r0: code entry
837 // r1: function 870 // r1: function
838 // r2: receiver 871 // r2: receiver
839 // r3: argc 872 // r3: argc
840 // r4: argv 873 // r4: argv
841 // r5-r6, r8 (if not FLAG_enable_ool_constant_pool) and cp may be clobbered 874 // r5-r6, r8 (if not FLAG_enable_ool_constant_pool) and cp may be clobbered
842 ProfileEntryHookStub::MaybeCallEntryHook(masm); 875 ProfileEntryHookStub::MaybeCallEntryHook(masm);
843 876
844 // Clear the context before we push it when entering the internal frame. 877 // Clear the context before we push it when entering the internal frame.
845 __ mov(cp, Operand::Zero()); 878 __ mov(cp, Operand::Zero());
846 879
847 // Enter an internal frame. 880 // Enter an internal frame.
848 { 881 {
849 FrameScope scope(masm, StackFrame::INTERNAL); 882 FrameScope scope(masm, StackFrame::INTERNAL);
850 883
851 // Set up the context from the function argument. 884 // Set up the context from the function argument.
852 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 885 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
853 886
854 __ InitializeRootRegister(); 887 __ InitializeRootRegister();
855 888
856 // Push the function and the receiver onto the stack. 889 // Push the function and the receiver onto the stack.
857 __ push(r1); 890 __ push(r1);
858 __ push(r2); 891 __ push(r2);
859 892
893 // Check if we have enough stack space to push all arguments.
894 // The function is the first thing that was pushed above after entering
895 // the internal frame.
896 const int kFunctionOffset =
897 InternalFrameConstants::kCodeOffset - kPointerSize;
898 // Clobbers r2.
899 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsUntaggedInt);
900
860 // Copy arguments to the stack in a loop. 901 // Copy arguments to the stack in a loop.
861 // r1: function 902 // r1: function
862 // r3: argc 903 // r3: argc
863 // r4: argv, i.e. points to first arg 904 // r4: argv, i.e. points to first arg
864 Label loop, entry; 905 Label loop, entry;
865 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); 906 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2));
866 // r2 points past last arg. 907 // r2 points past last arg.
867 __ b(&entry); 908 __ b(&entry);
868 __ bind(&loop); 909 __ bind(&loop);
869 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter 910 __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1370 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1330 RelocInfo::CODE_TARGET, 1371 RelocInfo::CODE_TARGET,
1331 ne); 1372 ne);
1332 1373
1333 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 1374 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1334 ParameterCount expected(0); 1375 ParameterCount expected(0);
1335 __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 1376 __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1336 } 1377 }
1337 1378
1338 1379
1339 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1340 const int calleeOffset) {
1341 // Check the stack for overflow. We are not trying to catch
1342 // interruptions (e.g. debug break and preemption) here, so the "real stack
1343 // limit" is checked.
1344 Label okay;
1345 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
1346 // Make r2 the space we have left. The stack might already be overflowed
1347 // here which will cause r2 to become negative.
1348 __ sub(r2, sp, r2);
1349 // Check if the arguments will overflow the stack.
1350 __ cmp(r2, Operand::PointerOffsetFromSmiKey(r0));
1351 __ b(gt, &okay); // Signed comparison.
1352
1353 // Out of stack space.
1354 __ ldr(r1, MemOperand(fp, calleeOffset));
1355 __ Push(r1, r0);
1356 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1357
1358 __ bind(&okay);
1359 }
1360
1361
1362 static void Generate_PushAppliedArguments(MacroAssembler* masm, 1380 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1363 const int argumentsOffset, 1381 const int argumentsOffset,
1364 const int indexOffset, 1382 const int indexOffset,
1365 const int limitOffset) { 1383 const int limitOffset) {
1366 Label entry, loop; 1384 Label entry, loop;
1367 __ ldr(r0, MemOperand(fp, indexOffset)); 1385 __ ldr(r0, MemOperand(fp, indexOffset));
1368 __ b(&entry); 1386 __ b(&entry);
1369 1387
1370 // Load the current argument from the arguments array and push it to the 1388 // Load the current argument from the arguments array and push it to the
1371 // stack. 1389 // stack.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function 1427 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
1410 __ push(r0); 1428 __ push(r0);
1411 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array 1429 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array
1412 __ push(r0); 1430 __ push(r0);
1413 if (targetIsArgument) { 1431 if (targetIsArgument) {
1414 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); 1432 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1415 } else { 1433 } else {
1416 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1434 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1417 } 1435 }
1418 1436
1419 Generate_CheckStackOverflow(masm, kFunctionOffset); 1437 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
1420 1438
1421 // Push current limit and index. 1439 // Push current limit and index.
1422 const int kIndexOffset = 1440 const int kIndexOffset =
1423 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 1441 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1424 const int kLimitOffset = 1442 const int kLimitOffset =
1425 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 1443 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1426 __ push(r0); // limit 1444 __ push(r0); // limit
1427 __ mov(r1, Operand::Zero()); // initial index 1445 __ mov(r1, Operand::Zero()); // initial index
1428 __ push(r1); 1446 __ push(r1);
1429 1447
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 // Validate arguments 1555 // Validate arguments
1538 __ bind(&validate_arguments); 1556 __ bind(&validate_arguments);
1539 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function 1557 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
1540 __ push(r0); 1558 __ push(r0);
1541 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array 1559 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array
1542 __ push(r0); 1560 __ push(r0);
1543 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target 1561 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target
1544 __ push(r0); 1562 __ push(r0);
1545 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); 1563 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1546 1564
1547 Generate_CheckStackOverflow(masm, kFunctionOffset); 1565 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged);
1548 1566
1549 // Push current limit and index. 1567 // Push current limit and index.
1550 const int kIndexOffset = 1568 const int kIndexOffset =
1551 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 1569 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1552 const int kLimitOffset = 1570 const int kLimitOffset =
1553 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 1571 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1554 __ push(r0); // limit 1572 __ push(r0); // limit
1555 __ mov(r1, Operand::Zero()); // initial index 1573 __ mov(r1, Operand::Zero()); // initial index
1556 __ push(r1); 1574 __ push(r1);
1557 // Push newTarget and callee functions 1575 // Push newTarget and callee functions
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1759 __ bkpt(0); 1777 __ bkpt(0);
1760 } 1778 }
1761 } 1779 }
1762 1780
1763 1781
1764 #undef __ 1782 #undef __
1765 1783
1766 } } // namespace v8::internal 1784 } } // namespace v8::internal
1767 1785
1768 #endif // V8_TARGET_ARCH_ARM 1786 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698