Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(396)

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1416673009: X87: Remove CallFunctionStub, always call through the Call builtin (also from CallIC). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 CallStubInRecordCallTarget(masm, &create_stub, is_super); 1729 CallStubInRecordCallTarget(masm, &create_stub, is_super);
1730 __ jmp(&done); 1730 __ jmp(&done);
1731 1731
1732 __ bind(&not_array_function); 1732 __ bind(&not_array_function);
1733 CreateWeakCellStub weak_cell_stub(isolate); 1733 CreateWeakCellStub weak_cell_stub(isolate);
1734 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); 1734 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super);
1735 __ bind(&done); 1735 __ bind(&done);
1736 } 1736 }
1737 1737
1738 1738
1739 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
1740 // ----------- S t a t e -------------
1741 // -- edi : the function to call
1742 // -- edx : the function's shared function info
1743 // -----------------------------------
1744 // Do not transform the receiver for strict mode functions.
1745 __ test_b(FieldOperand(edx, SharedFunctionInfo::kStrictModeByteOffset),
1746 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
1747 __ j(not_equal, cont);
1748
1749 // Do not transform the receiver for natives (shared already in ecx).
1750 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
1751 1 << SharedFunctionInfo::kNativeBitWithinByte);
1752 __ j(not_equal, cont);
1753 }
1754
1755
1756 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) {
1757 __ Set(eax, argc);
1758 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1759 }
1760
1761
1762 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
1763 // Wrap the receiver and patch it back onto the stack.
1764 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
1765 __ push(edi);
1766 ToObjectStub stub(masm->isolate());
1767 __ CallStub(&stub);
1768 __ pop(edi);
1769 }
1770 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax);
1771 __ jmp(cont);
1772 }
1773
1774
1775 static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
1776 // ----------- S t a t e -------------
1777 // -- edi : the function to call
1778 // -- edx : the function's shared function info
1779 // -----------------------------------
1780 // ClassConstructor Check: ES6 section 9.2.1 [[Call]]
1781 Label non_class_constructor;
1782 // Check whether the current function is a classConstructor.
1783 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
1784 SharedFunctionInfo::kClassConstructorBitsWithinByte);
1785 __ j(zero, &non_class_constructor, Label::kNear);
1786 // If we call a classConstructor Function throw a TypeError
1787 // indirectly via the CallFunction builtin.
1788 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1789 __ bind(&non_class_constructor);
1790 }
1791
1792
1793 static void CallFunctionNoFeedback(MacroAssembler* masm,
1794 int argc, bool needs_checks,
1795 bool call_as_method) {
1796 // edi : the function to call
1797 Label slow, wrap, cont;
1798
1799 if (needs_checks) {
1800 // Check that the function really is a JavaScript function.
1801 __ JumpIfSmi(edi, &slow);
1802
1803 // Goto slow case if we do not have a function.
1804 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
1805 __ j(not_equal, &slow);
1806 }
1807
1808 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1809 EmitClassConstructorCallCheck(masm);
1810
1811 // Fast-case: Just invoke the function.
1812 ParameterCount actual(argc);
1813
1814 if (call_as_method) {
1815 if (needs_checks) {
1816 EmitContinueIfStrictOrNative(masm, &cont);
1817 }
1818
1819 // Load the receiver from the stack.
1820 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
1821
1822 if (needs_checks) {
1823 __ JumpIfSmi(eax, &wrap);
1824
1825 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
1826 __ j(below, &wrap);
1827 } else {
1828 __ jmp(&wrap);
1829 }
1830
1831 __ bind(&cont);
1832 }
1833
1834 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
1835
1836 if (needs_checks) {
1837 // Slow-case: Non-function called.
1838 __ bind(&slow);
1839 EmitSlowCase(masm->isolate(), masm, argc);
1840 }
1841
1842 if (call_as_method) {
1843 __ bind(&wrap);
1844 EmitWrapCase(masm, argc, &cont);
1845 }
1846 }
1847
1848
1849 void CallFunctionStub::Generate(MacroAssembler* masm) {
1850 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
1851 }
1852
1853
1854 void CallConstructStub::Generate(MacroAssembler* masm) { 1739 void CallConstructStub::Generate(MacroAssembler* masm) {
1855 // eax : number of arguments 1740 // eax : number of arguments
1856 // ebx : feedback vector 1741 // ebx : feedback vector
1857 // ecx : original constructor (for IsSuperConstructorCall) 1742 // ecx : original constructor (for IsSuperConstructorCall)
1858 // edx : slot in feedback vector (Smi, for RecordCallTarget) 1743 // edx : slot in feedback vector (Smi, for RecordCallTarget)
1859 // edi : constructor function 1744 // edi : constructor function
1860 1745
1861 if (IsSuperConstructorCall()) { 1746 if (IsSuperConstructorCall()) {
1862 __ push(ecx); 1747 __ push(ecx);
1863 } 1748 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1936 1821
1937 void CallICStub::Generate(MacroAssembler* masm) { 1822 void CallICStub::Generate(MacroAssembler* masm) {
1938 // edi - function 1823 // edi - function
1939 // edx - slot id 1824 // edx - slot id
1940 // ebx - vector 1825 // ebx - vector
1941 Isolate* isolate = masm->isolate(); 1826 Isolate* isolate = masm->isolate();
1942 const int with_types_offset = 1827 const int with_types_offset =
1943 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); 1828 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
1944 const int generic_offset = 1829 const int generic_offset =
1945 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); 1830 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
1946 Label extra_checks_or_miss, slow_start; 1831 Label extra_checks_or_miss, call;
1947 Label slow, wrap, cont;
1948 Label have_js_function;
1949 int argc = arg_count(); 1832 int argc = arg_count();
1950 ParameterCount actual(argc); 1833 ParameterCount actual(argc);
1951 1834
1952 // The checks. First, does edi match the recorded monomorphic target? 1835 // The checks. First, does edi match the recorded monomorphic target?
1953 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, 1836 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
1954 FixedArray::kHeaderSize)); 1837 FixedArray::kHeaderSize));
1955 1838
1956 // We don't know that we have a weak cell. We might have a private symbol 1839 // We don't know that we have a weak cell. We might have a private symbol
1957 // or an AllocationSite, but the memory is safe to examine. 1840 // or an AllocationSite, but the memory is safe to examine.
1958 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to 1841 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to
(...skipping 13 matching lines...) Expand all
1972 1855
1973 // The compare above could have been a SMI/SMI comparison. Guard against this 1856 // The compare above could have been a SMI/SMI comparison. Guard against this
1974 // convincing us that we have a monomorphic JSFunction. 1857 // convincing us that we have a monomorphic JSFunction.
1975 __ JumpIfSmi(edi, &extra_checks_or_miss); 1858 __ JumpIfSmi(edi, &extra_checks_or_miss);
1976 1859
1977 // Increment the call count for monomorphic function calls. 1860 // Increment the call count for monomorphic function calls.
1978 __ add(FieldOperand(ebx, edx, times_half_pointer_size, 1861 __ add(FieldOperand(ebx, edx, times_half_pointer_size,
1979 FixedArray::kHeaderSize + kPointerSize), 1862 FixedArray::kHeaderSize + kPointerSize),
1980 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); 1863 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement)));
1981 1864
1982 __ bind(&have_js_function); 1865 __ bind(&call);
1983 1866 __ Set(eax, argc);
1984 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 1867 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1985 EmitClassConstructorCallCheck(masm);
1986
1987 if (CallAsMethod()) {
1988 EmitContinueIfStrictOrNative(masm, &cont);
1989
1990 // Load the receiver from the stack.
1991 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
1992
1993 __ JumpIfSmi(eax, &wrap);
1994
1995 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
1996 __ j(below, &wrap);
1997
1998 __ bind(&cont);
1999 }
2000
2001 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2002
2003 __ bind(&slow);
2004 EmitSlowCase(isolate, masm, argc);
2005
2006 if (CallAsMethod()) {
2007 __ bind(&wrap);
2008 EmitWrapCase(masm, argc, &cont);
2009 }
2010 1868
2011 __ bind(&extra_checks_or_miss); 1869 __ bind(&extra_checks_or_miss);
2012 Label uninitialized, miss, not_allocation_site; 1870 Label uninitialized, miss, not_allocation_site;
2013 1871
2014 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); 1872 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
2015 __ j(equal, &slow_start); 1873 __ j(equal, &call);
2016 1874
2017 // Check if we have an allocation site. 1875 // Check if we have an allocation site.
2018 __ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset), 1876 __ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset),
2019 Heap::kAllocationSiteMapRootIndex); 1877 Heap::kAllocationSiteMapRootIndex);
2020 __ j(not_equal, &not_allocation_site); 1878 __ j(not_equal, &not_allocation_site);
2021 1879
2022 // We have an allocation site. 1880 // We have an allocation site.
2023 HandleArrayCase(masm, &miss); 1881 HandleArrayCase(masm, &miss);
2024 1882
2025 __ bind(&not_allocation_site); 1883 __ bind(&not_allocation_site);
(...skipping 11 matching lines...) Expand all
2037 // to handle it here. More complex cases are dealt with in the runtime. 1895 // to handle it here. More complex cases are dealt with in the runtime.
2038 __ AssertNotSmi(ecx); 1896 __ AssertNotSmi(ecx);
2039 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); 1897 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
2040 __ j(not_equal, &miss); 1898 __ j(not_equal, &miss);
2041 __ mov( 1899 __ mov(
2042 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), 1900 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
2043 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); 1901 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
2044 // We have to update statistics for runtime profiling. 1902 // We have to update statistics for runtime profiling.
2045 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); 1903 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
2046 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); 1904 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
2047 __ jmp(&slow_start); 1905 __ jmp(&call);
2048 1906
2049 __ bind(&uninitialized); 1907 __ bind(&uninitialized);
2050 1908
2051 // We are going monomorphic, provided we actually have a JSFunction. 1909 // We are going monomorphic, provided we actually have a JSFunction.
2052 __ JumpIfSmi(edi, &miss); 1910 __ JumpIfSmi(edi, &miss);
2053 1911
2054 // Goto miss case if we do not have a function. 1912 // Goto miss case if we do not have a function.
2055 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 1913 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2056 __ j(not_equal, &miss); 1914 __ j(not_equal, &miss);
2057 1915
(...skipping 16 matching lines...) Expand all
2074 // edx - slot 1932 // edx - slot
2075 // edi - function 1933 // edi - function
2076 { 1934 {
2077 FrameScope scope(masm, StackFrame::INTERNAL); 1935 FrameScope scope(masm, StackFrame::INTERNAL);
2078 CreateWeakCellStub create_stub(isolate); 1936 CreateWeakCellStub create_stub(isolate);
2079 __ push(edi); 1937 __ push(edi);
2080 __ CallStub(&create_stub); 1938 __ CallStub(&create_stub);
2081 __ pop(edi); 1939 __ pop(edi);
2082 } 1940 }
2083 1941
2084 __ jmp(&have_js_function); 1942 __ jmp(&call);
2085 1943
2086 // We are here because tracing is on or we encountered a MISS case we can't 1944 // We are here because tracing is on or we encountered a MISS case we can't
2087 // handle here. 1945 // handle here.
2088 __ bind(&miss); 1946 __ bind(&miss);
2089 GenerateMiss(masm); 1947 GenerateMiss(masm);
2090 1948
2091 // the slow case 1949 __ jmp(&call);
2092 __ bind(&slow_start);
2093
2094 // Check that the function really is a JavaScript function.
2095 __ JumpIfSmi(edi, &slow);
2096
2097 // Goto slow case if we do not have a function.
2098 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2099 __ j(not_equal, &slow);
2100 __ jmp(&have_js_function);
2101 1950
2102 // Unreachable 1951 // Unreachable
2103 __ int3(); 1952 __ int3();
2104 } 1953 }
2105 1954
2106 1955
2107 void CallICStub::GenerateMiss(MacroAssembler* masm) { 1956 void CallICStub::GenerateMiss(MacroAssembler* masm) {
2108 FrameScope scope(masm, StackFrame::INTERNAL); 1957 FrameScope scope(masm, StackFrame::INTERNAL);
2109 1958
2110 // Push the function and feedback info. 1959 // Push the function and feedback info.
(...skipping 3465 matching lines...) Expand 10 before | Expand all | Expand 10 after
5576 Operand(ebp, 7 * kPointerSize), NULL); 5425 Operand(ebp, 7 * kPointerSize), NULL);
5577 } 5426 }
5578 5427
5579 5428
5580 #undef __ 5429 #undef __
5581 5430
5582 } // namespace internal 5431 } // namespace internal
5583 } // namespace v8 5432 } // namespace v8
5584 5433
5585 #endif // V8_TARGET_ARCH_X87 5434 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/full-codegen/x87/full-codegen-x87.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698