| 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 |