| 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_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 2021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2032 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 2032 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
| 2033 __ j(not_equal, cont); | 2033 __ j(not_equal, cont); |
| 2034 | 2034 |
| 2035 // Do not transform the receiver for natives (shared already in ecx). | 2035 // Do not transform the receiver for natives (shared already in ecx). |
| 2036 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), | 2036 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kNativeByteOffset), |
| 2037 1 << SharedFunctionInfo::kNativeBitWithinByte); | 2037 1 << SharedFunctionInfo::kNativeBitWithinByte); |
| 2038 __ j(not_equal, cont); | 2038 __ j(not_equal, cont); |
| 2039 } | 2039 } |
| 2040 | 2040 |
| 2041 | 2041 |
| 2042 static void EmitSlowCase(Isolate* isolate, | 2042 static void EmitSlowCase(Isolate* isolate, MacroAssembler* masm, int argc) { |
| 2043 MacroAssembler* masm, | 2043 __ Set(eax, argc); |
| 2044 int argc, | 2044 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2045 Label* non_function) { | |
| 2046 // Check for function proxy. | |
| 2047 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | |
| 2048 __ j(not_equal, non_function); | |
| 2049 __ pop(ecx); | |
| 2050 __ push(edi); // put proxy as additional argument under return address | |
| 2051 __ push(ecx); | |
| 2052 __ Move(eax, Immediate(argc + 1)); | |
| 2053 __ Move(ebx, Immediate(0)); | |
| 2054 __ GetBuiltinEntry(edx, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); | |
| 2055 { | |
| 2056 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | |
| 2057 __ jmp(adaptor, RelocInfo::CODE_TARGET); | |
| 2058 } | |
| 2059 | |
| 2060 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | |
| 2061 // of the original receiver from the call site). | |
| 2062 __ bind(non_function); | |
| 2063 __ mov(Operand(esp, (argc + 1) * kPointerSize), edi); | |
| 2064 __ Move(eax, Immediate(argc)); | |
| 2065 __ Move(ebx, Immediate(0)); | |
| 2066 __ GetBuiltinEntry(edx, Context::CALL_NON_FUNCTION_BUILTIN_INDEX); | |
| 2067 Handle<Code> adaptor = isolate->builtins()->ArgumentsAdaptorTrampoline(); | |
| 2068 __ jmp(adaptor, RelocInfo::CODE_TARGET); | |
| 2069 } | 2045 } |
| 2070 | 2046 |
| 2071 | 2047 |
| 2072 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2048 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
| 2073 // Wrap the receiver and patch it back onto the stack. | 2049 // Wrap the receiver and patch it back onto the stack. |
| 2074 { FrameScope frame_scope(masm, StackFrame::INTERNAL); | 2050 { FrameScope frame_scope(masm, StackFrame::INTERNAL); |
| 2075 __ push(edi); | 2051 __ push(edi); |
| 2076 ToObjectStub stub(masm->isolate()); | 2052 ToObjectStub stub(masm->isolate()); |
| 2077 __ CallStub(&stub); | 2053 __ CallStub(&stub); |
| 2078 __ pop(edi); | 2054 __ pop(edi); |
| 2079 } | 2055 } |
| 2080 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); | 2056 __ mov(Operand(esp, (argc + 1) * kPointerSize), eax); |
| 2081 __ jmp(cont); | 2057 __ jmp(cont); |
| 2082 } | 2058 } |
| 2083 | 2059 |
| 2084 | 2060 |
| 2085 static void CallFunctionNoFeedback(MacroAssembler* masm, | 2061 static void CallFunctionNoFeedback(MacroAssembler* masm, |
| 2086 int argc, bool needs_checks, | 2062 int argc, bool needs_checks, |
| 2087 bool call_as_method) { | 2063 bool call_as_method) { |
| 2088 // edi : the function to call | 2064 // edi : the function to call |
| 2089 Label slow, non_function, wrap, cont; | 2065 Label slow, wrap, cont; |
| 2090 | 2066 |
| 2091 if (needs_checks) { | 2067 if (needs_checks) { |
| 2092 // Check that the function really is a JavaScript function. | 2068 // Check that the function really is a JavaScript function. |
| 2093 __ JumpIfSmi(edi, &non_function); | 2069 __ JumpIfSmi(edi, &slow); |
| 2094 | 2070 |
| 2095 // Goto slow case if we do not have a function. | 2071 // Goto slow case if we do not have a function. |
| 2096 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2072 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2097 __ j(not_equal, &slow); | 2073 __ j(not_equal, &slow); |
| 2098 } | 2074 } |
| 2099 | 2075 |
| 2100 // Fast-case: Just invoke the function. | 2076 // Fast-case: Just invoke the function. |
| 2101 ParameterCount actual(argc); | 2077 ParameterCount actual(argc); |
| 2102 | 2078 |
| 2103 if (call_as_method) { | 2079 if (call_as_method) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2118 } | 2094 } |
| 2119 | 2095 |
| 2120 __ bind(&cont); | 2096 __ bind(&cont); |
| 2121 } | 2097 } |
| 2122 | 2098 |
| 2123 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2099 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2124 | 2100 |
| 2125 if (needs_checks) { | 2101 if (needs_checks) { |
| 2126 // Slow-case: Non-function called. | 2102 // Slow-case: Non-function called. |
| 2127 __ bind(&slow); | 2103 __ bind(&slow); |
| 2128 // (non_function is bound in EmitSlowCase) | 2104 EmitSlowCase(masm->isolate(), masm, argc); |
| 2129 EmitSlowCase(masm->isolate(), masm, argc, &non_function); | |
| 2130 } | 2105 } |
| 2131 | 2106 |
| 2132 if (call_as_method) { | 2107 if (call_as_method) { |
| 2133 __ bind(&wrap); | 2108 __ bind(&wrap); |
| 2134 EmitWrapCase(masm, argc, &cont); | 2109 EmitWrapCase(masm, argc, &cont); |
| 2135 } | 2110 } |
| 2136 } | 2111 } |
| 2137 | 2112 |
| 2138 | 2113 |
| 2139 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2114 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2263 | 2238 |
| 2264 __ mov(ebx, ecx); | 2239 __ mov(ebx, ecx); |
| 2265 __ mov(edx, edi); | 2240 __ mov(edx, edi); |
| 2266 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2241 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2267 __ TailCallStub(&stub); | 2242 __ TailCallStub(&stub); |
| 2268 | 2243 |
| 2269 __ bind(&miss); | 2244 __ bind(&miss); |
| 2270 GenerateMiss(masm); | 2245 GenerateMiss(masm); |
| 2271 | 2246 |
| 2272 // The slow case, we need this no matter what to complete a call after a miss. | 2247 // The slow case, we need this no matter what to complete a call after a miss. |
| 2273 CallFunctionNoFeedback(masm, | 2248 __ Set(eax, arg_count()); |
| 2274 arg_count(), | 2249 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2275 true, | |
| 2276 CallAsMethod()); | |
| 2277 | |
| 2278 // Unreachable. | |
| 2279 __ int3(); | |
| 2280 } | 2250 } |
| 2281 | 2251 |
| 2282 | 2252 |
| 2283 void CallICStub::Generate(MacroAssembler* masm) { | 2253 void CallICStub::Generate(MacroAssembler* masm) { |
| 2284 // edi - function | 2254 // edi - function |
| 2285 // edx - slot id | 2255 // edx - slot id |
| 2286 // ebx - vector | 2256 // ebx - vector |
| 2287 Isolate* isolate = masm->isolate(); | 2257 Isolate* isolate = masm->isolate(); |
| 2288 const int with_types_offset = | 2258 const int with_types_offset = |
| 2289 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 2259 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2290 const int generic_offset = | 2260 const int generic_offset = |
| 2291 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 2261 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
| 2292 Label extra_checks_or_miss, slow_start; | 2262 Label extra_checks_or_miss, slow_start; |
| 2293 Label slow, non_function, wrap, cont; | 2263 Label slow, wrap, cont; |
| 2294 Label have_js_function; | 2264 Label have_js_function; |
| 2295 int argc = arg_count(); | 2265 int argc = arg_count(); |
| 2296 ParameterCount actual(argc); | 2266 ParameterCount actual(argc); |
| 2297 | 2267 |
| 2298 // The checks. First, does edi match the recorded monomorphic target? | 2268 // The checks. First, does edi match the recorded monomorphic target? |
| 2299 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, | 2269 __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 2300 FixedArray::kHeaderSize)); | 2270 FixedArray::kHeaderSize)); |
| 2301 | 2271 |
| 2302 // We don't know that we have a weak cell. We might have a private symbol | 2272 // We don't know that we have a weak cell. We might have a private symbol |
| 2303 // or an AllocationSite, but the memory is safe to examine. | 2273 // or an AllocationSite, but the memory is safe to examine. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2336 | 2306 |
| 2337 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); | 2307 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); |
| 2338 __ j(below, &wrap); | 2308 __ j(below, &wrap); |
| 2339 | 2309 |
| 2340 __ bind(&cont); | 2310 __ bind(&cont); |
| 2341 } | 2311 } |
| 2342 | 2312 |
| 2343 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2313 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2344 | 2314 |
| 2345 __ bind(&slow); | 2315 __ bind(&slow); |
| 2346 EmitSlowCase(isolate, masm, argc, &non_function); | 2316 EmitSlowCase(isolate, masm, argc); |
| 2347 | 2317 |
| 2348 if (CallAsMethod()) { | 2318 if (CallAsMethod()) { |
| 2349 __ bind(&wrap); | 2319 __ bind(&wrap); |
| 2350 EmitWrapCase(masm, argc, &cont); | 2320 EmitWrapCase(masm, argc, &cont); |
| 2351 } | 2321 } |
| 2352 | 2322 |
| 2353 __ bind(&extra_checks_or_miss); | 2323 __ bind(&extra_checks_or_miss); |
| 2354 Label uninitialized, miss; | 2324 Label uninitialized, miss; |
| 2355 | 2325 |
| 2356 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); | 2326 __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2417 | 2387 |
| 2418 // We are here because tracing is on or we encountered a MISS case we can't | 2388 // We are here because tracing is on or we encountered a MISS case we can't |
| 2419 // handle here. | 2389 // handle here. |
| 2420 __ bind(&miss); | 2390 __ bind(&miss); |
| 2421 GenerateMiss(masm); | 2391 GenerateMiss(masm); |
| 2422 | 2392 |
| 2423 // the slow case | 2393 // the slow case |
| 2424 __ bind(&slow_start); | 2394 __ bind(&slow_start); |
| 2425 | 2395 |
| 2426 // Check that the function really is a JavaScript function. | 2396 // Check that the function really is a JavaScript function. |
| 2427 __ JumpIfSmi(edi, &non_function); | 2397 __ JumpIfSmi(edi, &slow); |
| 2428 | 2398 |
| 2429 // Goto slow case if we do not have a function. | 2399 // Goto slow case if we do not have a function. |
| 2430 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2400 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
| 2431 __ j(not_equal, &slow); | 2401 __ j(not_equal, &slow); |
| 2432 __ jmp(&have_js_function); | 2402 __ jmp(&have_js_function); |
| 2433 | 2403 |
| 2434 // Unreachable | 2404 // Unreachable |
| 2435 __ int3(); | 2405 __ int3(); |
| 2436 } | 2406 } |
| 2437 | 2407 |
| (...skipping 3406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5844 Operand(ebp, 7 * kPointerSize), NULL); | 5814 Operand(ebp, 7 * kPointerSize), NULL); |
| 5845 } | 5815 } |
| 5846 | 5816 |
| 5847 | 5817 |
| 5848 #undef __ | 5818 #undef __ |
| 5849 | 5819 |
| 5850 } // namespace internal | 5820 } // namespace internal |
| 5851 } // namespace v8 | 5821 } // namespace v8 |
| 5852 | 5822 |
| 5853 #endif // V8_TARGET_ARCH_IA32 | 5823 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |