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 | 5 |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS | 9 #if V8_TARGET_ARCH_MIPS |
10 | 10 |
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 // Leave construct frame. | 839 // Leave construct frame. |
840 } | 840 } |
841 | 841 |
842 __ sll(at, a1, kPointerSizeLog2 - 1); | 842 __ sll(at, a1, kPointerSizeLog2 - 1); |
843 __ Addu(sp, sp, Operand(at)); | 843 __ Addu(sp, sp, Operand(at)); |
844 __ Addu(sp, sp, Operand(kPointerSize)); | 844 __ Addu(sp, sp, Operand(kPointerSize)); |
845 __ Jump(ra); | 845 __ Jump(ra); |
846 } | 846 } |
847 | 847 |
848 | 848 |
| 849 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; |
| 850 |
| 851 |
| 852 // Clobbers a2; preserves all other registers. |
| 853 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 854 const int calleeOffset, Register argc, |
| 855 IsTagged argc_is_tagged) { |
| 856 // Check the stack for overflow. We are not trying to catch |
| 857 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 858 // limit" is checked. |
| 859 Label okay; |
| 860 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); |
| 861 // Make a2 the space we have left. The stack might already be overflowed |
| 862 // here which will cause r2 to become negative. |
| 863 __ Subu(a2, sp, a2); |
| 864 // Check if the arguments will overflow the stack. |
| 865 if (argc_is_tagged == kArgcIsSmiTagged) { |
| 866 __ sll(t3, argc, kPointerSizeLog2 - kSmiTagSize); |
| 867 } else { |
| 868 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); |
| 869 __ sll(t3, argc, kPointerSizeLog2); |
| 870 } |
| 871 // Signed comparison. |
| 872 __ Branch(&okay, gt, a2, Operand(t3)); |
| 873 |
| 874 // Out of stack space. |
| 875 __ lw(a1, MemOperand(fp, calleeOffset)); |
| 876 if (argc_is_tagged == kArgcIsUntaggedInt) { |
| 877 __ SmiTag(argc); |
| 878 } |
| 879 __ Push(a1, argc); |
| 880 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 881 |
| 882 __ bind(&okay); |
| 883 } |
| 884 |
| 885 |
849 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 886 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
850 bool is_construct) { | 887 bool is_construct) { |
851 // Called from JSEntryStub::GenerateBody | 888 // Called from JSEntryStub::GenerateBody |
852 | 889 |
853 // ----------- S t a t e ------------- | 890 // ----------- S t a t e ------------- |
854 // -- a0: code entry | 891 // -- a0: code entry |
855 // -- a1: function | 892 // -- a1: function |
856 // -- a2: receiver_pointer | 893 // -- a2: receiver_pointer |
857 // -- a3: argc | 894 // -- a3: argc |
858 // -- s0: argv | 895 // -- s0: argv |
859 // ----------------------------------- | 896 // ----------------------------------- |
860 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 897 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
861 | 898 |
862 // Clear the context before we push it when entering the JS frame. | 899 // Clear the context before we push it when entering the JS frame. |
863 __ mov(cp, zero_reg); | 900 __ mov(cp, zero_reg); |
864 | 901 |
865 // Enter an internal frame. | 902 // Enter an internal frame. |
866 { | 903 { |
867 FrameScope scope(masm, StackFrame::INTERNAL); | 904 FrameScope scope(masm, StackFrame::INTERNAL); |
868 | 905 |
869 // Set up the context from the function argument. | 906 // Set up the context from the function argument. |
870 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 907 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
871 | 908 |
872 // Push the function and the receiver onto the stack. | 909 // Push the function and the receiver onto the stack. |
873 __ Push(a1, a2); | 910 __ Push(a1, a2); |
874 | 911 |
| 912 // Check if we have enough stack space to push all arguments. |
| 913 // The function is the first thing that was pushed above after entering |
| 914 // the internal frame. |
| 915 const int kFunctionOffset = |
| 916 InternalFrameConstants::kCodeOffset - kPointerSize; |
| 917 // Clobbers a2. |
| 918 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); |
| 919 |
875 // Copy arguments to the stack in a loop. | 920 // Copy arguments to the stack in a loop. |
876 // a3: argc | 921 // a3: argc |
877 // s0: argv, i.e. points to first arg | 922 // s0: argv, i.e. points to first arg |
878 Label loop, entry; | 923 Label loop, entry; |
879 __ sll(t0, a3, kPointerSizeLog2); | 924 __ sll(t0, a3, kPointerSizeLog2); |
880 __ addu(t2, s0, t0); | 925 __ addu(t2, s0, t0); |
881 __ b(&entry); | 926 __ b(&entry); |
882 __ nop(); // Branch delay slot nop. | 927 __ nop(); // Branch delay slot nop. |
883 // t2 points past last arg. | 928 // t2 points past last arg. |
884 __ bind(&loop); | 929 __ bind(&loop); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 // Check formal and actual parameter counts. | 1389 // Check formal and actual parameter counts. |
1345 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1390 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1346 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1391 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1347 | 1392 |
1348 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1393 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1349 ParameterCount expected(0); | 1394 ParameterCount expected(0); |
1350 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1395 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1351 } | 1396 } |
1352 | 1397 |
1353 | 1398 |
1354 static void Generate_CheckStackOverflow(MacroAssembler* masm, | |
1355 const int calleeOffset) { | |
1356 // Check the stack for overflow. We are not trying to catch | |
1357 // interruptions (e.g. debug break and preemption) here, so the "real stack | |
1358 // limit" is checked. | |
1359 Label okay; | |
1360 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); | |
1361 // Make a2 the space we have left. The stack might already be overflowed | |
1362 // here which will cause a2 to become negative. | |
1363 __ Subu(a2, sp, a2); | |
1364 // Check if the arguments will overflow the stack. | |
1365 __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize); | |
1366 // Signed comparison. | |
1367 __ Branch(&okay, gt, a2, Operand(t3)); | |
1368 | |
1369 // Out of stack space. | |
1370 __ lw(a1, MemOperand(fp, calleeOffset)); | |
1371 __ Push(a1, v0); | |
1372 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | |
1373 | |
1374 __ bind(&okay); | |
1375 } | |
1376 | |
1377 | |
1378 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1399 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
1379 const int argumentsOffset, | 1400 const int argumentsOffset, |
1380 const int indexOffset, | 1401 const int indexOffset, |
1381 const int limitOffset) { | 1402 const int limitOffset) { |
1382 Label entry, loop; | 1403 Label entry, loop; |
1383 __ lw(a0, MemOperand(fp, indexOffset)); | 1404 __ lw(a0, MemOperand(fp, indexOffset)); |
1384 __ Branch(&entry); | 1405 __ Branch(&entry); |
1385 | 1406 |
1386 // Load the current argument from the arguments array and push it to the | 1407 // Load the current argument from the arguments array and push it to the |
1387 // stack. | 1408 // stack. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. | 1447 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. |
1427 __ push(a0); | 1448 __ push(a0); |
1428 // Returns (in v0) number of arguments to copy to stack as Smi. | 1449 // Returns (in v0) number of arguments to copy to stack as Smi. |
1429 if (targetIsArgument) { | 1450 if (targetIsArgument) { |
1430 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1451 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1431 } else { | 1452 } else { |
1432 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1453 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1433 } | 1454 } |
1434 | 1455 |
1435 // Returns the result in v0. | 1456 // Returns the result in v0. |
1436 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1457 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1437 | 1458 |
1438 // Push current limit and index. | 1459 // Push current limit and index. |
1439 const int kIndexOffset = | 1460 const int kIndexOffset = |
1440 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1461 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1441 const int kLimitOffset = | 1462 const int kLimitOffset = |
1442 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1463 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1443 __ mov(a1, zero_reg); | 1464 __ mov(a1, zero_reg); |
1444 __ Push(v0, a1); // Limit and initial index. | 1465 __ Push(v0, a1); // Limit and initial index. |
1445 | 1466 |
1446 // Get the receiver. | 1467 // Get the receiver. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 __ lw(a0, MemOperand(fp, kFunctionOffset)); // get the function | 1576 __ lw(a0, MemOperand(fp, kFunctionOffset)); // get the function |
1556 __ push(a0); | 1577 __ push(a0); |
1557 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1578 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1558 __ push(a0); | 1579 __ push(a0); |
1559 __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1580 __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1560 __ push(a0); | 1581 __ push(a0); |
1561 // Returns argument count in v0. | 1582 // Returns argument count in v0. |
1562 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1583 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1563 | 1584 |
1564 // Returns result in v0. | 1585 // Returns result in v0. |
1565 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1586 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1566 | 1587 |
1567 // Push current limit and index. | 1588 // Push current limit and index. |
1568 const int kIndexOffset = | 1589 const int kIndexOffset = |
1569 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1590 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1570 const int kLimitOffset = | 1591 const int kLimitOffset = |
1571 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1592 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1572 __ push(v0); // limit | 1593 __ push(v0); // limit |
1573 __ mov(a1, zero_reg); // initial index | 1594 __ mov(a1, zero_reg); // initial index |
1574 __ push(a1); | 1595 __ push(a1); |
1575 // Push newTarget and callee functions | 1596 // Push newTarget and callee functions |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 __ break_(0xCC); | 1809 __ break_(0xCC); |
1789 } | 1810 } |
1790 } | 1811 } |
1791 | 1812 |
1792 | 1813 |
1793 #undef __ | 1814 #undef __ |
1794 | 1815 |
1795 } } // namespace v8::internal | 1816 } } // namespace v8::internal |
1796 | 1817 |
1797 #endif // V8_TARGET_ARCH_MIPS | 1818 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |