OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 // Leave construct frame. | 820 // Leave construct frame. |
821 } | 821 } |
822 | 822 |
823 __ SmiToPtrArrayOffset(r4, r4); | 823 __ SmiToPtrArrayOffset(r4, r4); |
824 __ add(sp, sp, r4); | 824 __ add(sp, sp, r4); |
825 __ addi(sp, sp, Operand(kPointerSize)); | 825 __ addi(sp, sp, Operand(kPointerSize)); |
826 __ blr(); | 826 __ blr(); |
827 } | 827 } |
828 | 828 |
829 | 829 |
| 830 enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt }; |
| 831 |
| 832 |
| 833 // Clobbers r5; preserves all other registers. |
| 834 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
| 835 const int calleeOffset, Register argc, |
| 836 IsTagged argc_is_tagged) { |
| 837 // Check the stack for overflow. We are not trying to catch |
| 838 // interruptions (e.g. debug break and preemption) here, so the "real stack |
| 839 // limit" is checked. |
| 840 Label okay; |
| 841 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); |
| 842 // Make r5 the space we have left. The stack might already be overflowed |
| 843 // here which will cause r5 to become negative. |
| 844 __ sub(r5, sp, r5); |
| 845 // Check if the arguments will overflow the stack. |
| 846 if (argc_is_tagged == kArgcIsSmiTagged) { |
| 847 __ SmiToPtrArrayOffset(r0, argc); |
| 848 } else { |
| 849 DCHECK(argc_is_tagged == kArgcIsUntaggedInt); |
| 850 __ ShiftLeftImm(r0, argc, Operand(kPointerSizeLog2)); |
| 851 } |
| 852 __ cmp(r5, r0); |
| 853 __ bgt(&okay); // Signed comparison. |
| 854 |
| 855 // Out of stack space. |
| 856 __ LoadP(r4, MemOperand(fp, calleeOffset)); |
| 857 if (argc_is_tagged == kArgcIsUntaggedInt) { |
| 858 __ SmiTag(argc); |
| 859 } |
| 860 __ Push(r4, argc); |
| 861 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); |
| 862 |
| 863 __ bind(&okay); |
| 864 } |
| 865 |
| 866 |
830 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 867 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
831 bool is_construct) { | 868 bool is_construct) { |
832 // Called from Generate_JS_Entry | 869 // Called from Generate_JS_Entry |
833 // r3: code entry | 870 // r3: code entry |
834 // r4: function | 871 // r4: function |
835 // r5: receiver | 872 // r5: receiver |
836 // r6: argc | 873 // r6: argc |
837 // r7: argv | 874 // r7: argv |
838 // r0,r8-r9, cp may be clobbered | 875 // r0,r8-r9, cp may be clobbered |
839 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 876 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
840 | 877 |
841 // Clear the context before we push it when entering the internal frame. | 878 // Clear the context before we push it when entering the internal frame. |
842 __ li(cp, Operand::Zero()); | 879 __ li(cp, Operand::Zero()); |
843 | 880 |
844 // Enter an internal frame. | 881 // Enter an internal frame. |
845 { | 882 { |
846 FrameScope scope(masm, StackFrame::INTERNAL); | 883 FrameScope scope(masm, StackFrame::INTERNAL); |
847 | 884 |
848 // Set up the context from the function argument. | 885 // Set up the context from the function argument. |
849 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); | 886 __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
850 | 887 |
851 __ InitializeRootRegister(); | 888 __ InitializeRootRegister(); |
852 | 889 |
853 // Push the function and the receiver onto the stack. | 890 // Push the function and the receiver onto the stack. |
854 __ push(r4); | 891 __ push(r4); |
855 __ push(r5); | 892 __ push(r5); |
856 | 893 |
| 894 // Check if we have enough stack space to push all arguments. |
| 895 // The function is the first thing that was pushed above after entering |
| 896 // the internal frame. |
| 897 const int kFunctionOffset = |
| 898 InternalFrameConstants::kCodeOffset - kPointerSize; |
| 899 // Clobbers r5. |
| 900 Generate_CheckStackOverflow(masm, kFunctionOffset, r6, kArgcIsUntaggedInt); |
| 901 |
857 // Copy arguments to the stack in a loop. | 902 // Copy arguments to the stack in a loop. |
858 // r4: function | 903 // r4: function |
859 // r6: argc | 904 // r6: argc |
860 // r7: argv, i.e. points to first arg | 905 // r7: argv, i.e. points to first arg |
861 Label loop, entry; | 906 Label loop, entry; |
862 __ ShiftLeftImm(r0, r6, Operand(kPointerSizeLog2)); | 907 __ ShiftLeftImm(r0, r6, Operand(kPointerSizeLog2)); |
863 __ add(r5, r7, r0); | 908 __ add(r5, r7, r0); |
864 // r5 points past last arg. | 909 // r5 points past last arg. |
865 __ b(&entry); | 910 __ b(&entry); |
866 __ bind(&loop); | 911 __ bind(&loop); |
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 __ cmp(r5, r3); // Check formal and actual parameter counts. | 1404 __ cmp(r5, r3); // Check formal and actual parameter counts. |
1360 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 1405 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
1361 RelocInfo::CODE_TARGET, ne); | 1406 RelocInfo::CODE_TARGET, ne); |
1362 | 1407 |
1363 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); | 1408 __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset)); |
1364 ParameterCount expected(0); | 1409 ParameterCount expected(0); |
1365 __ InvokeCode(ip, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 1410 __ InvokeCode(ip, expected, expected, JUMP_FUNCTION, NullCallWrapper()); |
1366 } | 1411 } |
1367 | 1412 |
1368 | 1413 |
1369 static void Generate_CheckStackOverflow(MacroAssembler* masm, | |
1370 const int calleeOffset) { | |
1371 // Check the stack for overflow. We are not trying to catch | |
1372 // interruptions (e.g. debug break and preemption) here, so the "real stack | |
1373 // limit" is checked. | |
1374 Label okay; | |
1375 __ LoadRoot(r5, Heap::kRealStackLimitRootIndex); | |
1376 // Make r5 the space we have left. The stack might already be overflowed | |
1377 // here which will cause r5 to become negative. | |
1378 __ sub(r5, sp, r5); | |
1379 // Check if the arguments will overflow the stack. | |
1380 __ SmiToPtrArrayOffset(r0, r3); | |
1381 __ cmp(r5, r0); | |
1382 __ bgt(&okay); // Signed comparison. | |
1383 | |
1384 // Out of stack space. | |
1385 __ LoadP(r4, MemOperand(fp, calleeOffset)); | |
1386 __ Push(r4, r3); | |
1387 __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); | |
1388 | |
1389 __ bind(&okay); | |
1390 } | |
1391 | |
1392 | |
1393 static void Generate_PushAppliedArguments(MacroAssembler* masm, | 1414 static void Generate_PushAppliedArguments(MacroAssembler* masm, |
1394 const int argumentsOffset, | 1415 const int argumentsOffset, |
1395 const int indexOffset, | 1416 const int indexOffset, |
1396 const int limitOffset) { | 1417 const int limitOffset) { |
1397 Label entry, loop; | 1418 Label entry, loop; |
1398 __ LoadP(r3, MemOperand(fp, indexOffset)); | 1419 __ LoadP(r3, MemOperand(fp, indexOffset)); |
1399 __ b(&entry); | 1420 __ b(&entry); |
1400 | 1421 |
1401 // Load the current argument from the arguments array and push it to the | 1422 // Load the current argument from the arguments array and push it to the |
1402 // stack. | 1423 // stack. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function | 1461 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function |
1441 __ push(r3); | 1462 __ push(r3); |
1442 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array | 1463 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array |
1443 __ push(r3); | 1464 __ push(r3); |
1444 if (targetIsArgument) { | 1465 if (targetIsArgument) { |
1445 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); | 1466 __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); |
1446 } else { | 1467 } else { |
1447 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 1468 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
1448 } | 1469 } |
1449 | 1470 |
1450 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1471 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsSmiTagged); |
1451 | 1472 |
1452 // Push current limit and index. | 1473 // Push current limit and index. |
1453 const int kIndexOffset = | 1474 const int kIndexOffset = |
1454 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1475 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1455 const int kLimitOffset = | 1476 const int kLimitOffset = |
1456 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1477 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1457 __ li(r4, Operand::Zero()); | 1478 __ li(r4, Operand::Zero()); |
1458 __ Push(r3, r4); // limit and initial index. | 1479 __ Push(r3, r4); // limit and initial index. |
1459 | 1480 |
1460 // Get the receiver. | 1481 // Get the receiver. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 // Validate arguments | 1598 // Validate arguments |
1578 __ bind(&validate_arguments); | 1599 __ bind(&validate_arguments); |
1579 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function | 1600 __ LoadP(r3, MemOperand(fp, kFunctionOffset)); // get the function |
1580 __ push(r3); | 1601 __ push(r3); |
1581 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array | 1602 __ LoadP(r3, MemOperand(fp, kArgumentsOffset)); // get the args array |
1582 __ push(r3); | 1603 __ push(r3); |
1583 __ LoadP(r3, MemOperand(fp, kNewTargetOffset)); // get the new.target | 1604 __ LoadP(r3, MemOperand(fp, kNewTargetOffset)); // get the new.target |
1584 __ push(r3); | 1605 __ push(r3); |
1585 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); | 1606 __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); |
1586 | 1607 |
1587 Generate_CheckStackOverflow(masm, kFunctionOffset); | 1608 Generate_CheckStackOverflow(masm, kFunctionOffset, r3, kArgcIsSmiTagged); |
1588 | 1609 |
1589 // Push current limit and index. | 1610 // Push current limit and index. |
1590 const int kIndexOffset = | 1611 const int kIndexOffset = |
1591 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 1612 StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); |
1592 const int kLimitOffset = | 1613 const int kLimitOffset = |
1593 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 1614 StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); |
1594 __ li(r4, Operand::Zero()); | 1615 __ li(r4, Operand::Zero()); |
1595 __ Push(r3, r4); // limit and initial index. | 1616 __ Push(r3, r4); // limit and initial index. |
1596 // Push newTarget and callee functions | 1617 // Push newTarget and callee functions |
1597 __ LoadP(r3, MemOperand(fp, kNewTargetOffset)); | 1618 __ LoadP(r3, MemOperand(fp, kNewTargetOffset)); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 __ bkpt(0); | 1824 __ bkpt(0); |
1804 } | 1825 } |
1805 } | 1826 } |
1806 | 1827 |
1807 | 1828 |
1808 #undef __ | 1829 #undef __ |
1809 } | 1830 } |
1810 } // namespace v8::internal | 1831 } // namespace v8::internal |
1811 | 1832 |
1812 #endif // V8_TARGET_ARCH_PPC | 1833 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |