OLD | NEW |
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_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.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 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 __ PushReturnAddressFrom(rcx); | 443 __ PushReturnAddressFrom(rcx); |
444 __ ret(0); | 444 __ ret(0); |
445 } | 445 } |
446 | 446 |
447 | 447 |
448 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; | 448 enum IsTagged { kRaxIsSmiTagged, kRaxIsUntaggedInt }; |
449 | 449 |
450 | 450 |
451 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. | 451 // Clobbers rcx, r11, kScratchRegister; preserves all other registers. |
452 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 452 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
453 const int calleeOffset, | |
454 IsTagged rax_is_tagged) { | 453 IsTagged rax_is_tagged) { |
455 // rax : the number of items to be pushed to the stack | 454 // rax : the number of items to be pushed to the stack |
456 // | 455 // |
457 // Check the stack for overflow. We are not trying to catch | 456 // Check the stack for overflow. We are not trying to catch |
458 // interruptions (e.g. debug break and preemption) here, so the "real stack | 457 // interruptions (e.g. debug break and preemption) here, so the "real stack |
459 // limit" is checked. | 458 // limit" is checked. |
460 Label okay; | 459 Label okay; |
461 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); | 460 __ LoadRoot(kScratchRegister, Heap::kRealStackLimitRootIndex); |
462 __ movp(rcx, rsp); | 461 __ movp(rcx, rsp); |
463 // Make rcx the space we have left. The stack might already be overflowed | 462 // Make rcx the space we have left. The stack might already be overflowed |
464 // here which will cause rcx to become negative. | 463 // here which will cause rcx to become negative. |
465 __ subp(rcx, kScratchRegister); | 464 __ subp(rcx, kScratchRegister); |
466 // Make r11 the space we need for the array when it is unrolled onto the | 465 // Make r11 the space we need for the array when it is unrolled onto the |
467 // stack. | 466 // stack. |
468 if (rax_is_tagged == kRaxIsSmiTagged) { | 467 if (rax_is_tagged == kRaxIsSmiTagged) { |
469 __ PositiveSmiTimesPowerOfTwoToInteger64(r11, rax, kPointerSizeLog2); | 468 __ PositiveSmiTimesPowerOfTwoToInteger64(r11, rax, kPointerSizeLog2); |
470 } else { | 469 } else { |
471 DCHECK(rax_is_tagged == kRaxIsUntaggedInt); | 470 DCHECK(rax_is_tagged == kRaxIsUntaggedInt); |
472 __ movp(r11, rax); | 471 __ movp(r11, rax); |
473 __ shlq(r11, Immediate(kPointerSizeLog2)); | 472 __ shlq(r11, Immediate(kPointerSizeLog2)); |
474 } | 473 } |
475 // Check if the arguments will overflow the stack. | 474 // Check if the arguments will overflow the stack. |
476 __ cmpp(rcx, r11); | 475 __ cmpp(rcx, r11); |
477 __ j(greater, &okay); // Signed comparison. | 476 __ j(greater, &okay); // Signed comparison. |
478 | 477 |
479 // Out of stack space. | 478 // Out of stack space. |
480 __ Push(Operand(rbp, calleeOffset)); | |
481 if (rax_is_tagged == kRaxIsUntaggedInt) { | |
482 __ Integer32ToSmi(rax, rax); | |
483 } | |
484 __ Push(rax); | |
485 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 479 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
486 | 480 |
487 __ bind(&okay); | 481 __ bind(&okay); |
488 } | 482 } |
489 | 483 |
490 | 484 |
491 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 485 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
492 bool is_construct) { | 486 bool is_construct) { |
493 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 487 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
494 | 488 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 // [rsp + kPointerSize] : function | 575 // [rsp + kPointerSize] : function |
582 // [rsp] : receiver | 576 // [rsp] : receiver |
583 // Current register contents: | 577 // Current register contents: |
584 // rax : argc | 578 // rax : argc |
585 // rbx : argv | 579 // rbx : argv |
586 // rsi : context | 580 // rsi : context |
587 // rdi : function | 581 // rdi : function |
588 // rdx : new.target | 582 // rdx : new.target |
589 | 583 |
590 // Check if we have enough stack space to push all arguments. | 584 // Check if we have enough stack space to push all arguments. |
591 // The function is the first thing that was pushed above after entering | |
592 // the internal frame. | |
593 const int kFunctionOffset = | |
594 InternalFrameConstants::kCodeOffset - kRegisterSize; | |
595 // Expects argument count in rax. Clobbers rcx, r11. | 585 // Expects argument count in rax. Clobbers rcx, r11. |
596 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsUntaggedInt); | 586 Generate_CheckStackOverflow(masm, kRaxIsUntaggedInt); |
597 | 587 |
598 // Copy arguments to the stack in a loop. | 588 // Copy arguments to the stack in a loop. |
599 // Register rbx points to array of pointers to handle locations. | 589 // Register rbx points to array of pointers to handle locations. |
600 // Push the values of these handles. | 590 // Push the values of these handles. |
601 Label loop, entry; | 591 Label loop, entry; |
602 __ Set(rcx, 0); // Set loop variable to 0. | 592 __ Set(rcx, 0); // Set loop variable to 0. |
603 __ jmp(&entry, Label::kNear); | 593 __ jmp(&entry, Label::kNear); |
604 __ bind(&loop); | 594 __ bind(&loop); |
605 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); | 595 __ movp(kScratchRegister, Operand(rbx, rcx, times_pointer_size, 0)); |
606 __ Push(Operand(kScratchRegister, 0)); // dereference handle | 596 __ Push(Operand(kScratchRegister, 0)); // dereference handle |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 | 1089 |
1100 __ Push(Operand(rbp, kFunctionOffset)); | 1090 __ Push(Operand(rbp, kFunctionOffset)); |
1101 __ Push(Operand(rbp, kArgumentsOffset)); | 1091 __ Push(Operand(rbp, kArgumentsOffset)); |
1102 if (targetIsArgument) { | 1092 if (targetIsArgument) { |
1103 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1093 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
1104 CALL_FUNCTION); | 1094 CALL_FUNCTION); |
1105 } else { | 1095 } else { |
1106 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1096 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
1107 } | 1097 } |
1108 | 1098 |
1109 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1099 Generate_CheckStackOverflow(masm, kRaxIsSmiTagged); |
1110 | 1100 |
1111 // Push current index and limit, and receiver. | 1101 // Push current index and limit, and receiver. |
1112 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; | 1102 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1113 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1103 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1114 __ Push(rax); // limit | 1104 __ Push(rax); // limit |
1115 __ Push(Immediate(0)); // index | 1105 __ Push(Immediate(0)); // index |
1116 __ Push(Operand(rbp, kReceiverOffset)); // receiver | 1106 __ Push(Operand(rbp, kReceiverOffset)); // receiver |
1117 | 1107 |
1118 // Loop over the arguments array, pushing each value to the stack | 1108 // Loop over the arguments array, pushing each value to the stack |
1119 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, | 1109 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 __ movp(Operand(rbp, kNewTargetOffset), rax); | 1159 __ movp(Operand(rbp, kNewTargetOffset), rax); |
1170 | 1160 |
1171 // Validate arguments | 1161 // Validate arguments |
1172 __ bind(&validate_arguments); | 1162 __ bind(&validate_arguments); |
1173 __ Push(Operand(rbp, kFunctionOffset)); | 1163 __ Push(Operand(rbp, kFunctionOffset)); |
1174 __ Push(Operand(rbp, kArgumentsOffset)); | 1164 __ Push(Operand(rbp, kArgumentsOffset)); |
1175 __ Push(Operand(rbp, kNewTargetOffset)); | 1165 __ Push(Operand(rbp, kNewTargetOffset)); |
1176 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1166 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
1177 CALL_FUNCTION); | 1167 CALL_FUNCTION); |
1178 | 1168 |
1179 Generate_CheckStackOverflow(masm, kFunctionOffset, kRaxIsSmiTagged); | 1169 Generate_CheckStackOverflow(masm, kRaxIsSmiTagged); |
1180 | 1170 |
1181 // Push current index and limit. | 1171 // Push current index and limit. |
1182 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; | 1172 const int kLimitOffset = kVectorOffset - 1 * kPointerSize; |
1183 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; | 1173 const int kIndexOffset = kLimitOffset - 1 * kPointerSize; |
1184 __ Push(rax); // limit | 1174 __ Push(rax); // limit |
1185 __ Push(Immediate(0)); // index | 1175 __ Push(Immediate(0)); // index |
1186 // Push the constructor function as callee. | 1176 // Push the constructor function as callee. |
1187 __ Push(Operand(rbp, kFunctionOffset)); | 1177 __ Push(Operand(rbp, kFunctionOffset)); |
1188 | 1178 |
1189 // Loop over the arguments array, pushing each value to the stack | 1179 // Loop over the arguments array, pushing each value to the stack |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 __ ret(0); | 1904 __ ret(0); |
1915 } | 1905 } |
1916 | 1906 |
1917 | 1907 |
1918 #undef __ | 1908 #undef __ |
1919 | 1909 |
1920 } // namespace internal | 1910 } // namespace internal |
1921 } // namespace v8 | 1911 } // namespace v8 |
1922 | 1912 |
1923 #endif // V8_TARGET_ARCH_X64 | 1913 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |