| 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/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1739 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 1739 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
| 1740 __ j(not_equal, cont); | 1740 __ j(not_equal, cont); |
| 1741 | 1741 |
| 1742 // Do not transform the receiver for natives (shared already in ecx). | 1742 // Do not transform the receiver for natives (shared already in ecx). |
| 1743 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), | 1743 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), |
| 1744 1 << SharedFunctionInfo::kNativeBitWithinByte); | 1744 1 << SharedFunctionInfo::kNativeBitWithinByte); |
| 1745 __ j(not_equal, cont); | 1745 __ j(not_equal, cont); |
| 1746 } | 1746 } |
| 1747 | 1747 |
| 1748 | 1748 |
| 1749 static void EmitSlowCase(Isolate* isolate, | 1749 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { |
| 1750 MacroAssembler* masm, | 1750 __ Set(eax, argc); |
| 1751 int argc, | 1751 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1752 Label* non_function) { | |
| 1753 // Check for function proxy. | |
| 1754 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | |
| 1755 __ j(not_equal, non_function); | |
| 1756 __ pop(ecx); | |
| 1757 __ push(edi); // put proxy as additional argument under return address | |
| 1758 __ push(ecx); | |
| 1759 __ Move(eax, Immediate(argc + 1)); | |
| 1760 __ Move(ebx, Immediate(0)); | |
| 1761 __ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); | |
| 1762 { | |
| 1763 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | |
| 1764 __ jmp(adaptor, RelocInfo::CODE_TARGET); | |
| 1765 } | |
| 1766 | |
| 1767 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | |
| 1768 // of the original receiver from the call site). | |
| 1769 __ bind(non_function); | |
| 1770 __ mov(Operand(esp, (argc + 1) * kPointerSize), edi); | |
| 1771 __ Move(eax, Immediate(argc)); | |
| 1772 __ Move(ebx, Immediate(0)); | |
| 1773 __ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX); | |
| 1774 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | |
| 1775 __ jmp(adaptor, RelocInfo::CODE_TARGET); | |
| 1776 } | 1752 } |
| 1777 | 1753 |
| 1778 | 1754 |
| 1779 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 1755 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
| 1780 // Wrap the receiver and patch it back onto the stack. | 1756 // Wrap the receiver and patch it back onto the stack. |
| 1781 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 1757 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 1782 __ push(edi); | 1758 __ push(edi); |
| 1783 ToObjectStub stub(masm->isolate()); | 1759 ToObjectStub stub(masm->isolate()); |
| 1784 __ CallStub(&stub); | 1760 __ CallStub(&stub); |
| 1785 __ pop(edi); | 1761 __ pop(edi); |
| 1786 } | 1762 } |
| 1787 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); | 1763 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); |
| 1788 __ jmp(cont); | 1764 __ jmp(cont); |
| 1789 } | 1765 } |
| 1790 | 1766 |
| 1791 | 1767 |
| 1792 static void CallFunctionNoFeedback(MacroAssembler* masm, | 1768 static void CallFunctionNoFeedback(MacroAssembler* masm, |
| 1793 int argc, bool needs_checks, | 1769 int argc, bool needs_checks, |
| 1794 bool call_as_method) { | 1770 bool call_as_method) { |
| 1795 // edi : the function to call | 1771 // edi : the function to call |
| 1796 Label slow, non_function, wrap, cont; | 1772 Label slow, wrap, cont; |
| 1797 | 1773 |
| 1798 if (needs_checks) { | 1774 if (needs_checks) { |
| 1799 // Check that the function really is a JavaScript function. | 1775 // Check that the function really is a JavaScript function. |
| 1800 __ JumpIfSmi(edi, &non_function); | 1776 __ JumpIfSmi(edi, &slow); |
| 1801 | 1777 |
| 1802 // Goto slow case if we do not have a function. | 1778 // Goto slow case if we do not have a function. |
| 1803 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 1779 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 1804 __ j(not_equal, &slow); | 1780 __ j(not_equal, &slow); |
| 1805 } | 1781 } |
| 1806 | 1782 |
| 1807 // Fast-case: Just invoke the function. | 1783 // Fast-case: Just invoke the function. |
| 1808 ParameterCount actual(argc); | 1784 ParameterCount actual(argc); |
| 1809 | 1785 |
| 1810 if (call_as_method) { | 1786 if (call_as_method) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1825 } | 1801 } |
| 1826 | 1802 |
| 1827 __ bind(&cont); | 1803 __ bind(&cont); |
| 1828 } | 1804 } |
| 1829 | 1805 |
| 1830 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 1806 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1831 | 1807 |
| 1832 if (needs_checks) { | 1808 if (needs_checks) { |
| 1833 // Slow-case: Non-function called. | 1809 // Slow-case: Non-function called. |
| 1834 __ bind(&slow); | 1810 __ bind(&slow); |
| 1835 // (non_function is bound in EmitSlowCase) | 1811 EmitSlowCase(masm->isolate(), masm, argc); |
| 1836 EmitSlowCase(masm->isolate(), masm, argc, &non_function); | |
| 1837 } | 1812 } |
| 1838 | 1813 |
| 1839 if (call_as_method) { | 1814 if (call_as_method) { |
| 1840 __ bind(&wrap); | 1815 __ bind(&wrap); |
| 1841 EmitWrapCase(masm, argc, &cont); | 1816 EmitWrapCase(masm, argc, &cont); |
| 1842 } | 1817 } |
| 1843 } | 1818 } |
| 1844 | 1819 |
| 1845 | 1820 |
| 1846 void CallFunctionStub::Generate(MacroAssembler* masm) { | 1821 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1970 | 1945 |
| 1971 __ mov(ebx, ecx); | 1946 __ mov(ebx, ecx); |
| 1972 __ mov(edx, edi); | 1947 __ mov(edx, edi); |
| 1973 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 1948 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 1974 __ TailCallStub(&stub); | 1949 __ TailCallStub(&stub); |
| 1975 | 1950 |
| 1976 __ bind(&miss); | 1951 __ bind(&miss); |
| 1977 GenerateMiss(masm); | 1952 GenerateMiss(masm); |
| 1978 | 1953 |
| 1979 // The slow case, we need this no matter what to complete a call after a miss. | 1954 // The slow case, we need this no matter what to complete a call after a miss. |
| 1980 CallFunctionNoFeedback(masm, | 1955 __ Set(eax, arg_count()); |
| 1981 arg_count(), | 1956 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 1982 true, | |
| 1983 CallAsMethod()); | |
| 1984 | |
| 1985 // Unreachable. | |
| 1986 __ int3(); | |
| 1987 } | 1957 } |
| 1988 | 1958 |
| 1989 | 1959 |
| 1990 void CallICStub::Generate(MacroAssembler* masm) { | 1960 void CallICStub::Generate(MacroAssembler* masm) { |
| 1991 // edi - function | 1961 // edi - function |
| 1992 // edx - slot id | 1962 // edx - slot id |
| 1993 // ebx - vector | 1963 // ebx - vector |
| 1994 Isolate* isolate = masm->isolate(); | 1964 Isolate* isolate = masm->isolate(); |
| 1995 const int with_types_offset = | 1965 const int with_types_offset = |
| 1996 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 1966 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 1997 const int generic_offset = | 1967 const int generic_offset = |
| 1998 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 1968 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
| 1999 Label extra_checks_or_miss, slow_start; | 1969 Label extra_checks_or_miss, slow_start; |
| 2000 Label slow, non_function, wrap, cont; | 1970 Label slow, wrap, cont; |
| 2001 Label have_js_function; | 1971 Label have_js_function; |
| 2002 int argc = arg_count(); | 1972 int argc = arg_count(); |
| 2003 ParameterCount actual(argc); | 1973 ParameterCount actual(argc); |
| 2004 | 1974 |
| 2005 // The checks. First, does edi match the recorded monomorphic target? | 1975 // The checks. First, does edi match the recorded monomorphic target? |
| 2006 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 1976 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 2007 FixedArray::kHeaderSize)); | 1977 FixedArray::kHeaderSize)); |
| 2008 | 1978 |
| 2009 // We don't know that we have a weak cell. We might have a private symbol | 1979 // We don't know that we have a weak cell. We might have a private symbol |
| 2010 // or an AllocationSite, but the memory is safe to examine. | 1980 // or an AllocationSite, but the memory is safe to examine. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2043 | 2013 |
| 2044 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); | 2014 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
| 2045 __ j(below, &wrap); | 2015 __ j(below, &wrap); |
| 2046 | 2016 |
| 2047 __ bind(&cont); | 2017 __ bind(&cont); |
| 2048 } | 2018 } |
| 2049 | 2019 |
| 2050 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2020 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2051 | 2021 |
| 2052 __ bind(&slow); | 2022 __ bind(&slow); |
| 2053 EmitSlowCase(isolate, masm, argc, &non_function); | 2023 EmitSlowCase(isolate, masm, argc); |
| 2054 | 2024 |
| 2055 if (CallAsMethod()) { | 2025 if (CallAsMethod()) { |
| 2056 __ bind(&wrap); | 2026 __ bind(&wrap); |
| 2057 EmitWrapCase(masm, argc, &cont); | 2027 EmitWrapCase(masm, argc, &cont); |
| 2058 } | 2028 } |
| 2059 | 2029 |
| 2060 __ bind(&extra_checks_or_miss); | 2030 __ bind(&extra_checks_or_miss); |
| 2061 Label uninitialized, miss; | 2031 Label uninitialized, miss; |
| 2062 | 2032 |
| 2063 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 2033 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 | 2094 |
| 2125 // We are here because tracing is on or we encountered a MISS case we can't | 2095 // We are here because tracing is on or we encountered a MISS case we can't |
| 2126 // handle here. | 2096 // handle here. |
| 2127 __ bind(&miss); | 2097 __ bind(&miss); |
| 2128 GenerateMiss(masm); | 2098 GenerateMiss(masm); |
| 2129 | 2099 |
| 2130 // the slow case | 2100 // the slow case |
| 2131 __ bind(&slow_start); | 2101 __ bind(&slow_start); |
| 2132 | 2102 |
| 2133 // Check that the function really is a JavaScript function. | 2103 // Check that the function really is a JavaScript function. |
| 2134 __ JumpIfSmi(edi, &non_function); | 2104 __ JumpIfSmi(edi, &slow); |
| 2135 | 2105 |
| 2136 // Goto slow case if we do not have a function. | 2106 // Goto slow case if we do not have a function. |
| 2137 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2107 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2138 __ j(not_equal, &slow); | 2108 __ j(not_equal, &slow); |
| 2139 __ jmp(&have_js_function); | 2109 __ jmp(&have_js_function); |
| 2140 | 2110 |
| 2141 // Unreachable | 2111 // Unreachable |
| 2142 __ int3(); | 2112 __ int3(); |
| 2143 } | 2113 } |
| 2144 | 2114 |
| (...skipping 3379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5524 Operand(ebp, 7 * kPointerSize), NULL); | 5494 Operand(ebp, 7 * kPointerSize), NULL); |
| 5525 } | 5495 } |
| 5526 | 5496 |
| 5527 | 5497 |
| 5528 #undef __ | 5498 #undef __ |
| 5529 | 5499 |
| 5530 } // namespace internal | 5500 } // namespace internal |
| 5531 } // namespace v8 | 5501 } // namespace v8 |
| 5532 | 5502 |
| 5533 #endif // V8_TARGET_ARCH_X87 | 5503 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |