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

Side by Side Diff: src/ia32/code-stubs-ia32.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/globals.h ('k') | src/ic/ic.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 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_IA32 5 #if V8_TARGET_ARCH_IA32
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 2011 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 CallStubInRecordCallTarget(masm, &create_stub, is_super); 2022 CallStubInRecordCallTarget(masm, &create_stub, is_super);
2023 __ jmp(&done); 2023 __ jmp(&done);
2024 2024
2025 __ bind(&not_array_function); 2025 __ bind(&not_array_function);
2026 CreateWeakCellStub weak_cell_stub(isolate); 2026 CreateWeakCellStub weak_cell_stub(isolate);
2027 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); 2027 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super);
2028 __ bind(&done); 2028 __ bind(&done);
2029 } 2029 }
2030 2030
2031 2031
2032 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
2033 // ----------- S t a t e -------------
2034 // -- edi : the function to call
2035 // -- edx : the function's shared function info
2036 // -----------------------------------
2037 // Do not transform the receiver for strict mode functions.
2038 __ test_b(FieldOperand(edx, SharedFunctionInfo::kStrictModeByteOffset),
2039 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
2040 __ j(not_equal, cont);
2041
2042 // Do not transform the receiver for natives (shared already in ecx).
2043 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
2044 1 << SharedFunctionInfo::kNativeBitWithinByte);
2045 __ j(not_equal, cont);
2046 }
2047
2048
2049 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) {
2050 __ Set(eax, argc);
2051 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2052 }
2053
2054
2055 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
2056 // Wrap the receiver and patch it back onto the stack.
2057 { FrameScope frame_scope(masm, StackFrame::INTERNAL);
2058 __ push(edi);
2059 ToObjectStub stub(masm->isolate());
2060 __ CallStub(&stub);
2061 __ pop(edi);
2062 }
2063 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax);
2064 __ jmp(cont);
2065 }
2066
2067
2068 static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
2069 // ----------- S t a t e -------------
2070 // -- edi : the function to call
2071 // -- edx : the function's shared function info
2072 // -----------------------------------
2073 // ClassConstructor Check: ES6 section 9.2.1 [[Call]]
2074 Label non_class_constructor;
2075 // Check whether the current function is a classConstructor.
2076 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
2077 SharedFunctionInfo::kClassConstructorBitsWithinByte);
2078 __ j(zero, &non_class_constructor, Label::kNear);
2079 // If we call a classConstructor Function throw a TypeError
2080 // indirectly via the CallFunction builtin.
2081 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
2082 __ bind(&non_class_constructor);
2083 }
2084
2085
2086 static void CallFunctionNoFeedback(MacroAssembler* masm,
2087 int argc, bool needs_checks,
2088 bool call_as_method) {
2089 // edi : the function to call
2090 Label slow, wrap, cont;
2091
2092 if (needs_checks) {
2093 // Check that the function really is a JavaScript function.
2094 __ JumpIfSmi(edi, &slow);
2095
2096 // Goto slow case if we do not have a function.
2097 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2098 __ j(not_equal, &slow);
2099 }
2100
2101 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
2102 EmitClassConstructorCallCheck(masm);
2103
2104 // Fast-case: Just invoke the function.
2105 ParameterCount actual(argc);
2106
2107 if (call_as_method) {
2108 if (needs_checks) {
2109 EmitContinueIfStrictOrNative(masm, &cont);
2110 }
2111
2112 // Load the receiver from the stack.
2113 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
2114
2115 if (needs_checks) {
2116 __ JumpIfSmi(eax, &wrap);
2117
2118 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2119 __ j(below, &wrap);
2120 } else {
2121 __ jmp(&wrap);
2122 }
2123
2124 __ bind(&cont);
2125 }
2126
2127 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2128
2129 if (needs_checks) {
2130 // Slow-case: Non-function called.
2131 __ bind(&slow);
2132 EmitSlowCase(masm->isolate(), masm, argc);
2133 }
2134
2135 if (call_as_method) {
2136 __ bind(&wrap);
2137 EmitWrapCase(masm, argc, &cont);
2138 }
2139 }
2140
2141
2142 void CallFunctionStub::Generate(MacroAssembler* masm) {
2143 CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
2144 }
2145
2146
2147 void CallConstructStub::Generate(MacroAssembler* masm) { 2032 void CallConstructStub::Generate(MacroAssembler* masm) {
2148 // eax : number of arguments 2033 // eax : number of arguments
2149 // ebx : feedback vector 2034 // ebx : feedback vector
2150 // ecx : original constructor (for IsSuperConstructorCall) 2035 // ecx : original constructor (for IsSuperConstructorCall)
2151 // edx : slot in feedback vector (Smi, for RecordCallTarget) 2036 // edx : slot in feedback vector (Smi, for RecordCallTarget)
2152 // edi : constructor function 2037 // edi : constructor function
2153 2038
2154 if (IsSuperConstructorCall()) { 2039 if (IsSuperConstructorCall()) {
2155 __ push(ecx); 2040 __ push(ecx);
2156 } 2041 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
2229 2114
2230 void CallICStub::Generate(MacroAssembler* masm) { 2115 void CallICStub::Generate(MacroAssembler* masm) {
2231 // edi - function 2116 // edi - function
2232 // edx - slot id 2117 // edx - slot id
2233 // ebx - vector 2118 // ebx - vector
2234 Isolate* isolate = masm->isolate(); 2119 Isolate* isolate = masm->isolate();
2235 const int with_types_offset = 2120 const int with_types_offset =
2236 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); 2121 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
2237 const int generic_offset = 2122 const int generic_offset =
2238 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); 2123 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
2239 Label extra_checks_or_miss, slow_start; 2124 Label extra_checks_or_miss, call;
2240 Label slow, wrap, cont;
2241 Label have_js_function;
2242 int argc = arg_count(); 2125 int argc = arg_count();
2243 ParameterCount actual(argc); 2126 ParameterCount actual(argc);
2244 2127
2245 // The checks. First, does edi match the recorded monomorphic target? 2128 // The checks. First, does edi match the recorded monomorphic target?
2246 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, 2129 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
2247 FixedArray::kHeaderSize)); 2130 FixedArray::kHeaderSize));
2248 2131
2249 // We don't know that we have a weak cell. We might have a private symbol 2132 // We don't know that we have a weak cell. We might have a private symbol
2250 // or an AllocationSite, but the memory is safe to examine. 2133 // or an AllocationSite, but the memory is safe to examine.
2251 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to 2134 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to
(...skipping 13 matching lines...) Expand all
2265 2148
2266 // The compare above could have been a SMI/SMI comparison. Guard against this 2149 // The compare above could have been a SMI/SMI comparison. Guard against this
2267 // convincing us that we have a monomorphic JSFunction. 2150 // convincing us that we have a monomorphic JSFunction.
2268 __ JumpIfSmi(edi, &extra_checks_or_miss); 2151 __ JumpIfSmi(edi, &extra_checks_or_miss);
2269 2152
2270 // Increment the call count for monomorphic function calls. 2153 // Increment the call count for monomorphic function calls.
2271 __ add(FieldOperand(ebx, edx, times_half_pointer_size, 2154 __ add(FieldOperand(ebx, edx, times_half_pointer_size,
2272 FixedArray::kHeaderSize + kPointerSize), 2155 FixedArray::kHeaderSize + kPointerSize),
2273 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement))); 2156 Immediate(Smi::FromInt(CallICNexus::kCallCountIncrement)));
2274 2157
2275 __ bind(&have_js_function); 2158 __ bind(&call);
2276 2159 __ Set(eax, argc);
2277 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2160 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2278 EmitClassConstructorCallCheck(masm);
2279
2280 if (CallAsMethod()) {
2281 EmitContinueIfStrictOrNative(masm, &cont);
2282
2283 // Load the receiver from the stack.
2284 __ mov(eax, Operand(esp, (argc + 1) * kPointerSize));
2285
2286 __ JumpIfSmi(eax, &wrap);
2287
2288 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
2289 __ j(below, &wrap);
2290
2291 __ bind(&cont);
2292 }
2293
2294 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper());
2295
2296 __ bind(&slow);
2297 EmitSlowCase(isolate, masm, argc);
2298
2299 if (CallAsMethod()) {
2300 __ bind(&wrap);
2301 EmitWrapCase(masm, argc, &cont);
2302 }
2303 2161
2304 __ bind(&extra_checks_or_miss); 2162 __ bind(&extra_checks_or_miss);
2305 Label uninitialized, miss, not_allocation_site; 2163 Label uninitialized, miss, not_allocation_site;
2306 2164
2307 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); 2165 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
2308 __ j(equal, &slow_start); 2166 __ j(equal, &call);
2309 2167
2310 // Check if we have an allocation site. 2168 // Check if we have an allocation site.
2311 __ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset), 2169 __ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset),
2312 Heap::kAllocationSiteMapRootIndex); 2170 Heap::kAllocationSiteMapRootIndex);
2313 __ j(not_equal, &not_allocation_site); 2171 __ j(not_equal, &not_allocation_site);
2314 2172
2315 // We have an allocation site. 2173 // We have an allocation site.
2316 HandleArrayCase(masm, &miss); 2174 HandleArrayCase(masm, &miss);
2317 2175
2318 __ bind(&not_allocation_site); 2176 __ bind(&not_allocation_site);
(...skipping 11 matching lines...) Expand all
2330 // to handle it here. More complex cases are dealt with in the runtime. 2188 // to handle it here. More complex cases are dealt with in the runtime.
2331 __ AssertNotSmi(ecx); 2189 __ AssertNotSmi(ecx);
2332 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx); 2190 __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
2333 __ j(not_equal, &miss); 2191 __ j(not_equal, &miss);
2334 __ mov( 2192 __ mov(
2335 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), 2193 FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
2336 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); 2194 Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
2337 // We have to update statistics for runtime profiling. 2195 // We have to update statistics for runtime profiling.
2338 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); 2196 __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
2339 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1))); 2197 __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
2340 __ jmp(&slow_start); 2198 __ jmp(&call);
2341 2199
2342 __ bind(&uninitialized); 2200 __ bind(&uninitialized);
2343 2201
2344 // We are going monomorphic, provided we actually have a JSFunction. 2202 // We are going monomorphic, provided we actually have a JSFunction.
2345 __ JumpIfSmi(edi, &miss); 2203 __ JumpIfSmi(edi, &miss);
2346 2204
2347 // Goto miss case if we do not have a function. 2205 // Goto miss case if we do not have a function.
2348 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2206 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2349 __ j(not_equal, &miss); 2207 __ j(not_equal, &miss);
2350 2208
(...skipping 16 matching lines...) Expand all
2367 // edx - slot 2225 // edx - slot
2368 // edi - function 2226 // edi - function
2369 { 2227 {
2370 FrameScope scope(masm, StackFrame::INTERNAL); 2228 FrameScope scope(masm, StackFrame::INTERNAL);
2371 CreateWeakCellStub create_stub(isolate); 2229 CreateWeakCellStub create_stub(isolate);
2372 __ push(edi); 2230 __ push(edi);
2373 __ CallStub(&create_stub); 2231 __ CallStub(&create_stub);
2374 __ pop(edi); 2232 __ pop(edi);
2375 } 2233 }
2376 2234
2377 __ jmp(&have_js_function); 2235 __ jmp(&call);
2378 2236
2379 // We are here because tracing is on or we encountered a MISS case we can't 2237 // We are here because tracing is on or we encountered a MISS case we can't
2380 // handle here. 2238 // handle here.
2381 __ bind(&miss); 2239 __ bind(&miss);
2382 GenerateMiss(masm); 2240 GenerateMiss(masm);
2383 2241
2384 // the slow case 2242 __ jmp(&call);
2385 __ bind(&slow_start);
2386
2387 // Check that the function really is a JavaScript function.
2388 __ JumpIfSmi(edi, &slow);
2389
2390 // Goto slow case if we do not have a function.
2391 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2392 __ j(not_equal, &slow);
2393 __ jmp(&have_js_function);
2394 2243
2395 // Unreachable 2244 // Unreachable
2396 __ int3(); 2245 __ int3();
2397 } 2246 }
2398 2247
2399 2248
2400 void CallICStub::GenerateMiss(MacroAssembler* masm) { 2249 void CallICStub::GenerateMiss(MacroAssembler* masm) {
2401 FrameScope scope(masm, StackFrame::INTERNAL); 2250 FrameScope scope(masm, StackFrame::INTERNAL);
2402 2251
2403 // Push the function and feedback info. 2252 // Push the function and feedback info.
(...skipping 3492 matching lines...) Expand 10 before | Expand all | Expand 10 after
5896 Operand(ebp, 7 * kPointerSize), NULL); 5745 Operand(ebp, 7 * kPointerSize), NULL);
5897 } 5746 }
5898 5747
5899 5748
5900 #undef __ 5749 #undef __
5901 5750
5902 } // namespace internal 5751 } // namespace internal
5903 } // namespace v8 5752 } // namespace v8
5904 5753
5905 #endif // V8_TARGET_ARCH_IA32 5754 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/globals.h ('k') | src/ic/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698