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

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

Issue 1407373007: 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/mips64/code-stubs-mips64.cc ('k') | test/mjsunit/call-cross-realm.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/code-stubs.h" 8 #include "src/code-stubs.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 1857 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); 1868 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super);
1869 __ jmp(&done_no_smi_convert); 1869 __ jmp(&done_no_smi_convert);
1870 1870
1871 __ bind(&done); 1871 __ bind(&done);
1872 __ Integer32ToSmi(rdx, rdx); 1872 __ Integer32ToSmi(rdx, rdx);
1873 1873
1874 __ bind(&done_no_smi_convert); 1874 __ bind(&done_no_smi_convert);
1875 } 1875 }
1876 1876
1877 1877
1878 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
1879 // ----------- S t a t e -------------
1880 // -- rdi : the function to call
1881 // -- rdx : the function's shared function info
1882 // -----------------------------------
1883 // Assume that SharedFunctionInfo is already loaded into rdx.
1884 // Do not transform the receiver for strict mode functions.
1885 __ testb(FieldOperand(rdx, SharedFunctionInfo::kStrictModeByteOffset),
1886 Immediate(1 << SharedFunctionInfo::kStrictModeBitWithinByte));
1887 __ j(not_equal, cont);
1888
1889 // Do not transform the receiver for natives.
1890 __ testb(FieldOperand(rdx, SharedFunctionInfo::kNativeByteOffset),
1891 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
1892 __ j(not_equal, cont);
1893 }
1894
1895
1896 static void EmitSlowCase(MacroAssembler* masm, StackArgumentsAccessor* args,
1897 int argc) {
1898 __ Set(rax, argc);
1899 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1900 }
1901
1902
1903 static void EmitWrapCase(MacroAssembler* masm,
1904 StackArgumentsAccessor* args,
1905 Label* cont) {
1906 // Wrap the receiver and patch it back onto the stack.
1907 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
1908 __ Push(rdi);
1909 ToObjectStub stub(masm->isolate());
1910 __ CallStub(&stub);
1911 __ Pop(rdi);
1912 }
1913 __ movp(args->GetReceiverOperand(), rax);
1914 __ jmp(cont);
1915 }
1916
1917
1918 static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
1919 // ----------- S t a t e -------------
1920 // -- rdi : the function to call
1921 // -- rdx : the function's shared function info
1922 // -----------------------------------
1923 // ClassConstructor Check: ES6 section 9.2.1 [[Call]]
1924 Label non_class_constructor;
1925 // Check whether the current function is a classConstructor
1926 __ testb(FieldOperand(rdx, SharedFunctionInfo::kFunctionKindByteOffset),
1927 Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1928 __ j(zero, &non_class_constructor, Label::kNear);
1929 // If we call a classConstructor Function throw a TypeError
1930 // indirectly via the CallFunction builtin.
1931 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1932 __ bind(&non_class_constructor);
1933 }
1934
1935
1936 static void CallFunctionNoFeedback(MacroAssembler* masm,
1937 int argc, bool needs_checks,
1938 bool call_as_method) {
1939 // ----------- S t a t e -------------
1940 // -- rdi : the function to call
1941 // -----------------------------------
1942
1943 // wrap_and_call can only be true if we are compiling a monomorphic method.
1944 Label slow, wrap, cont;
1945 StackArgumentsAccessor args(rsp, argc);
1946
1947 if (needs_checks) {
1948 // Check that the function really is a JavaScript function.
1949 __ JumpIfSmi(rdi, &slow);
1950
1951 // Goto slow case if we do not have a function.
1952 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
1953 __ j(not_equal, &slow);
1954 }
1955
1956 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
1957 EmitClassConstructorCallCheck(masm);
1958
1959 // Fast-case: Just invoke the function.
1960 ParameterCount actual(argc);
1961
1962 if (call_as_method) {
1963 if (needs_checks) {
1964 EmitContinueIfStrictOrNative(masm, &cont);
1965 }
1966
1967 // Load the receiver from the stack.
1968 __ movp(rax, args.GetReceiverOperand());
1969
1970 if (needs_checks) {
1971 __ JumpIfSmi(rax, &wrap);
1972
1973 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
1974 __ j(below, &wrap);
1975 } else {
1976 __ jmp(&wrap);
1977 }
1978
1979 __ bind(&cont);
1980 }
1981
1982 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
1983
1984 if (needs_checks) {
1985 // Slow-case: Non-function called.
1986 __ bind(&slow);
1987 EmitSlowCase(masm, &args, argc);
1988 }
1989
1990 if (call_as_method) {
1991 __ bind(&wrap);
1992 EmitWrapCase(masm, &args, &cont);
1993 }
1994 }
1995
1996
1997 void CallFunctionStub::Generate(MacroAssembler* masm) {
1998 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
1999 }
2000
2001
2002 void CallConstructStub::Generate(MacroAssembler* masm) { 1878 void CallConstructStub::Generate(MacroAssembler* masm) {
2003 // rax : number of arguments 1879 // rax : number of arguments
2004 // rbx : feedback vector 1880 // rbx : feedback vector
2005 // rcx : original constructor (for IsSuperConstructorCall) 1881 // rcx : original constructor (for IsSuperConstructorCall)
2006 // rdx : slot in feedback vector (Smi, for RecordCallTarget) 1882 // rdx : slot in feedback vector (Smi, for RecordCallTarget)
2007 // rdi : constructor function 1883 // rdi : constructor function
2008 1884
2009 Label non_function; 1885 Label non_function;
2010 // Check that the constructor is not a smi. 1886 // Check that the constructor is not a smi.
2011 __ JumpIfSmi(rdi, &non_function); 1887 __ JumpIfSmi(rdi, &non_function);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2076 // ----------- S t a t e ------------- 1952 // ----------- S t a t e -------------
2077 // -- rdi - function 1953 // -- rdi - function
2078 // -- rdx - slot id 1954 // -- rdx - slot id
2079 // -- rbx - vector 1955 // -- rbx - vector
2080 // ----------------------------------- 1956 // -----------------------------------
2081 Isolate* isolate = masm->isolate(); 1957 Isolate* isolate = masm->isolate();
2082 const int with_types_offset = 1958 const int with_types_offset =
2083 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); 1959 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2084 const int generic_offset = 1960 const int generic_offset =
2085 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); 1961 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
2086 Label extra_checks_or_miss, slow_start; 1962 Label extra_checks_or_miss, call;
2087 Label slow, wrap, cont;
2088 Label have_js_function;
2089 int argc = arg_count(); 1963 int argc = arg_count();
2090 StackArgumentsAccessor args(rsp, argc); 1964 StackArgumentsAccessor args(rsp, argc);
2091 ParameterCount actual(argc); 1965 ParameterCount actual(argc);
2092 1966
2093 // The checks. First, does rdi match the recorded monomorphic target? 1967 // The checks. First, does rdi match the recorded monomorphic target?
2094 __ SmiToInteger32(rdx, rdx); 1968 __ SmiToInteger32(rdx, rdx);
2095 __ movp(rcx, 1969 __ movp(rcx,
2096 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); 1970 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
2097 1971
2098 // We don't know that we have a weak cell. We might have a private symbol 1972 // We don't know that we have a weak cell. We might have a private symbol
(...skipping 15 matching lines...) Expand all
2114 1988
2115 // The compare above could have been a SMI/SMI comparison. Guard against this 1989 // The compare above could have been a SMI/SMI comparison. Guard against this
2116 // convincing us that we have a monomorphic JSFunction. 1990 // convincing us that we have a monomorphic JSFunction.
2117 __ JumpIfSmi(rdi, &extra_checks_or_miss); 1991 __ JumpIfSmi(rdi, &extra_checks_or_miss);
2118 1992
2119 // Increment the call count for monomorphic function calls. 1993 // Increment the call count for monomorphic function calls.
2120 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size, 1994 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size,
2121 FixedArray::kHeaderSize + kPointerSize), 1995 FixedArray::kHeaderSize + kPointerSize),
2122 Smi::FromInt(CallICNexus::kCallCountIncrement)); 1996 Smi::FromInt(CallICNexus::kCallCountIncrement));
2123 1997
2124 __ bind(&have_js_function); 1998 __ bind(&call);
2125 1999 __ Set(rax, argc);
2126 __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 2000 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2127 EmitClassConstructorCallCheck(masm);
2128
2129 if (CallAsMethod()) {
2130 EmitContinueIfStrictOrNative(masm, &cont);
2131
2132 // Load the receiver from the stack.
2133 __ movp(rax, args.GetReceiverOperand());
2134
2135 __ JumpIfSmi(rax, &wrap);
2136
2137 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
2138 __ j(below, &wrap);
2139
2140 __ bind(&cont);
2141 }
2142
2143 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
2144
2145 __ bind(&slow);
2146 EmitSlowCase(masm, &args, argc);
2147
2148 if (CallAsMethod()) {
2149 __ bind(&wrap);
2150 EmitWrapCase(masm, &args, &cont);
2151 }
2152 2001
2153 __ bind(&extra_checks_or_miss); 2002 __ bind(&extra_checks_or_miss);
2154 Label uninitialized, miss, not_allocation_site; 2003 Label uninitialized, miss, not_allocation_site;
2155 2004
2156 __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate)); 2005 __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate));
2157 __ j(equal, &slow_start); 2006 __ j(equal, &call);
2158 2007
2159 // Check if we have an allocation site. 2008 // Check if we have an allocation site.
2160 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 2009 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
2161 Heap::kAllocationSiteMapRootIndex); 2010 Heap::kAllocationSiteMapRootIndex);
2162 __ j(not_equal, &not_allocation_site); 2011 __ j(not_equal, &not_allocation_site);
2163 2012
2164 // We have an allocation site. 2013 // We have an allocation site.
2165 HandleArrayCase(masm, &miss); 2014 HandleArrayCase(masm, &miss);
2166 2015
2167 __ bind(&not_allocation_site); 2016 __ bind(&not_allocation_site);
(...skipping 10 matching lines...) Expand all
2178 // We are going megamorphic. If the feedback is a JSFunction, it is fine 2027 // We are going megamorphic. If the feedback is a JSFunction, it is fine
2179 // to handle it here. More complex cases are dealt with in the runtime. 2028 // to handle it here. More complex cases are dealt with in the runtime.
2180 __ AssertNotSmi(rcx); 2029 __ AssertNotSmi(rcx);
2181 __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx); 2030 __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
2182 __ j(not_equal, &miss); 2031 __ j(not_equal, &miss);
2183 __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize), 2032 __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
2184 TypeFeedbackVector::MegamorphicSentinel(isolate)); 2033 TypeFeedbackVector::MegamorphicSentinel(isolate));
2185 // We have to update statistics for runtime profiling. 2034 // We have to update statistics for runtime profiling.
2186 __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(-1)); 2035 __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(-1));
2187 __ SmiAddConstant(FieldOperand(rbx, generic_offset), Smi::FromInt(1)); 2036 __ SmiAddConstant(FieldOperand(rbx, generic_offset), Smi::FromInt(1));
2188 __ jmp(&slow_start); 2037 __ jmp(&call);
2189 2038
2190 __ bind(&uninitialized); 2039 __ bind(&uninitialized);
2191 2040
2192 // We are going monomorphic, provided we actually have a JSFunction. 2041 // We are going monomorphic, provided we actually have a JSFunction.
2193 __ JumpIfSmi(rdi, &miss); 2042 __ JumpIfSmi(rdi, &miss);
2194 2043
2195 // Goto miss case if we do not have a function. 2044 // Goto miss case if we do not have a function.
2196 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2045 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2197 __ j(not_equal, &miss); 2046 __ j(not_equal, &miss);
2198 2047
(...skipping 18 matching lines...) Expand all
2217 { 2066 {
2218 FrameScope scope(masm, StackFrame::INTERNAL); 2067 FrameScope scope(masm, StackFrame::INTERNAL);
2219 CreateWeakCellStub create_stub(isolate); 2068 CreateWeakCellStub create_stub(isolate);
2220 2069
2221 __ Integer32ToSmi(rdx, rdx); 2070 __ Integer32ToSmi(rdx, rdx);
2222 __ Push(rdi); 2071 __ Push(rdi);
2223 __ CallStub(&create_stub); 2072 __ CallStub(&create_stub);
2224 __ Pop(rdi); 2073 __ Pop(rdi);
2225 } 2074 }
2226 2075
2227 __ jmp(&have_js_function); 2076 __ jmp(&call);
2228 2077
2229 // We are here because tracing is on or we encountered a MISS case we can't 2078 // We are here because tracing is on or we encountered a MISS case we can't
2230 // handle here. 2079 // handle here.
2231 __ bind(&miss); 2080 __ bind(&miss);
2232 GenerateMiss(masm); 2081 GenerateMiss(masm);
2233 2082
2234 // the slow case 2083 __ jmp(&call);
2235 __ bind(&slow_start);
2236 // Check that function is not a smi.
2237 __ JumpIfSmi(rdi, &slow);
2238 // Check that function is a JSFunction.
2239 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2240 __ j(not_equal, &slow);
2241 __ jmp(&have_js_function);
2242 2084
2243 // Unreachable 2085 // Unreachable
2244 __ int3(); 2086 __ int3();
2245 } 2087 }
2246 2088
2247 2089
2248 void CallICStub::GenerateMiss(MacroAssembler* masm) { 2090 void CallICStub::GenerateMiss(MacroAssembler* masm) {
2249 FrameScope scope(masm, StackFrame::INTERNAL); 2091 FrameScope scope(masm, StackFrame::INTERNAL);
2250 2092
2251 // Push the receiver and the function and feedback info. 2093 // Push the receiver and the function and feedback info.
(...skipping 3375 matching lines...) Expand 10 before | Expand all | Expand 10 after
5627 kStackSpace, nullptr, return_value_operand, NULL); 5469 kStackSpace, nullptr, return_value_operand, NULL);
5628 } 5470 }
5629 5471
5630 5472
5631 #undef __ 5473 #undef __
5632 5474
5633 } // namespace internal 5475 } // namespace internal
5634 } // namespace v8 5476 } // namespace v8
5635 5477
5636 #endif // V8_TARGET_ARCH_X64 5478 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/mips64/code-stubs-mips64.cc ('k') | test/mjsunit/call-cross-realm.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698