OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 __ DropBySMI(x1); | 714 __ DropBySMI(x1); |
715 __ Drop(1); | 715 __ Drop(1); |
716 __ Ret(); | 716 __ Ret(); |
717 } | 717 } |
718 | 718 |
719 | 719 |
720 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; | 720 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; |
721 | 721 |
722 | 722 |
723 // Clobbers x10, x15; preserves all other registers. | 723 // Clobbers x10, x15; preserves all other registers. |
724 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 724 static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc, |
725 const int calleeOffset, Register argc, | |
726 IsTagged argc_is_tagged) { | 725 IsTagged argc_is_tagged) { |
727 Register function = x15; | |
728 | |
729 // Check the stack for overflow. | 726 // Check the stack for overflow. |
730 // We are not trying to catch interruptions (e.g. debug break and | 727 // We are not trying to catch interruptions (e.g. debug break and |
731 // preemption) here, so the "real stack limit" is checked. | 728 // preemption) here, so the "real stack limit" is checked. |
732 Label enough_stack_space; | 729 Label enough_stack_space; |
733 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); | 730 __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); |
734 __ Ldr(function, MemOperand(fp, calleeOffset)); | |
735 // Make x10 the space we have left. The stack might already be overflowed | 731 // Make x10 the space we have left. The stack might already be overflowed |
736 // here which will cause x10 to become negative. | 732 // here which will cause x10 to become negative. |
737 // TODO(jbramley): Check that the stack usage here is safe. | 733 // TODO(jbramley): Check that the stack usage here is safe. |
738 __ Sub(x10, jssp, x10); | 734 __ Sub(x10, jssp, x10); |
739 // Check if the arguments will overflow the stack. | 735 // Check if the arguments will overflow the stack. |
740 if (argc_is_tagged == kArgcIsSmiTagged) { | 736 if (argc_is_tagged == kArgcIsSmiTagged) { |
741 __ Cmp(x10, Operand::UntagSmiAndScale(argc, kPointerSizeLog2)); | 737 __ Cmp(x10, Operand::UntagSmiAndScale(argc, kPointerSizeLog2)); |
742 } else { | 738 } else { |
743 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); | 739 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); |
744 __ Cmp(x10, Operand(argc, LSL, kPointerSizeLog2)); | 740 __ Cmp(x10, Operand(argc, LSL, kPointerSizeLog2)); |
745 } | 741 } |
746 __ B(gt, &enough_stack_space); | 742 __ B(gt, &enough_stack_space); |
747 // There is not enough stack space, so use a builtin to throw an appropriate | |
748 // error. | |
749 if (argc_is_tagged == kArgcIsUntaggedInt) { | |
750 __ SmiTag(argc); | |
751 } | |
752 __ Push(function, argc); | |
753 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 743 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
754 // We should never return from the APPLY_OVERFLOW builtin. | 744 // We should never return from the APPLY_OVERFLOW builtin. |
755 if (__ emit_debug_code()) { | 745 if (__ emit_debug_code()) { |
756 __ Unreachable(); | 746 __ Unreachable(); |
757 } | 747 } |
758 | 748 |
759 __ Bind(&enough_stack_space); | 749 __ Bind(&enough_stack_space); |
760 } | 750 } |
761 | 751 |
762 | 752 |
(...skipping 28 matching lines...) Expand all Loading... |
791 __ Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, | 781 __ Mov(scratch, Operand(ExternalReference(Isolate::kContextAddress, |
792 masm->isolate()))); | 782 masm->isolate()))); |
793 __ Ldr(cp, MemOperand(scratch)); | 783 __ Ldr(cp, MemOperand(scratch)); |
794 | 784 |
795 __ InitializeRootRegister(); | 785 __ InitializeRootRegister(); |
796 | 786 |
797 // Push the function and the receiver onto the stack. | 787 // Push the function and the receiver onto the stack. |
798 __ Push(function, receiver); | 788 __ Push(function, receiver); |
799 | 789 |
800 // Check if we have enough stack space to push all arguments. | 790 // Check if we have enough stack space to push all arguments. |
801 // The function is the first thing that was pushed above after entering | |
802 // the internal frame. | |
803 const int kFunctionOffset = | |
804 InternalFrameConstants::kCodeOffset - kPointerSize; | |
805 // Expects argument count in eax. Clobbers ecx, edx, edi. | 791 // Expects argument count in eax. Clobbers ecx, edx, edi. |
806 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, | 792 Generate_CheckStackOverflow(masm, argc, kArgcIsUntaggedInt); |
807 kArgcIsUntaggedInt); | |
808 | 793 |
809 // Copy arguments to the stack in a loop, in reverse order. | 794 // Copy arguments to the stack in a loop, in reverse order. |
810 // x3: argc. | 795 // x3: argc. |
811 // x4: argv. | 796 // x4: argv. |
812 Label loop, entry; | 797 Label loop, entry; |
813 // Compute the copy end address. | 798 // Compute the copy end address. |
814 __ Add(scratch, argv, Operand(argc, LSL, kPointerSizeLog2)); | 799 __ Add(scratch, argv, Operand(argc, LSL, kPointerSizeLog2)); |
815 | 800 |
816 __ B(&entry); | 801 __ B(&entry); |
817 __ Bind(&loop); | 802 __ Bind(&loop); |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1388 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); | 1373 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); |
1389 __ Push(function, args); | 1374 __ Push(function, args); |
1390 if (targetIsArgument) { | 1375 if (targetIsArgument) { |
1391 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1376 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
1392 CALL_FUNCTION); | 1377 CALL_FUNCTION); |
1393 } else { | 1378 } else { |
1394 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1379 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
1395 } | 1380 } |
1396 Register argc = x0; | 1381 Register argc = x0; |
1397 | 1382 |
1398 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged); | 1383 Generate_CheckStackOverflow(masm, argc, kArgcIsSmiTagged); |
1399 | 1384 |
1400 // Push current limit, index and receiver. | 1385 // Push current limit, index and receiver. |
1401 __ Mov(x1, 0); // Initial index. | 1386 __ Mov(x1, 0); // Initial index. |
1402 __ Ldr(receiver, MemOperand(fp, kReceiverOffset)); | 1387 __ Ldr(receiver, MemOperand(fp, kReceiverOffset)); |
1403 __ Push(argc, x1, receiver); | 1388 __ Push(argc, x1, receiver); |
1404 | 1389 |
1405 // Copy all arguments from the array to the stack. | 1390 // Copy all arguments from the array to the stack. |
1406 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, | 1391 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1407 kIndexOffset, kLimitOffset); | 1392 kIndexOffset, kLimitOffset); |
1408 | 1393 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 // Validate arguments | 1444 // Validate arguments |
1460 __ Bind(&validate_arguments); | 1445 __ Bind(&validate_arguments); |
1461 __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 1446 __ Ldr(function, MemOperand(fp, kFunctionOffset)); |
1462 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); | 1447 __ Ldr(args, MemOperand(fp, kArgumentsOffset)); |
1463 __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset)); | 1448 __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset)); |
1464 __ Push(function, args, newTarget); | 1449 __ Push(function, args, newTarget); |
1465 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1450 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
1466 CALL_FUNCTION); | 1451 CALL_FUNCTION); |
1467 Register argc = x0; | 1452 Register argc = x0; |
1468 | 1453 |
1469 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged); | 1454 Generate_CheckStackOverflow(masm, argc, kArgcIsSmiTagged); |
1470 | 1455 |
1471 // Push current limit and index & constructor function as callee. | 1456 // Push current limit and index & constructor function as callee. |
1472 __ Mov(x1, 0); // Initial index. | 1457 __ Mov(x1, 0); // Initial index. |
1473 __ Push(argc, x1, function); | 1458 __ Push(argc, x1, function); |
1474 | 1459 |
1475 // Copy all arguments from the array to the stack. | 1460 // Copy all arguments from the array to the stack. |
1476 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, | 1461 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
1477 kIndexOffset, kLimitOffset); | 1462 kIndexOffset, kLimitOffset); |
1478 | 1463 |
1479 // Use undefined feedback vector | 1464 // Use undefined feedback vector |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 } | 1937 } |
1953 } | 1938 } |
1954 | 1939 |
1955 | 1940 |
1956 #undef __ | 1941 #undef __ |
1957 | 1942 |
1958 } // namespace internal | 1943 } // namespace internal |
1959 } // namespace v8 | 1944 } // namespace v8 |
1960 | 1945 |
1961 #endif // V8_TARGET_ARCH_ARM | 1946 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |