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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 } | 1375 } |
1376 __ Ret(); | 1376 __ Ret(); |
1377 } | 1377 } |
1378 | 1378 |
1379 | 1379 |
1380 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1380 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1381 Label* stack_overflow) { | 1381 Label* stack_overflow) { |
1382 // ----------- S t a t e ------------- | 1382 // ----------- S t a t e ------------- |
1383 // -- eax : actual number of arguments | 1383 // -- eax : actual number of arguments |
1384 // -- ebx : expected number of arguments | 1384 // -- ebx : expected number of arguments |
1385 // -- edi : function (passed through to callee) | 1385 // -- edx : new target (passed through to callee) |
1386 // ----------------------------------- | 1386 // ----------------------------------- |
1387 // Check the stack for overflow. We are not trying to catch | 1387 // Check the stack for overflow. We are not trying to catch |
1388 // interruptions (e.g. debug break and preemption) here, so the "real stack | 1388 // interruptions (e.g. debug break and preemption) here, so the "real stack |
1389 // limit" is checked. | 1389 // limit" is checked. |
1390 ExternalReference real_stack_limit = | 1390 ExternalReference real_stack_limit = |
1391 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 1391 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
1392 __ mov(edx, Operand::StaticVariable(real_stack_limit)); | 1392 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
1393 // Make ecx the space we have left. The stack might already be overflowed | 1393 // Make ecx the space we have left. The stack might already be overflowed |
1394 // here which will cause ecx to become negative. | 1394 // here which will cause ecx to become negative. |
1395 __ mov(ecx, esp); | 1395 __ mov(ecx, esp); |
1396 __ sub(ecx, edx); | 1396 __ sub(ecx, edi); |
1397 // Make edx the space we need for the array when it is unrolled onto the | 1397 // Make edi the space we need for the array when it is unrolled onto the |
1398 // stack. | 1398 // stack. |
1399 __ mov(edx, ebx); | 1399 __ mov(edi, ebx); |
1400 __ shl(edx, kPointerSizeLog2); | 1400 __ shl(edi, kPointerSizeLog2); |
1401 // Check if the arguments will overflow the stack. | 1401 // Check if the arguments will overflow the stack. |
1402 __ cmp(ecx, edx); | 1402 __ cmp(ecx, edi); |
1403 __ j(less_equal, stack_overflow); // Signed comparison. | 1403 __ j(less_equal, stack_overflow); // Signed comparison. |
1404 } | 1404 } |
1405 | 1405 |
1406 | 1406 |
1407 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 1407 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
1408 __ push(ebp); | 1408 __ push(ebp); |
1409 __ mov(ebp, esp); | 1409 __ mov(ebp, esp); |
1410 | 1410 |
1411 // Store the arguments adaptor context sentinel. | 1411 // Store the arguments adaptor context sentinel. |
1412 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 1412 __ push(Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1672 __ Push(edi); | 1672 __ Push(edi); |
1673 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1673 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); |
1674 } | 1674 } |
1675 } | 1675 } |
1676 | 1676 |
1677 | 1677 |
1678 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 1678 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
1679 // ----------- S t a t e ------------- | 1679 // ----------- S t a t e ------------- |
1680 // -- eax : actual number of arguments | 1680 // -- eax : actual number of arguments |
1681 // -- ebx : expected number of arguments | 1681 // -- ebx : expected number of arguments |
| 1682 // -- edx : new target (passed through to callee) |
1682 // -- edi : function (passed through to callee) | 1683 // -- edi : function (passed through to callee) |
1683 // ----------------------------------- | 1684 // ----------------------------------- |
1684 | 1685 |
1685 Label invoke, dont_adapt_arguments; | 1686 Label invoke, dont_adapt_arguments, stack_overflow; |
1686 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); | 1687 __ IncrementCounter(masm->isolate()->counters()->arguments_adaptors(), 1); |
1687 | 1688 |
1688 Label stack_overflow; | |
1689 ArgumentsAdaptorStackCheck(masm, &stack_overflow); | |
1690 | |
1691 Label enough, too_few; | 1689 Label enough, too_few; |
1692 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | |
1693 __ cmp(eax, ebx); | 1690 __ cmp(eax, ebx); |
1694 __ j(less, &too_few); | 1691 __ j(less, &too_few); |
1695 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 1692 __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel); |
1696 __ j(equal, &dont_adapt_arguments); | 1693 __ j(equal, &dont_adapt_arguments); |
1697 | 1694 |
1698 { // Enough parameters: Actual >= expected. | 1695 { // Enough parameters: Actual >= expected. |
1699 __ bind(&enough); | 1696 __ bind(&enough); |
1700 EnterArgumentsAdaptorFrame(masm); | 1697 EnterArgumentsAdaptorFrame(masm); |
| 1698 ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
1701 | 1699 |
1702 // Copy receiver and all expected arguments. | 1700 // Copy receiver and all expected arguments. |
1703 const int offset = StandardFrameConstants::kCallerSPOffset; | 1701 const int offset = StandardFrameConstants::kCallerSPOffset; |
1704 __ lea(edi, Operand(ebp, eax, times_4, offset)); | 1702 __ lea(edi, Operand(ebp, eax, times_4, offset)); |
1705 __ mov(eax, -1); // account for receiver | 1703 __ mov(eax, -1); // account for receiver |
1706 | 1704 |
1707 Label copy; | 1705 Label copy; |
1708 __ bind(©); | 1706 __ bind(©); |
1709 __ inc(eax); | 1707 __ inc(eax); |
1710 __ push(Operand(edi, 0)); | 1708 __ push(Operand(edi, 0)); |
(...skipping 21 matching lines...) Expand all Loading... |
1732 __ j(greater_equal, &no_strong_error, Label::kNear); | 1730 __ j(greater_equal, &no_strong_error, Label::kNear); |
1733 | 1731 |
1734 { | 1732 { |
1735 FrameScope frame(masm, StackFrame::MANUAL); | 1733 FrameScope frame(masm, StackFrame::MANUAL); |
1736 EnterArgumentsAdaptorFrame(masm); | 1734 EnterArgumentsAdaptorFrame(masm); |
1737 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); | 1735 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); |
1738 } | 1736 } |
1739 | 1737 |
1740 __ bind(&no_strong_error); | 1738 __ bind(&no_strong_error); |
1741 EnterArgumentsAdaptorFrame(masm); | 1739 EnterArgumentsAdaptorFrame(masm); |
| 1740 ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
1742 | 1741 |
1743 // Remember expected arguments in ecx. | 1742 // Remember expected arguments in ecx. |
1744 __ mov(ecx, ebx); | 1743 __ mov(ecx, ebx); |
1745 | 1744 |
1746 // Copy receiver and all actual arguments. | 1745 // Copy receiver and all actual arguments. |
1747 const int offset = StandardFrameConstants::kCallerSPOffset; | 1746 const int offset = StandardFrameConstants::kCallerSPOffset; |
1748 __ lea(edi, Operand(ebp, eax, times_4, offset)); | 1747 __ lea(edi, Operand(ebp, eax, times_4, offset)); |
1749 // ebx = expected - actual. | 1748 // ebx = expected - actual. |
1750 __ sub(ebx, eax); | 1749 __ sub(ebx, eax); |
1751 // eax = -actual - 1 | 1750 // eax = -actual - 1 |
(...skipping 18 matching lines...) Expand all Loading... |
1770 | 1769 |
1771 // Restore expected arguments. | 1770 // Restore expected arguments. |
1772 __ mov(eax, ecx); | 1771 __ mov(eax, ecx); |
1773 } | 1772 } |
1774 | 1773 |
1775 // Call the entry point. | 1774 // Call the entry point. |
1776 __ bind(&invoke); | 1775 __ bind(&invoke); |
1777 // Restore function pointer. | 1776 // Restore function pointer. |
1778 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1777 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1779 // eax : expected number of arguments | 1778 // eax : expected number of arguments |
| 1779 // edx : new target (passed through to callee) |
1780 // edi : function (passed through to callee) | 1780 // edi : function (passed through to callee) |
1781 __ call(edx); | 1781 __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 1782 __ call(ecx); |
1782 | 1783 |
1783 // Store offset of return address for deoptimizer. | 1784 // Store offset of return address for deoptimizer. |
1784 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); | 1785 masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); |
1785 | 1786 |
1786 // Leave frame and return. | 1787 // Leave frame and return. |
1787 LeaveArgumentsAdaptorFrame(masm); | 1788 LeaveArgumentsAdaptorFrame(masm); |
1788 __ ret(0); | 1789 __ ret(0); |
1789 | 1790 |
1790 // ------------------------------------------- | 1791 // ------------------------------------------- |
1791 // Dont adapt arguments. | 1792 // Dont adapt arguments. |
1792 // ------------------------------------------- | 1793 // ------------------------------------------- |
1793 __ bind(&dont_adapt_arguments); | 1794 __ bind(&dont_adapt_arguments); |
1794 __ jmp(edx); | 1795 __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
| 1796 __ jmp(ecx); |
1795 | 1797 |
1796 __ bind(&stack_overflow); | 1798 __ bind(&stack_overflow); |
1797 { | 1799 { |
1798 FrameScope frame(masm, StackFrame::MANUAL); | 1800 FrameScope frame(masm, StackFrame::MANUAL); |
1799 EnterArgumentsAdaptorFrame(masm); | |
1800 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1801 __ CallRuntime(Runtime::kThrowStackOverflow, 0); |
1801 __ int3(); | 1802 __ int3(); |
1802 } | 1803 } |
1803 } | 1804 } |
1804 | 1805 |
1805 | 1806 |
1806 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1807 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1807 // Lookup the function in the JavaScript frame. | 1808 // Lookup the function in the JavaScript frame. |
1808 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 1809 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
1809 { | 1810 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1856 | 1857 |
1857 __ bind(&ok); | 1858 __ bind(&ok); |
1858 __ ret(0); | 1859 __ ret(0); |
1859 } | 1860 } |
1860 | 1861 |
1861 #undef __ | 1862 #undef __ |
1862 } // namespace internal | 1863 } // namespace internal |
1863 } // namespace v8 | 1864 } // namespace v8 |
1864 | 1865 |
1865 #endif // V8_TARGET_ARCH_IA32 | 1866 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |