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_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 // Leave construct frame. | 850 // Leave construct frame. |
851 } | 851 } |
852 | 852 |
853 __ SmiScale(at, a1, kPointerSizeLog2); | 853 __ SmiScale(at, a1, kPointerSizeLog2); |
854 __ Daddu(sp, sp, Operand(at)); | 854 __ Daddu(sp, sp, Operand(at)); |
855 __ Daddu(sp, sp, Operand(kPointerSize)); | 855 __ Daddu(sp, sp, Operand(kPointerSize)); |
856 __ Jump(ra); | 856 __ Jump(ra); |
857 } | 857 } |
858 | 858 |
859 | 859 |
| 860 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; |
| 861 |
| 862 |
| 863 // Clobbers a2; preserves all other registers. |
| 864 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 865 const int calleeOffset, Register argc, |
| 866 IsTagged argc_is_tagged) { |
| 867 // Check the stack for overflow. We are not trying to catch |
| 868 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 869 // limit" is checked. |
| 870 Label okay; |
| 871 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); |
| 872 // Make a2 the space we have left. The stack might already be overflowed |
| 873 // here which will cause r2 to become negative. |
| 874 __ dsubu(a2, sp, a2); |
| 875 // Check if the arguments will overflow the stack. |
| 876 if (argc_is_tagged == kArgcIsSmiTagged) { |
| 877 __ SmiScale(a7, v0, kPointerSizeLog2); |
| 878 } else { |
| 879 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); |
| 880 __ dsll(a7, argc, kPointerSizeLog2); |
| 881 } |
| 882 __ Branch(&okay, gt, a2, Operand(a7)); // Signed comparison. |
| 883 |
| 884 // Out of stack space. |
| 885 __ ld(a1, MemOperand(fp, calleeOffset)); |
| 886 if (argc_is_tagged == kArgcIsUntaggedInt) { |
| 887 __ SmiTag(argc); |
| 888 } |
| 889 __ Push(a1, argc); |
| 890 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 891 |
| 892 __ bind(&okay); |
| 893 } |
| 894 |
| 895 |
860 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 896 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
861 bool is_construct) { | 897 bool is_construct) { |
862 // Called from JSEntryStub::GenerateBody | 898 // Called from JSEntryStub::GenerateBody |
863 | 899 |
864 // ----------- S t a t e ------------- | 900 // ----------- S t a t e ------------- |
865 // -- a0: code entry | 901 // -- a0: code entry |
866 // -- a1: function | 902 // -- a1: function |
867 // -- a2: receiver_pointer | 903 // -- a2: receiver_pointer |
868 // -- a3: argc | 904 // -- a3: argc |
869 // -- s0: argv | 905 // -- s0: argv |
870 // ----------------------------------- | 906 // ----------------------------------- |
871 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 907 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
872 // Clear the context before we push it when entering the JS frame. | 908 // Clear the context before we push it when entering the JS frame. |
873 __ mov(cp, zero_reg); | 909 __ mov(cp, zero_reg); |
874 | 910 |
875 // Enter an internal frame. | 911 // Enter an internal frame. |
876 { | 912 { |
877 FrameScope scope(masm, StackFrame::INTERNAL); | 913 FrameScope scope(masm, StackFrame::INTERNAL); |
878 | 914 |
879 // Set up the context from the function argument. | 915 // Set up the context from the function argument. |
880 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 916 __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
881 | 917 |
882 // Push the function and the receiver onto the stack. | 918 // Push the function and the receiver onto the stack. |
883 __ Push(a1, a2); | 919 __ Push(a1, a2); |
884 | 920 |
| 921 // Check if we have enough stack space to push all arguments. |
| 922 // The function is the first thing that was pushed above after entering |
| 923 // the internal frame. |
| 924 const int kFunctionOffset = |
| 925 InternalFrameConstants::kCodeOffset - kPointerSize; |
| 926 // Clobbers a2. |
| 927 Generate_CheckStackOverflow(masm, kFunctionOffset, a3, kArgcIsUntaggedInt); |
| 928 |
885 // Copy arguments to the stack in a loop. | 929 // Copy arguments to the stack in a loop. |
886 // a3: argc | 930 // a3: argc |
887 // s0: argv, i.e. points to first arg | 931 // s0: argv, i.e. points to first arg |
888 Label loop, entry; | 932 Label loop, entry; |
889 __ dsll(a4, a3, kPointerSizeLog2); | 933 __ dsll(a4, a3, kPointerSizeLog2); |
890 __ daddu(a6, s0, a4); | 934 __ daddu(a6, s0, a4); |
891 __ b(&entry); | 935 __ b(&entry); |
892 __ nop(); // Branch delay slot nop. | 936 __ nop(); // Branch delay slot nop. |
893 // a6 points past last arg. | 937 // a6 points past last arg. |
894 __ bind(&loop); | 938 __ bind(&loop); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 // Check formal and actual parameter counts. | 1396 // Check formal and actual parameter counts. |
1353 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1397 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1354 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); | 1398 RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); |
1355 | 1399 |
1356 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1400 __ ld(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
1357 ParameterCount expected(0); | 1401 ParameterCount expected(0); |
1358 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1402 __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1359 } | 1403 } |
1360 | 1404 |
1361 | 1405 |
1362 static void Generate_CheckStackOverflow(MacroAssembler* masm, | |
1363 const int calleeOffset) { | |
1364 // Check the stack for overflow. We are not trying to catch | |
1365 // interruptions (e.g. debug break and preemption) here, so the "real stack | |
1366 // limit" is checked. | |
1367 Label okay; | |
1368 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); | |
1369 // Make a2 the space we have left. The stack might already be overflowed | |
1370 // here which will cause a2 to become negative. | |
1371 __ dsubu(a2, sp, a2); | |
1372 // Check if the arguments will overflow the stack. | |
1373 __ SmiScale(a7, v0, kPointerSizeLog2); | |
1374 __ Branch(&okay, gt, a2, Operand(a7)); // Signed comparison. | |
1375 | |
1376 // Out of stack space. | |
1377 __ ld(a1, MemOperand(fp, calleeOffset)); | |
1378 __ Push(a1, v0); | |
1379 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | |
1380 | |
1381 __ bind(&okay); | |
1382 } | |
1383 | |
1384 | |
1385 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1406 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
1386 const int argumentsOffset, | 1407 const int argumentsOffset, |
1387 const int indexOffset, | 1408 const int indexOffset, |
1388 const int limitOffset) { | 1409 const int limitOffset) { |
1389 Label entry, loop; | 1410 Label entry, loop; |
1390 __ ld(a0, MemOperand(fp, indexOffset)); | 1411 __ ld(a0, MemOperand(fp, indexOffset)); |
1391 __ Branch(&entry); | 1412 __ Branch(&entry); |
1392 | 1413 |
1393 // Load the current argument from the arguments array and push it to the | 1414 // Load the current argument from the arguments array and push it to the |
1394 // stack. | 1415 // stack. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 __ push(a0); | 1455 __ push(a0); |
1435 | 1456 |
1436 // Returns (in v0) number of arguments to copy to stack as Smi. | 1457 // Returns (in v0) number of arguments to copy to stack as Smi. |
1437 if (targetIsArgument) { | 1458 if (targetIsArgument) { |
1438 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1459 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1439 } else { | 1460 } else { |
1440 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1461 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1441 } | 1462 } |
1442 | 1463 |
1443 // Returns the result in v0. | 1464 // Returns the result in v0. |
1444 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1465 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1445 | 1466 |
1446 // Push current limit and index. | 1467 // Push current limit and index. |
1447 const int kIndexOffset = | 1468 const int kIndexOffset = |
1448 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1469 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1449 const int kLimitOffset = | 1470 const int kLimitOffset = |
1450 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1471 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1451 __ mov(a1, zero_reg); | 1472 __ mov(a1, zero_reg); |
1452 __ Push(v0, a1); // Limit and initial index. | 1473 __ Push(v0, a1); // Limit and initial index. |
1453 | 1474 |
1454 // Get the receiver. | 1475 // Get the receiver. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function | 1584 __ ld(a0, MemOperand(fp, kFunctionOffset)); // get the function |
1564 __ push(a0); | 1585 __ push(a0); |
1565 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array | 1586 __ ld(a0, MemOperand(fp, kArgumentsOffset)); // get the args array |
1566 __ push(a0); | 1587 __ push(a0); |
1567 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1588 __ ld(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1568 __ push(a0); | 1589 __ push(a0); |
1569 // Returns argument count in v0. | 1590 // Returns argument count in v0. |
1570 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1591 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1571 | 1592 |
1572 // Returns result in v0. | 1593 // Returns result in v0. |
1573 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1594 Generate_CheckStackOverflow(masm, kFunctionOffset, v0, kArgcIsSmiTagged); |
1574 | 1595 |
1575 // Push current limit and index. | 1596 // Push current limit and index. |
1576 const int kIndexOffset = | 1597 const int kIndexOffset = |
1577 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1598 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1578 const int kLimitOffset = | 1599 const int kLimitOffset = |
1579 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1600 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1580 __ push(v0); // limit | 1601 __ push(v0); // limit |
1581 __ mov(a1, zero_reg); // initial index | 1602 __ mov(a1, zero_reg); // initial index |
1582 __ push(a1); | 1603 __ push(a1); |
1583 // Push newTarget and callee functions | 1604 // Push newTarget and callee functions |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 __ break_(0xCC); | 1818 __ break_(0xCC); |
1798 } | 1819 } |
1799 } | 1820 } |
1800 | 1821 |
1801 | 1822 |
1802 #undef __ | 1823 #undef __ |
1803 | 1824 |
1804 } } // namespace v8::internal | 1825 } } // namespace v8::internal |
1805 | 1826 |
1806 #endif // V8_TARGET_ARCH_MIPS64 | 1827 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |