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