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

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

Issue 1311013008: [builtins] Unify the various versions of [[Call]] with a Call builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: AssertFunction was wrong Created 5 years, 3 months 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/x64/builtins-x64.cc ('k') | src/x64/macro-assembler-x64.h » ('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 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1895 __ j(not_equal, cont); 1895 __ j(not_equal, cont);
1896 1896
1897 // Do not transform the receiver for natives. 1897 // Do not transform the receiver for natives.
1898 // SharedFunctionInfo is already loaded into rcx. 1898 // SharedFunctionInfo is already loaded into rcx.
1899 __ testb(FieldOperand(rcx, SharedFunctionInfo::kNativeByteOffset), 1899 __ testb(FieldOperand(rcx, SharedFunctionInfo::kNativeByteOffset),
1900 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte)); 1900 Immediate(1 << SharedFunctionInfo::kNativeBitWithinByte));
1901 __ j(not_equal, cont); 1901 __ j(not_equal, cont);
1902 } 1902 }
1903 1903
1904 1904
1905 static void EmitSlowCase(Isolate* isolate, 1905 static void EmitSlowCase(MacroAssembler* masm, StackArgumentsAccessor* args,
1906 MacroAssembler* masm, 1906 int argc) {
1907 StackArgumentsAccessor* args,
1908 int argc,
1909 Label* non_function) {
1910 // Check for function proxy.
1911 __ CmpInstanceType(rcx, JS_FUNCTION_PROXY_TYPE);
1912 __ j(not_equal, non_function);
1913 __ PopReturnAddressTo(rcx);
1914 __ Push(rdi); // put proxy as additional argument under return address
1915 __ PushReturnAddressFrom(rcx);
1916 __ Set(rax, argc + 1);
1917 __ Set(rbx, 0);
1918 __ GetBuiltinEntry(rdx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
1919 {
1920 Handle<Code> adaptor =
1921 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
1922 __ jmp(adaptor, RelocInfo::CODE_TARGET);
1923 }
1924
1925 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
1926 // of the original receiver from the call site).
1927 __ bind(non_function);
1928 __ movp(args->GetReceiverOperand(), rdi);
1929 __ Set(rax, argc); 1907 __ Set(rax, argc);
1930 __ Set(rbx, 0); 1908 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1931 __ GetBuiltinEntry(rdx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
1932 Handle<Code> adaptor =
1933 isolate->builtins()->ArgumentsAdaptorTrampoline();
1934 __ Jump(adaptor, RelocInfo::CODE_TARGET);
1935 } 1909 }
1936 1910
1937 1911
1938 static void EmitWrapCase(MacroAssembler* masm, 1912 static void EmitWrapCase(MacroAssembler* masm,
1939 StackArgumentsAccessor* args, 1913 StackArgumentsAccessor* args,
1940 Label* cont) { 1914 Label* cont) {
1941 // Wrap the receiver and patch it back onto the stack. 1915 // Wrap the receiver and patch it back onto the stack.
1942 { FrameScope frame_scope(masm, StackFrame::INTERNAL); 1916 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
1943 __ Push(rdi); 1917 __ Push(rdi);
1944 ToObjectStub stub(masm->isolate()); 1918 ToObjectStub stub(masm->isolate());
1945 __ CallStub(&stub); 1919 __ CallStub(&stub);
1946 __ Pop(rdi); 1920 __ Pop(rdi);
1947 } 1921 }
1948 __ movp(args->GetReceiverOperand(), rax); 1922 __ movp(args->GetReceiverOperand(), rax);
1949 __ jmp(cont); 1923 __ jmp(cont);
1950 } 1924 }
1951 1925
1952 1926
1953 static void CallFunctionNoFeedback(MacroAssembler* masm, 1927 static void CallFunctionNoFeedback(MacroAssembler* masm,
1954 int argc, bool needs_checks, 1928 int argc, bool needs_checks,
1955 bool call_as_method) { 1929 bool call_as_method) {
1956 // rdi : the function to call 1930 // rdi : the function to call
1957 1931
1958 // wrap_and_call can only be true if we are compiling a monomorphic method. 1932 // wrap_and_call can only be true if we are compiling a monomorphic method.
1959 Isolate* isolate = masm->isolate(); 1933 Label slow, wrap, cont;
1960 Label slow, non_function, wrap, cont;
1961 StackArgumentsAccessor args(rsp, argc); 1934 StackArgumentsAccessor args(rsp, argc);
1962 1935
1963 if (needs_checks) { 1936 if (needs_checks) {
1964 // Check that the function really is a JavaScript function. 1937 // Check that the function really is a JavaScript function.
1965 __ JumpIfSmi(rdi, &non_function); 1938 __ JumpIfSmi(rdi, &slow);
1966 1939
1967 // Goto slow case if we do not have a function. 1940 // Goto slow case if we do not have a function.
1968 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 1941 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
1969 __ j(not_equal, &slow); 1942 __ j(not_equal, &slow);
1970 } 1943 }
1971 1944
1972 // Fast-case: Just invoke the function. 1945 // Fast-case: Just invoke the function.
1973 ParameterCount actual(argc); 1946 ParameterCount actual(argc);
1974 1947
1975 if (call_as_method) { 1948 if (call_as_method) {
(...skipping 14 matching lines...) Expand all
1990 } 1963 }
1991 1964
1992 __ bind(&cont); 1965 __ bind(&cont);
1993 } 1966 }
1994 1967
1995 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); 1968 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
1996 1969
1997 if (needs_checks) { 1970 if (needs_checks) {
1998 // Slow-case: Non-function called. 1971 // Slow-case: Non-function called.
1999 __ bind(&slow); 1972 __ bind(&slow);
2000 EmitSlowCase(isolate, masm, &args, argc, &non_function); 1973 EmitSlowCase(masm, &args, argc);
2001 } 1974 }
2002 1975
2003 if (call_as_method) { 1976 if (call_as_method) {
2004 __ bind(&wrap); 1977 __ bind(&wrap);
2005 EmitWrapCase(masm, &args, &cont); 1978 EmitWrapCase(masm, &args, &cont);
2006 } 1979 }
2007 } 1980 }
2008 1981
2009 1982
2010 void CallFunctionStub::Generate(MacroAssembler* masm) { 1983 void CallFunctionStub::Generate(MacroAssembler* masm) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 __ SmiToInteger32(rdx, rdx); 2079 __ SmiToInteger32(rdx, rdx);
2107 2080
2108 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx); 2081 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
2109 __ cmpp(rdi, rcx); 2082 __ cmpp(rdi, rcx);
2110 __ j(not_equal, &miss); 2083 __ j(not_equal, &miss);
2111 2084
2112 __ movp(rax, Immediate(arg_count())); 2085 __ movp(rax, Immediate(arg_count()));
2113 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size, 2086 __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
2114 FixedArray::kHeaderSize)); 2087 FixedArray::kHeaderSize));
2115 // Verify that ecx contains an AllocationSite 2088 // Verify that ecx contains an AllocationSite
2116 Factory* factory = masm->isolate()->factory(); 2089 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
2117 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), 2090 Heap::kAllocationSiteMapRootIndex);
2118 factory->allocation_site_map()); 2091 __ j(not_equal, &miss, Label::kNear);
2119 __ j(not_equal, &miss);
2120 2092
2121 // Increment the call count for monomorphic function calls. 2093 // Increment the call count for monomorphic function calls.
2122 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size, 2094 {
2123 FixedArray::kHeaderSize + kPointerSize), 2095 __ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size,
2124 Smi::FromInt(CallICNexus::kCallCountIncrement)); 2096 FixedArray::kHeaderSize + kPointerSize),
2097 Smi::FromInt(CallICNexus::kCallCountIncrement));
2125 2098
2126 __ movp(rbx, rcx); 2099 __ movp(rbx, rcx);
2127 __ movp(rdx, rdi); 2100 __ movp(rdx, rdi);
2128 ArrayConstructorStub stub(masm->isolate(), arg_count()); 2101 ArrayConstructorStub stub(masm->isolate(), arg_count());
2129 __ TailCallStub(&stub); 2102 __ TailCallStub(&stub);
2103 }
2130 2104
2131 __ bind(&miss); 2105 __ bind(&miss);
2132 GenerateMiss(masm); 2106 GenerateMiss(masm);
2133 2107
2134 // The slow case, we need this no matter what to complete a call after a miss. 2108 // The slow case, we need this no matter what to complete a call after a miss.
2135 CallFunctionNoFeedback(masm, 2109 __ Set(rax, arg_count());
2136 arg_count(), 2110 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2137 true,
2138 CallAsMethod());
2139
2140 // Unreachable.
2141 __ int3();
2142 } 2111 }
2143 2112
2144 2113
2145 void CallICStub::Generate(MacroAssembler* masm) { 2114 void CallICStub::Generate(MacroAssembler* masm) {
2146 // rdi - function 2115 // rdi - function
2147 // rdx - slot id 2116 // rdx - slot id
2148 // rbx - vector 2117 // rbx - vector
2149 Isolate* isolate = masm->isolate(); 2118 Isolate* isolate = masm->isolate();
2150 const int with_types_offset = 2119 const int with_types_offset =
2151 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); 2120 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2152 const int generic_offset = 2121 const int generic_offset =
2153 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); 2122 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
2154 Label extra_checks_or_miss, slow_start; 2123 Label extra_checks_or_miss, slow_start;
2155 Label slow, non_function, wrap, cont; 2124 Label slow, wrap, cont;
2156 Label have_js_function; 2125 Label have_js_function;
2157 int argc = arg_count(); 2126 int argc = arg_count();
2158 StackArgumentsAccessor args(rsp, argc); 2127 StackArgumentsAccessor args(rsp, argc);
2159 ParameterCount actual(argc); 2128 ParameterCount actual(argc);
2160 2129
2161 // The checks. First, does rdi match the recorded monomorphic target? 2130 // The checks. First, does rdi match the recorded monomorphic target?
2162 __ SmiToInteger32(rdx, rdx); 2131 __ SmiToInteger32(rdx, rdx);
2163 __ movp(rcx, 2132 __ movp(rcx,
2164 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); 2133 FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
2165 2134
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2200 2169
2201 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); 2170 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
2202 __ j(below, &wrap); 2171 __ j(below, &wrap);
2203 2172
2204 __ bind(&cont); 2173 __ bind(&cont);
2205 } 2174 }
2206 2175
2207 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper()); 2176 __ InvokeFunction(rdi, actual, JUMP_FUNCTION, NullCallWrapper());
2208 2177
2209 __ bind(&slow); 2178 __ bind(&slow);
2210 EmitSlowCase(isolate, masm, &args, argc, &non_function); 2179 EmitSlowCase(masm, &args, argc);
2211 2180
2212 if (CallAsMethod()) { 2181 if (CallAsMethod()) {
2213 __ bind(&wrap); 2182 __ bind(&wrap);
2214 EmitWrapCase(masm, &args, &cont); 2183 EmitWrapCase(masm, &args, &cont);
2215 } 2184 }
2216 2185
2217 __ bind(&extra_checks_or_miss); 2186 __ bind(&extra_checks_or_miss);
2218 Label uninitialized, miss; 2187 Label uninitialized, miss;
2219 2188
2220 __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate)); 2189 __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2281 __ jmp(&have_js_function); 2250 __ jmp(&have_js_function);
2282 2251
2283 // We are here because tracing is on or we encountered a MISS case we can't 2252 // We are here because tracing is on or we encountered a MISS case we can't
2284 // handle here. 2253 // handle here.
2285 __ bind(&miss); 2254 __ bind(&miss);
2286 GenerateMiss(masm); 2255 GenerateMiss(masm);
2287 2256
2288 // the slow case 2257 // the slow case
2289 __ bind(&slow_start); 2258 __ bind(&slow_start);
2290 // Check that function is not a smi. 2259 // Check that function is not a smi.
2291 __ JumpIfSmi(rdi, &non_function); 2260 __ JumpIfSmi(rdi, &slow);
2292 // Check that function is a JSFunction. 2261 // Check that function is a JSFunction.
2293 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 2262 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
2294 __ j(not_equal, &slow); 2263 __ j(not_equal, &slow);
2295 __ jmp(&have_js_function); 2264 __ jmp(&have_js_function);
2296 2265
2297 // Unreachable 2266 // Unreachable
2298 __ int3(); 2267 __ int3();
2299 } 2268 }
2300 2269
2301 2270
(...skipping 3323 matching lines...) Expand 10 before | Expand all | Expand 10 after
5625 kStackSpace, nullptr, return_value_operand, NULL); 5594 kStackSpace, nullptr, return_value_operand, NULL);
5626 } 5595 }
5627 5596
5628 5597
5629 #undef __ 5598 #undef __
5630 5599
5631 } // namespace internal 5600 } // namespace internal
5632 } // namespace v8 5601 } // namespace v8
5633 5602
5634 #endif // V8_TARGET_ARCH_X64 5603 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698