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 __ Push(a1, argc); | |
Jakob Kummerow
2015/04/07 13:23:51
Note that argc needs to be smi-tagged here if it i
balazs.kilvady
2015/04/07 13:49:53
Done.
| |
877 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | |
878 | |
879 __ bind(&okay); | |
880 } | |
881 | |
882 | |
849 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 883 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
850 bool is_construct) { | 884 bool is_construct) { |
851 // Called from JSEntryStub::GenerateBody | 885 // Called from JSEntryStub::GenerateBody |
852 | 886 |
853 // ----------- S t a t e ------------- | 887 // ----------- S t a t e ------------- |
854 // -- a0: code entry | 888 // -- a0: code entry |
855 // -- a1: function | 889 // -- a1: function |
856 // -- a2: receiver_pointer | 890 // -- a2: receiver_pointer |
857 // -- a3: argc | 891 // -- a3: argc |
858 // -- s0: argv | 892 // -- s0: argv |
859 // ----------------------------------- | 893 // ----------------------------------- |
860 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 894 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
861 | 895 |
862 // Clear the context before we push it when entering the JS frame. | 896 // Clear the context before we push it when entering the JS frame. |
863 __ mov(cp, zero_reg); | 897 __ mov(cp, zero_reg); |
864 | 898 |
865 // Enter an internal frame. | 899 // Enter an internal frame. |
866 { | 900 { |
867 FrameScope scope(masm, StackFrame::INTERNAL); | 901 FrameScope scope(masm, StackFrame::INTERNAL); |
868 | 902 |
869 // Set up the context from the function argument. | 903 // Set up the context from the function argument. |
870 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 904 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
871 | 905 |
872 // Push the function and the receiver onto the stack. | 906 // Push the function and the receiver onto the stack. |
873 __ Push(a1, a2); | 907 __ Push(a1, a2); |
874 | 908 |
909 // Check if we have enough stack space to push all arguments. | |
910 // The function is the first thing that was pushed above after entering | |
911 // the internal frame. | |
912 const int kFunctionOffset = | |
913 InternalFrameConstants::kCodeOffset - kPointerSize; | |
914 // Clobbers a2. | |
915 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); | |
916 | |
875 // Copy arguments to the stack in a loop. | 917 // Copy arguments to the stack in a loop. |
876 // a3: argc | 918 // a3: argc |
877 // s0: argv, i.e. points to first arg | 919 // s0: argv, i.e. points to first arg |
878 Label loop, entry; | 920 Label loop, entry; |
879 __ sll(t0, a3, kPointerSizeLog2); | 921 __ sll(t0, a3, kPointerSizeLog2); |
880 __ addu(t2, s0, t0); | 922 __ addu(t2, s0, t0); |
881 __ b(&entry); | 923 __ b(&entry); |
882 __ nop(); // Branch delay slot nop. | 924 __ nop(); // Branch delay slot nop. |
883 // t2 points past last arg. | 925 // t2 points past last arg. |
884 __ bind(&loop); | 926 __ bind(&loop); |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1344 // Check formal and actual parameter counts. | 1386 // Check formal and actual parameter counts. |
1345 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1387 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1346 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1388 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1347 | 1389 |
1348 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1390 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1349 ParameterCount expected(0); | 1391 ParameterCount expected(0); |
1350 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1392 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1351 } | 1393 } |
1352 | 1394 |
1353 | 1395 |
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, | 1396 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
1379 const int argumentsOffset, | 1397 const int argumentsOffset, |
1380 const int indexOffset, | 1398 const int indexOffset, |
1381 const int limitOffset) { | 1399 const int limitOffset) { |
1382 Label entry, loop; | 1400 Label entry, loop; |
1383 __ lw(a0, MemOperand(fp, indexOffset)); | 1401 __ lw(a0, MemOperand(fp, indexOffset)); |
1384 __ Branch(&entry); | 1402 __ Branch(&entry); |
1385 | 1403 |
1386 // Load the current argument from the arguments array and push it to the | 1404 // Load the current argument from the arguments array and push it to the |
1387 // stack. | 1405 // stack. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1426 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. | 1444 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. |
1427 __ push(a0); | 1445 __ push(a0); |
1428 // Returns (in v0) number of arguments to copy to stack as Smi. | 1446 // Returns (in v0) number of arguments to copy to stack as Smi. |
1429 if (targetIsArgument) { | 1447 if (targetIsArgument) { |
1430 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1448 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1431 } else { | 1449 } else { |
1432 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1450 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1433 } | 1451 } |
1434 | 1452 |
1435 // Returns the result in v0. | 1453 // Returns the result in v0. |
1436 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1454 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1437 | 1455 |
1438 // Push current limit and index. | 1456 // Push current limit and index. |
1439 const int kIndexOffset = | 1457 const int kIndexOffset = |
1440 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1458 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1441 const int kLimitOffset = | 1459 const int kLimitOffset = |
1442 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1460 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1443 __ mov(a1, zero_reg); | 1461 __ mov(a1, zero_reg); |
1444 __ Push(v0, a1); // Limit and initial index. | 1462 __ Push(v0, a1); // Limit and initial index. |
1445 | 1463 |
1446 // Get the receiver. | 1464 // 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 | 1573 __ lw(a0, MemOperand(fp, kFunctionOffset)); // get the function |
1556 __ push(a0); | 1574 __ push(a0); |
1557 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1575 __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1558 __ push(a0); | 1576 __ push(a0); |
1559 __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1577 __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1560 __ push(a0); | 1578 __ push(a0); |
1561 // Returns argument count in v0. | 1579 // Returns argument count in v0. |
1562 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1580 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1563 | 1581 |
1564 // Returns result in v0. | 1582 // Returns result in v0. |
1565 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1583 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1566 | 1584 |
1567 // Push current limit and index. | 1585 // Push current limit and index. |
1568 const int kIndexOffset = | 1586 const int kIndexOffset = |
1569 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1587 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1570 const int kLimitOffset = | 1588 const int kLimitOffset = |
1571 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1589 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1572 __ push(v0); // limit | 1590 __ push(v0); // limit |
1573 __ mov(a1, zero_reg); // initial index | 1591 __ mov(a1, zero_reg); // initial index |
1574 __ push(a1); | 1592 __ push(a1); |
1575 // Push newTarget and callee functions | 1593 // Push newTarget and callee functions |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1788 __ break_(0xCC); | 1806 __ break_(0xCC); |
1789 } | 1807 } |
1790 } | 1808 } |
1791 | 1809 |
1792 | 1810 |
1793 #undef __ | 1811 #undef __ |
1794 | 1812 |
1795 } } // namespace v8::internal | 1813 } } // namespace v8::internal |
1796 | 1814 |
1797 #endif // V8_TARGET_ARCH_MIPS | 1815 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |