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