| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 name, depth2, miss); | 575 name, depth2, miss); |
| 576 } else { | 576 } else { |
| 577 // CheckPrototypes has a side effect of fetching a 'holder' | 577 // CheckPrototypes has a side effect of fetching a 'holder' |
| 578 // for API (object which is instanceof for the signature). It's | 578 // for API (object which is instanceof for the signature). It's |
| 579 // safe to omit it here, as if present, it should be fetched | 579 // safe to omit it here, as if present, it should be fetched |
| 580 // by the previous CheckPrototypes. | 580 // by the previous CheckPrototypes. |
| 581 ASSERT(depth2 == kInvalidProtoDepth); | 581 ASSERT(depth2 == kInvalidProtoDepth); |
| 582 } | 582 } |
| 583 | 583 |
| 584 // Invoke function. | 584 // Invoke function. |
| 585 ASSERT(!CallICBase::ConstructCall::decode(extra_state_)); |
| 585 if (can_do_fast_api_call) { | 586 if (can_do_fast_api_call) { |
| 586 GenerateFastApiCall(masm, optimization, arguments_.immediate()); | 587 GenerateFastApiCall(masm, optimization, arguments_.immediate()); |
| 587 } else { | 588 } else { |
| 588 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 589 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 589 ? CALL_AS_FUNCTION | 590 ? CALL_AS_FUNCTION |
| 590 : CALL_AS_METHOD; | 591 : CALL_AS_METHOD; |
| 591 __ InvokeFunction(optimization.constant_function(), arguments_, | 592 __ InvokeFunction(optimization.constant_function(), arguments_, |
| 592 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 593 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 593 } | 594 } |
| 594 | 595 |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 __ j(not_equal, &miss); | 1292 __ j(not_equal, &miss); |
| 1292 | 1293 |
| 1293 // Patch the receiver on the stack with the global proxy if | 1294 // Patch the receiver on the stack with the global proxy if |
| 1294 // necessary. | 1295 // necessary. |
| 1295 if (object->IsGlobalObject()) { | 1296 if (object->IsGlobalObject()) { |
| 1296 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 1297 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 1297 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 1298 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 1298 } | 1299 } |
| 1299 | 1300 |
| 1300 // Invoke the function. | 1301 // Invoke the function. |
| 1301 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 1302 if (CallICBase::ConstructCall::decode(extra_state_)) { |
| 1302 ? CALL_AS_FUNCTION | 1303 __ InvokeConstruct(edi, arguments()); |
| 1303 : CALL_AS_METHOD; | 1304 } else { |
| 1304 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 1305 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 1305 NullCallWrapper(), call_kind); | 1306 ? CALL_AS_FUNCTION |
| 1307 : CALL_AS_METHOD; |
| 1308 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, |
| 1309 NullCallWrapper(), call_kind); |
| 1310 } |
| 1306 | 1311 |
| 1307 // Handle call cache miss. | 1312 // Handle call cache miss. |
| 1308 __ bind(&miss); | 1313 __ bind(&miss); |
| 1309 GenerateMissBranch(); | 1314 GenerateMissBranch(); |
| 1310 | 1315 |
| 1311 // Return the generated code. | 1316 // Return the generated code. |
| 1312 return GetCode(FIELD, name); | 1317 return GetCode(FIELD, name); |
| 1313 } | 1318 } |
| 1314 | 1319 |
| 1315 | 1320 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1800 StringCharFromCodeGenerator generator(code, eax); | 1805 StringCharFromCodeGenerator generator(code, eax); |
| 1801 generator.GenerateFast(masm()); | 1806 generator.GenerateFast(masm()); |
| 1802 __ ret(2 * kPointerSize); | 1807 __ ret(2 * kPointerSize); |
| 1803 | 1808 |
| 1804 StubRuntimeCallHelper call_helper; | 1809 StubRuntimeCallHelper call_helper; |
| 1805 generator.GenerateSlow(masm(), call_helper); | 1810 generator.GenerateSlow(masm(), call_helper); |
| 1806 | 1811 |
| 1807 // Tail call the full function. We do not have to patch the receiver | 1812 // Tail call the full function. We do not have to patch the receiver |
| 1808 // because the function makes no use of it. | 1813 // because the function makes no use of it. |
| 1809 __ bind(&slow); | 1814 __ bind(&slow); |
| 1815 ASSERT(!CallICBase::ConstructCall::decode(extra_state_)); |
| 1810 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 1816 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 1811 ? CALL_AS_FUNCTION | 1817 ? CALL_AS_FUNCTION |
| 1812 : CALL_AS_METHOD; | 1818 : CALL_AS_METHOD; |
| 1813 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 1819 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
| 1814 NullCallWrapper(), call_kind); | 1820 NullCallWrapper(), call_kind); |
| 1815 | 1821 |
| 1816 __ bind(&miss); | 1822 __ bind(&miss); |
| 1817 // ecx: function name. | 1823 // ecx: function name. |
| 1818 GenerateMissBranch(); | 1824 GenerateMissBranch(); |
| 1819 | 1825 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 __ ret(2 * kPointerSize); | 1939 __ ret(2 * kPointerSize); |
| 1934 | 1940 |
| 1935 // Return the argument (when it's an already round heap number). | 1941 // Return the argument (when it's an already round heap number). |
| 1936 __ bind(&already_round); | 1942 __ bind(&already_round); |
| 1937 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 1943 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
| 1938 __ ret(2 * kPointerSize); | 1944 __ ret(2 * kPointerSize); |
| 1939 | 1945 |
| 1940 // Tail call the full function. We do not have to patch the receiver | 1946 // Tail call the full function. We do not have to patch the receiver |
| 1941 // because the function makes no use of it. | 1947 // because the function makes no use of it. |
| 1942 __ bind(&slow); | 1948 __ bind(&slow); |
| 1949 ASSERT(!CallICBase::ConstructCall::decode(extra_state_)); |
| 1943 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 1950 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
| 1944 NullCallWrapper(), CALL_AS_METHOD); | 1951 NullCallWrapper(), CALL_AS_METHOD); |
| 1945 | 1952 |
| 1946 __ bind(&miss); | 1953 __ bind(&miss); |
| 1947 // ecx: function name. | 1954 // ecx: function name. |
| 1948 GenerateMissBranch(); | 1955 GenerateMissBranch(); |
| 1949 | 1956 |
| 1950 // Return the generated code. | 1957 // Return the generated code. |
| 1951 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); | 1958 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); |
| 1952 } | 1959 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2038 __ and_(ebx, ~HeapNumber::kSignMask); | 2045 __ and_(ebx, ~HeapNumber::kSignMask); |
| 2039 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); | 2046 __ mov(ecx, FieldOperand(eax, HeapNumber::kMantissaOffset)); |
| 2040 __ AllocateHeapNumber(eax, edi, edx, &slow); | 2047 __ AllocateHeapNumber(eax, edi, edx, &slow); |
| 2041 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); | 2048 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ebx); |
| 2042 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); | 2049 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx); |
| 2043 __ ret(2 * kPointerSize); | 2050 __ ret(2 * kPointerSize); |
| 2044 | 2051 |
| 2045 // Tail call the full function. We do not have to patch the receiver | 2052 // Tail call the full function. We do not have to patch the receiver |
| 2046 // because the function makes no use of it. | 2053 // because the function makes no use of it. |
| 2047 __ bind(&slow); | 2054 __ bind(&slow); |
| 2055 ASSERT(!CallICBase::ConstructCall::decode(extra_state_)); |
| 2048 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2056 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
| 2049 NullCallWrapper(), CALL_AS_METHOD); | 2057 NullCallWrapper(), CALL_AS_METHOD); |
| 2050 | 2058 |
| 2051 __ bind(&miss); | 2059 __ bind(&miss); |
| 2052 // ecx: function name. | 2060 // ecx: function name. |
| 2053 GenerateMissBranch(); | 2061 GenerateMissBranch(); |
| 2054 | 2062 |
| 2055 // Return the generated code. | 2063 // Return the generated code. |
| 2056 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); | 2064 return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); |
| 2057 } | 2065 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2223 Handle<JSObject>(JSObject::cast(object->GetPrototype())), | 2231 Handle<JSObject>(JSObject::cast(object->GetPrototype())), |
| 2224 eax, holder, ebx, edx, edi, name, &miss); | 2232 eax, holder, ebx, edx, edi, name, &miss); |
| 2225 } else { | 2233 } else { |
| 2226 // Calling non-strict non-builtins with a value as the receiver | 2234 // Calling non-strict non-builtins with a value as the receiver |
| 2227 // requires boxing. | 2235 // requires boxing. |
| 2228 __ jmp(&miss); | 2236 __ jmp(&miss); |
| 2229 } | 2237 } |
| 2230 break; | 2238 break; |
| 2231 } | 2239 } |
| 2232 | 2240 |
| 2233 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2241 if (CallICBase::ConstructCall::decode(extra_state_)) { |
| 2234 ? CALL_AS_FUNCTION | 2242 __ InvokeConstruct(function, arguments()); |
| 2235 : CALL_AS_METHOD; | 2243 } else { |
| 2236 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2244 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2237 NullCallWrapper(), call_kind); | 2245 ? CALL_AS_FUNCTION |
| 2246 : CALL_AS_METHOD; |
| 2247 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
| 2248 NullCallWrapper(), call_kind); |
| 2249 } |
| 2238 | 2250 |
| 2239 // Handle call cache miss. | 2251 // Handle call cache miss. |
| 2240 __ bind(&miss); | 2252 __ bind(&miss); |
| 2241 GenerateMissBranch(); | 2253 GenerateMissBranch(); |
| 2242 | 2254 |
| 2243 // Return the generated code. | 2255 // Return the generated code. |
| 2244 return GetCode(function); | 2256 return GetCode(function); |
| 2245 } | 2257 } |
| 2246 | 2258 |
| 2247 | 2259 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2282 | 2294 |
| 2283 // Patch the receiver on the stack with the global proxy if | 2295 // Patch the receiver on the stack with the global proxy if |
| 2284 // necessary. | 2296 // necessary. |
| 2285 if (object->IsGlobalObject()) { | 2297 if (object->IsGlobalObject()) { |
| 2286 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2298 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 2287 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2299 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 2288 } | 2300 } |
| 2289 | 2301 |
| 2290 // Invoke the function. | 2302 // Invoke the function. |
| 2291 __ mov(edi, eax); | 2303 __ mov(edi, eax); |
| 2304 ASSERT(!CallICBase::ConstructCall::decode(extra_state_)); |
| 2292 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2305 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2293 ? CALL_AS_FUNCTION | 2306 ? CALL_AS_FUNCTION |
| 2294 : CALL_AS_METHOD; | 2307 : CALL_AS_METHOD; |
| 2295 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, | 2308 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, |
| 2296 NullCallWrapper(), call_kind); | 2309 NullCallWrapper(), call_kind); |
| 2297 | 2310 |
| 2298 // Handle load cache miss. | 2311 // Handle load cache miss. |
| 2299 __ bind(&miss); | 2312 __ bind(&miss); |
| 2300 GenerateMissBranch(); | 2313 GenerateMissBranch(); |
| 2301 | 2314 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2350 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 2338 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2351 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 2339 } | 2352 } |
| 2340 | 2353 |
| 2341 // Setup the context (function already in edi). | 2354 // Setup the context (function already in edi). |
| 2342 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2355 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 2343 | 2356 |
| 2344 // Jump to the cached code (tail call). | 2357 // Jump to the cached code (tail call). |
| 2345 Counters* counters = isolate()->counters(); | 2358 Counters* counters = isolate()->counters(); |
| 2346 __ IncrementCounter(counters->call_global_inline(), 1); | 2359 __ IncrementCounter(counters->call_global_inline(), 1); |
| 2347 ParameterCount expected(function->shared()->formal_parameter_count()); | 2360 if (CallICBase::ConstructCall::decode(extra_state_)) { |
| 2348 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2361 __ InvokeConstruct(edi, arguments()); |
| 2349 ? CALL_AS_FUNCTION | 2362 } else { |
| 2350 : CALL_AS_METHOD; | 2363 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2351 // We call indirectly through the code field in the function to | 2364 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2352 // allow recompilation to take effect without changing any of the | 2365 ? CALL_AS_FUNCTION |
| 2353 // call sites. | 2366 : CALL_AS_METHOD; |
| 2354 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 2367 // We call indirectly through the code field in the function to |
| 2355 expected, arguments(), JUMP_FUNCTION, | 2368 // allow recompilation to take effect without changing any of the |
| 2356 NullCallWrapper(), call_kind); | 2369 // call sites. |
| 2370 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
| 2371 expected, arguments(), JUMP_FUNCTION, |
| 2372 NullCallWrapper(), call_kind); |
| 2373 } |
| 2357 | 2374 |
| 2358 // Handle call cache miss. | 2375 // Handle call cache miss. |
| 2359 __ bind(&miss); | 2376 __ bind(&miss); |
| 2360 __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2377 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
| 2361 GenerateMissBranch(); | 2378 GenerateMissBranch(); |
| 2362 | 2379 |
| 2363 // Return the generated code. | 2380 // Return the generated code. |
| 2364 return GetCode(NORMAL, name); | 2381 return GetCode(NORMAL, name); |
| 2365 } | 2382 } |
| 2366 | 2383 |
| (...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3845 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3862 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 3846 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3863 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
| 3847 } | 3864 } |
| 3848 | 3865 |
| 3849 | 3866 |
| 3850 #undef __ | 3867 #undef __ |
| 3851 | 3868 |
| 3852 } } // namespace v8::internal | 3869 } } // namespace v8::internal |
| 3853 | 3870 |
| 3854 #endif // V8_TARGET_ARCH_IA32 | 3871 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |