| 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.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 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 695 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); | 695 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); |
| 696 __ add(sp, sp, Operand(kPointerSize)); | 696 __ add(sp, sp, Operand(kPointerSize)); |
| 697 __ Jump(lr); | 697 __ Jump(lr); |
| 698 } | 698 } |
| 699 | 699 |
| 700 | 700 |
| 701 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; | 701 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; |
| 702 | 702 |
| 703 | 703 |
| 704 // Clobbers r2; preserves all other registers. | 704 // Clobbers r2; preserves all other registers. |
| 705 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 705 static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc, |
| 706 const int calleeOffset, Register argc, | |
| 707 IsTagged argc_is_tagged) { | 706 IsTagged argc_is_tagged) { |
| 708 // Check the stack for overflow. We are not trying to catch | 707 // Check the stack for overflow. We are not trying to catch |
| 709 // interruptions (e.g. debug break and preemption) here, so the "real stack | 708 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 710 // limit" is checked. | 709 // limit" is checked. |
| 711 Label okay; | 710 Label okay; |
| 712 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex); | 711 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex); |
| 713 // Make r2 the space we have left. The stack might already be overflowed | 712 // Make r2 the space we have left. The stack might already be overflowed |
| 714 // here which will cause r2 to become negative. | 713 // here which will cause r2 to become negative. |
| 715 __ sub(r2, sp, r2); | 714 __ sub(r2, sp, r2); |
| 716 // Check if the arguments will overflow the stack. | 715 // Check if the arguments will overflow the stack. |
| 717 if (argc_is_tagged == kArgcIsSmiTagged) { | 716 if (argc_is_tagged == kArgcIsSmiTagged) { |
| 718 __ cmp(r2, Operand::PointerOffsetFromSmiKey(argc)); | 717 __ cmp(r2, Operand::PointerOffsetFromSmiKey(argc)); |
| 719 } else { | 718 } else { |
| 720 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); | 719 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); |
| 721 __ cmp(r2, Operand(argc, LSL, kPointerSizeLog2)); | 720 __ cmp(r2, Operand(argc, LSL, kPointerSizeLog2)); |
| 722 } | 721 } |
| 723 __ b(gt, &okay); // Signed comparison. | 722 __ b(gt, &okay); // Signed comparison. |
| 724 | 723 |
| 725 // Out of stack space. | 724 // Out of stack space. |
| 726 __ ldr(r1, MemOperand(fp, calleeOffset)); | |
| 727 if (argc_is_tagged == kArgcIsUntaggedInt) { | |
| 728 __ SmiTag(argc); | |
| 729 } | |
| 730 __ Push(r1, argc); | |
| 731 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 725 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
| 732 | 726 |
| 733 __ bind(&okay); | 727 __ bind(&okay); |
| 734 } | 728 } |
| 735 | 729 |
| 736 | 730 |
| 737 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 731 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
| 738 bool is_construct) { | 732 bool is_construct) { |
| 739 // Called from Generate_JS_Entry | 733 // Called from Generate_JS_Entry |
| 740 // r0: new.target | 734 // r0: new.target |
| (...skipping 16 matching lines...) Expand all Loading... |
| 757 masm->isolate()); | 751 masm->isolate()); |
| 758 __ mov(cp, Operand(context_address)); | 752 __ mov(cp, Operand(context_address)); |
| 759 __ ldr(cp, MemOperand(cp)); | 753 __ ldr(cp, MemOperand(cp)); |
| 760 | 754 |
| 761 __ InitializeRootRegister(); | 755 __ InitializeRootRegister(); |
| 762 | 756 |
| 763 // Push the function and the receiver onto the stack. | 757 // Push the function and the receiver onto the stack. |
| 764 __ Push(r1, r2); | 758 __ Push(r1, r2); |
| 765 | 759 |
| 766 // Check if we have enough stack space to push all arguments. | 760 // Check if we have enough stack space to push all arguments. |
| 767 // The function is the first thing that was pushed above after entering | |
| 768 // the internal frame. | |
| 769 const int kFunctionOffset = | |
| 770 InternalFrameConstants::kCodeOffset - kPointerSize; | |
| 771 // Clobbers r2. | 761 // Clobbers r2. |
| 772 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsUntaggedInt); | 762 Generate_CheckStackOverflow(masm, r3, kArgcIsUntaggedInt); |
| 773 | 763 |
| 774 // Remember new.target. | 764 // Remember new.target. |
| 775 __ mov(r5, r0); | 765 __ mov(r5, r0); |
| 776 | 766 |
| 777 // Copy arguments to the stack in a loop. | 767 // Copy arguments to the stack in a loop. |
| 778 // r1: function | 768 // r1: function |
| 779 // r3: argc | 769 // r3: argc |
| 780 // r4: argv, i.e. points to first arg | 770 // r4: argv, i.e. points to first arg |
| 781 Label loop, entry; | 771 Label loop, entry; |
| 782 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); | 772 __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function | 1321 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function |
| 1332 __ ldr(r1, MemOperand(fp, kArgumentsOffset)); // get the args array | 1322 __ ldr(r1, MemOperand(fp, kArgumentsOffset)); // get the args array |
| 1333 __ Push(r0, r1); | 1323 __ Push(r0, r1); |
| 1334 if (targetIsArgument) { | 1324 if (targetIsArgument) { |
| 1335 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, | 1325 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, |
| 1336 CALL_FUNCTION); | 1326 CALL_FUNCTION); |
| 1337 } else { | 1327 } else { |
| 1338 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); | 1328 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); |
| 1339 } | 1329 } |
| 1340 | 1330 |
| 1341 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); | 1331 Generate_CheckStackOverflow(masm, r0, kArgcIsSmiTagged); |
| 1342 | 1332 |
| 1343 // Push current limit and index. | 1333 // Push current limit and index. |
| 1344 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); | 1334 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
| 1345 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); | 1335 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
| 1346 __ mov(r1, Operand::Zero()); | 1336 __ mov(r1, Operand::Zero()); |
| 1347 __ ldr(r2, MemOperand(fp, kReceiverOffset)); | 1337 __ ldr(r2, MemOperand(fp, kReceiverOffset)); |
| 1348 __ Push(r0, r1, r2); // limit, initial index and receiver. | 1338 __ Push(r0, r1, r2); // limit, initial index and receiver. |
| 1349 | 1339 |
| 1350 // Copy all arguments from the array to the stack. | 1340 // Copy all arguments from the array to the stack. |
| 1351 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, | 1341 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 __ bind(&validate_arguments); | 1382 __ bind(&validate_arguments); |
| 1393 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function | 1383 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function |
| 1394 __ push(r0); | 1384 __ push(r0); |
| 1395 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1385 __ ldr(r0, MemOperand(fp, kArgumentsOffset)); // get the args array |
| 1396 __ push(r0); | 1386 __ push(r0); |
| 1397 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1387 __ ldr(r0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
| 1398 __ push(r0); | 1388 __ push(r0); |
| 1399 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, | 1389 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, |
| 1400 CALL_FUNCTION); | 1390 CALL_FUNCTION); |
| 1401 | 1391 |
| 1402 Generate_CheckStackOverflow(masm, kFunctionOffset, r0, kArgcIsSmiTagged); | 1392 Generate_CheckStackOverflow(masm, r0, kArgcIsSmiTagged); |
| 1403 | 1393 |
| 1404 // Push current limit and index. | 1394 // Push current limit and index. |
| 1405 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); | 1395 const int kIndexOffset = kVectorOffset - (2 * kPointerSize); |
| 1406 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); | 1396 const int kLimitOffset = kVectorOffset - (1 * kPointerSize); |
| 1407 __ push(r0); // limit | 1397 __ push(r0); // limit |
| 1408 __ mov(r1, Operand::Zero()); // initial index | 1398 __ mov(r1, Operand::Zero()); // initial index |
| 1409 __ push(r1); | 1399 __ push(r1); |
| 1410 // Push the constructor function as callee. | 1400 // Push the constructor function as callee. |
| 1411 __ ldr(r0, MemOperand(fp, kFunctionOffset)); | 1401 __ ldr(r0, MemOperand(fp, kFunctionOffset)); |
| 1412 __ push(r0); | 1402 __ push(r0); |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1863 } | 1853 } |
| 1864 } | 1854 } |
| 1865 | 1855 |
| 1866 | 1856 |
| 1867 #undef __ | 1857 #undef __ |
| 1868 | 1858 |
| 1869 } // namespace internal | 1859 } // namespace internal |
| 1870 } // namespace v8 | 1860 } // namespace v8 |
| 1871 | 1861 |
| 1872 #endif // V8_TARGET_ARCH_ARM | 1862 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |