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