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

Side by Side Diff: src/x64/builtins-x64.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 | « src/ia32/builtins-ia32.cc ('k') | test/mjsunit/regress/regress-crbug-469768.js » ('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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 566
567 // Remove caller arguments from the stack and return. 567 // Remove caller arguments from the stack and return.
568 __ PopReturnAddressTo(rcx); 568 __ PopReturnAddressTo(rcx);
569 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); 569 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
570 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); 570 __ leap(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
571 __ PushReturnAddressFrom(rcx); 571 __ PushReturnAddressFrom(rcx);
572 __ ret(0); 572 __ ret(0);
573 } 573 }
574 574
575 575
576 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt };
577
578
579 // Clobbers rcx, rdx, kScratchRegister; preserves all other registers.
580 static void Generate_CheckStackOverflow(MacroAssembler* masm,
581 const int calleeOffset,
582 IsTagged rax_is_tagged) {
583 // rax : the number of items to be pushed to the stack
584 //
585 // Check the stack for overflow. We are not trying to catch
586 // interruptions (e.g. debug break and preemption) here, so the "real stack
587 // limit" is checked.
588 Label okay;
589 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
590 __ movp(rcx, rsp);
591 // Make rcx the space we have left. The stack might already be overflowed
592 // here which will cause rcx to become negative.
593 __ subp(rcx, kScratchRegister);
594 // Make rdx the space we need for the array when it is unrolled onto the
595 // stack.
596 if (rax_is_tagged == kRaxIsSmiTagged) {
597 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2);
598 } else {
599 DCHECK(rax_is_tagged == kRaxIsUntaggedInt);
600 __ movp(rdx, rax);
601 __ shlq(rdx, Immediate(kPointerSizeLog2));
602 }
603 // Check if the arguments will overflow the stack.
604 __ cmpp(rcx, rdx);
605 __ j(greater, &okay); // Signed comparison.
606
607 // Out of stack space.
608 __ Push(Operand(rbp, calleeOffset));
609 __ Push(rax);
610 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
611
612 __ bind(&okay);
613 }
614
615
576 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 616 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
577 bool is_construct) { 617 bool is_construct) {
578 ProfileEntryHookStub::MaybeCallEntryHook(masm); 618 ProfileEntryHookStub::MaybeCallEntryHook(masm);
579 619
580 // Expects five C++ function parameters. 620 // Expects five C++ function parameters.
581 // - Address entry (ignored) 621 // - Address entry (ignored)
582 // - JSFunction* function ( 622 // - JSFunction* function (
583 // - Object* receiver 623 // - Object* receiver
584 // - int argc 624 // - int argc
585 // - Object*** argv 625 // - Object*** argv
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 // Current stack contents: 688 // Current stack contents:
649 // [rsp + 2 * kPointerSize ... ] : Internal frame 689 // [rsp + 2 * kPointerSize ... ] : Internal frame
650 // [rsp + kPointerSize] : function 690 // [rsp + kPointerSize] : function
651 // [rsp] : receiver 691 // [rsp] : receiver
652 // Current register contents: 692 // Current register contents:
653 // rax : argc 693 // rax : argc
654 // rbx : argv 694 // rbx : argv
655 // rsi : context 695 // rsi : context
656 // rdi : function 696 // rdi : function
657 697
698 // Check if we have enough stack space to push all arguments.
699 // The function is the first thing that was pushed above after entering
700 // the internal frame.
701 const int kFunctionOffset =
702 InternalFrameConstants::kCodeOffset - kRegisterSize;
703 // Expects argument count in rax. Clobbers rcx, rdx.
704 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsUntaggedInt);
705
658 // Copy arguments to the stack in a loop. 706 // Copy arguments to the stack in a loop.
659 // Register rbx points to array of pointers to handle locations. 707 // Register rbx points to array of pointers to handle locations.
660 // Push the values of these handles. 708 // Push the values of these handles.
661 Label loop, entry; 709 Label loop, entry;
662 __ Set(rcx, 0); // Set loop variable to 0. 710 __ Set(rcx, 0); // Set loop variable to 0.
663 __ jmp(&entry); 711 __ jmp(&entry);
664 __ bind(&loop); 712 __ bind(&loop);
665 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); 713 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0));
666 __ Push(Operand(kScratchRegister, 0)); // dereference handle 714 __ Push(Operand(kScratchRegister, 0)); // dereference handle
667 __ addp(rcx, Immediate(1)); 715 __ addp(rcx, Immediate(1));
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 __ cmpp(rax, rbx); 1092 __ cmpp(rax, rbx);
1045 __ j(not_equal, 1093 __ j(not_equal,
1046 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1094 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1047 RelocInfo::CODE_TARGET); 1095 RelocInfo::CODE_TARGET);
1048 1096
1049 ParameterCount expected(0); 1097 ParameterCount expected(0);
1050 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 1098 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1051 } 1099 }
1052 1100
1053 1101
1054 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1055 const int calleeOffset) {
1056 // rax : the number of items to be pushed to the stack
1057 //
1058 // Check the stack for overflow. We are not trying to catch
1059 // interruptions (e.g. debug break and preemption) here, so the "real stack
1060 // limit" is checked.
1061 Label okay;
1062 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex);
1063 __ movp(rcx, rsp);
1064 // Make rcx the space we have left. The stack might already be overflowed
1065 // here which will cause rcx to become negative.
1066 __ subp(rcx, kScratchRegister);
1067 // Make rdx the space we need for the array when it is unrolled onto the
1068 // stack.
1069 __ PositiveSmiTimesPowerOfTwoToInteger64(rdx, rax, kPointerSizeLog2);
1070 // Check if the arguments will overflow the stack.
1071 __ cmpp(rcx, rdx);
1072 __ j(greater, &okay); // Signed comparison.
1073
1074 // Out of stack space.
1075 __ Push(Operand(rbp, calleeOffset));
1076 __ Push(rax);
1077 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1078
1079 __ bind(&okay);
1080 }
1081
1082
1083 static void Generate_PushAppliedArguments(MacroAssembler* masm, 1102 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1084 const int argumentsOffset, 1103 const int argumentsOffset,
1085 const int indexOffset, 1104 const int indexOffset,
1086 const int limitOffset) { 1105 const int limitOffset) {
1087 Register receiver = LoadDescriptor::ReceiverRegister(); 1106 Register receiver = LoadDescriptor::ReceiverRegister();
1088 Register key = LoadDescriptor::NameRegister(); 1107 Register key = LoadDescriptor::NameRegister();
1089 1108
1090 // Copy all arguments from the array to the stack. 1109 // Copy all arguments from the array to the stack.
1091 Label entry, loop; 1110 Label entry, loop;
1092 __ movp(key, Operand(rbp, indexOffset)); 1111 __ movp(key, Operand(rbp, indexOffset));
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1150 static const int kFunctionOffset = kReceiverOffset + kPointerSize; 1169 static const int kFunctionOffset = kReceiverOffset + kPointerSize;
1151 1170
1152 __ Push(Operand(rbp, kFunctionOffset)); 1171 __ Push(Operand(rbp, kFunctionOffset));
1153 __ Push(Operand(rbp, kArgumentsOffset)); 1172 __ Push(Operand(rbp, kArgumentsOffset));
1154 if (targetIsArgument) { 1173 if (targetIsArgument) {
1155 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); 1174 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1156 } else { 1175 } else {
1157 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1176 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1158 } 1177 }
1159 1178
1160 Generate_CheckStackOverflow(masm, kFunctionOffset); 1179 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
1161 1180
1162 // Push current index and limit. 1181 // Push current index and limit.
1163 const int kLimitOffset = 1182 const int kLimitOffset =
1164 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; 1183 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
1165 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; 1184 const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
1166 __ Push(rax); // limit 1185 __ Push(rax); // limit
1167 __ Push(Immediate(0)); // index 1186 __ Push(Immediate(0)); // index
1168 1187
1169 // Get the receiver. 1188 // Get the receiver.
1170 __ movp(rbx, Operand(rbp, kReceiverOffset)); 1189 __ movp(rbx, Operand(rbp, kReceiverOffset));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 __ movp(rax, Operand(rbp, kFunctionOffset)); 1298 __ movp(rax, Operand(rbp, kFunctionOffset));
1280 __ movp(Operand(rbp, kNewTargetOffset), rax); 1299 __ movp(Operand(rbp, kNewTargetOffset), rax);
1281 1300
1282 // Validate arguments 1301 // Validate arguments
1283 __ bind(&validate_arguments); 1302 __ bind(&validate_arguments);
1284 __ Push(Operand(rbp, kFunctionOffset)); 1303 __ Push(Operand(rbp, kFunctionOffset));
1285 __ Push(Operand(rbp, kArgumentsOffset)); 1304 __ Push(Operand(rbp, kArgumentsOffset));
1286 __ Push(Operand(rbp, kNewTargetOffset)); 1305 __ Push(Operand(rbp, kNewTargetOffset));
1287 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); 1306 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1288 1307
1289 Generate_CheckStackOverflow(masm, kFunctionOffset); 1308 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged);
1290 1309
1291 // Push current index and limit. 1310 // Push current index and limit.
1292 const int kLimitOffset = 1311 const int kLimitOffset =
1293 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize; 1312 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
1294 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; 1313 const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
1295 __ Push(rax); // limit 1314 __ Push(rax); // limit
1296 __ Push(Immediate(0)); // index 1315 __ Push(Immediate(0)); // index
1297 // Push newTarget and callee functions 1316 // Push newTarget and callee functions
1298 __ Push(Operand(rbp, kNewTargetOffset)); 1317 __ Push(Operand(rbp, kNewTargetOffset));
1299 __ Push(Operand(rbp, kFunctionOffset)); 1318 __ Push(Operand(rbp, kFunctionOffset));
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 __ bind(&ok); 1748 __ bind(&ok);
1730 __ ret(0); 1749 __ ret(0);
1731 } 1750 }
1732 1751
1733 1752
1734 #undef __ 1753 #undef __
1735 1754
1736 } } // namespace v8::internal 1755 } } // namespace v8::internal
1737 1756
1738 #endif // V8_TARGET_ARCH_X64 1757 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | test/mjsunit/regress/regress-crbug-469768.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698