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 1289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 __ j(not_equal, miss); | 1300 __ j(not_equal, miss); |
1301 } else { | 1301 } else { |
1302 __ Cmp(rdi, Handle<JSFunction>(function)); | 1302 __ Cmp(rdi, Handle<JSFunction>(function)); |
1303 __ j(not_equal, miss); | 1303 __ j(not_equal, miss); |
1304 } | 1304 } |
1305 } | 1305 } |
1306 | 1306 |
1307 | 1307 |
1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { | 1308 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
1309 MaybeObject* maybe_obj = | 1309 MaybeObject* maybe_obj = |
1310 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1310 isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), |
1311 kind_, | 1311 kind_, |
1312 extra_ic_state_); | 1312 extra_state_); |
1313 Object* obj; | 1313 Object* obj; |
1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1314 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1315 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1316 return obj; | 1316 return obj; |
1317 } | 1317 } |
1318 | 1318 |
1319 | 1319 |
1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, | 1320 MaybeObject* CallStubCompiler::CompileCallField(JSObject* object, |
1321 JSObject* holder, | 1321 JSObject* holder, |
1322 int index, | 1322 int index, |
(...skipping 30 matching lines...) Expand all Loading... |
1353 __ j(not_equal, &miss); | 1353 __ j(not_equal, &miss); |
1354 | 1354 |
1355 // Patch the receiver on the stack with the global proxy if | 1355 // Patch the receiver on the stack with the global proxy if |
1356 // necessary. | 1356 // necessary. |
1357 if (object->IsGlobalObject()) { | 1357 if (object->IsGlobalObject()) { |
1358 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 1358 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
1359 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 1359 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
1360 } | 1360 } |
1361 | 1361 |
1362 // Invoke the function. | 1362 // Invoke the function. |
1363 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1363 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1364 ? CALL_AS_FUNCTION | 1364 ? CALL_AS_FUNCTION |
1365 : CALL_AS_METHOD; | 1365 : CALL_AS_METHOD; |
1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 1366 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
1367 NullCallWrapper(), call_kind); | 1367 NullCallWrapper(), call_kind); |
1368 | 1368 |
1369 // Handle call cache miss. | 1369 // Handle call cache miss. |
1370 __ bind(&miss); | 1370 __ bind(&miss); |
1371 MaybeObject* maybe_result = GenerateMissBranch(); | 1371 MaybeObject* maybe_result = GenerateMissBranch(); |
1372 if (maybe_result->IsFailure()) return maybe_result; | 1372 if (maybe_result->IsFailure()) return maybe_result; |
1373 | 1373 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1662 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1663 | 1663 |
1664 const int argc = arguments().immediate(); | 1664 const int argc = arguments().immediate(); |
1665 | 1665 |
1666 Label miss; | 1666 Label miss; |
1667 Label name_miss; | 1667 Label name_miss; |
1668 Label index_out_of_range; | 1668 Label index_out_of_range; |
1669 Label* index_out_of_range_label = &index_out_of_range; | 1669 Label* index_out_of_range_label = &index_out_of_range; |
1670 | 1670 |
1671 if (kind_ == Code::CALL_IC && | 1671 if (kind_ == Code::CALL_IC && |
1672 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1672 (CallICBase::StringStubState::decode(extra_state_) == |
1673 DEFAULT_STRING_STUB)) { | 1673 DEFAULT_STRING_STUB)) { |
1674 index_out_of_range_label = &miss; | 1674 index_out_of_range_label = &miss; |
1675 } | 1675 } |
1676 | 1676 |
1677 GenerateNameCheck(name, &name_miss); | 1677 GenerateNameCheck(name, &name_miss); |
1678 | 1678 |
1679 // Check that the maps starting from the prototype haven't changed. | 1679 // Check that the maps starting from the prototype haven't changed. |
1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1680 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1681 Context::STRING_FUNCTION_INDEX, | 1681 Context::STRING_FUNCTION_INDEX, |
1682 rax, | 1682 rax, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); | 1746 if (!object->IsString() || cell != NULL) return heap()->undefined_value(); |
1747 | 1747 |
1748 const int argc = arguments().immediate(); | 1748 const int argc = arguments().immediate(); |
1749 | 1749 |
1750 Label miss; | 1750 Label miss; |
1751 Label name_miss; | 1751 Label name_miss; |
1752 Label index_out_of_range; | 1752 Label index_out_of_range; |
1753 Label* index_out_of_range_label = &index_out_of_range; | 1753 Label* index_out_of_range_label = &index_out_of_range; |
1754 | 1754 |
1755 if (kind_ == Code::CALL_IC && | 1755 if (kind_ == Code::CALL_IC && |
1756 (CallICBase::StringStubState::decode(extra_ic_state_) == | 1756 (CallICBase::StringStubState::decode(extra_state_) == |
1757 DEFAULT_STRING_STUB)) { | 1757 DEFAULT_STRING_STUB)) { |
1758 index_out_of_range_label = &miss; | 1758 index_out_of_range_label = &miss; |
1759 } | 1759 } |
1760 | 1760 |
1761 GenerateNameCheck(name, &name_miss); | 1761 GenerateNameCheck(name, &name_miss); |
1762 | 1762 |
1763 // Check that the maps starting from the prototype haven't changed. | 1763 // Check that the maps starting from the prototype haven't changed. |
1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1764 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1765 Context::STRING_FUNCTION_INDEX, | 1765 Context::STRING_FUNCTION_INDEX, |
1766 rax, | 1766 rax, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 StringCharFromCodeGenerator char_from_code_generator(code, rax); | 1864 StringCharFromCodeGenerator char_from_code_generator(code, rax); |
1865 char_from_code_generator.GenerateFast(masm()); | 1865 char_from_code_generator.GenerateFast(masm()); |
1866 __ ret(2 * kPointerSize); | 1866 __ ret(2 * kPointerSize); |
1867 | 1867 |
1868 StubRuntimeCallHelper call_helper; | 1868 StubRuntimeCallHelper call_helper; |
1869 char_from_code_generator.GenerateSlow(masm(), call_helper); | 1869 char_from_code_generator.GenerateSlow(masm(), call_helper); |
1870 | 1870 |
1871 // Tail call the full function. We do not have to patch the receiver | 1871 // Tail call the full function. We do not have to patch the receiver |
1872 // because the function makes no use of it. | 1872 // because the function makes no use of it. |
1873 __ bind(&slow); | 1873 __ bind(&slow); |
1874 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1874 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1875 ? CALL_AS_FUNCTION | 1875 ? CALL_AS_FUNCTION |
1876 : CALL_AS_METHOD; | 1876 : CALL_AS_METHOD; |
1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 1877 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1878 NullCallWrapper(), call_kind); | 1878 NullCallWrapper(), call_kind); |
1879 | 1879 |
1880 __ bind(&miss); | 1880 __ bind(&miss); |
1881 // rcx: function name. | 1881 // rcx: function name. |
1882 MaybeObject* maybe_result = GenerateMissBranch(); | 1882 MaybeObject* maybe_result = GenerateMissBranch(); |
1883 if (maybe_result->IsFailure()) return maybe_result; | 1883 if (maybe_result->IsFailure()) return maybe_result; |
1884 | 1884 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 // number. We still have the sign mask in rdi. | 1981 // number. We still have the sign mask in rdi. |
1982 __ bind(&negative_sign); | 1982 __ bind(&negative_sign); |
1983 __ xor_(rbx, rdi); | 1983 __ xor_(rbx, rdi); |
1984 __ AllocateHeapNumber(rax, rdx, &slow); | 1984 __ AllocateHeapNumber(rax, rdx, &slow); |
1985 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); | 1985 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); |
1986 __ ret(2 * kPointerSize); | 1986 __ ret(2 * kPointerSize); |
1987 | 1987 |
1988 // Tail call the full function. We do not have to patch the receiver | 1988 // Tail call the full function. We do not have to patch the receiver |
1989 // because the function makes no use of it. | 1989 // because the function makes no use of it. |
1990 __ bind(&slow); | 1990 __ bind(&slow); |
1991 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 1991 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
1992 ? CALL_AS_FUNCTION | 1992 ? CALL_AS_FUNCTION |
1993 : CALL_AS_METHOD; | 1993 : CALL_AS_METHOD; |
1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 1994 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
1995 NullCallWrapper(), call_kind); | 1995 NullCallWrapper(), call_kind); |
1996 | 1996 |
1997 __ bind(&miss); | 1997 __ bind(&miss); |
1998 // rcx: function name. | 1998 // rcx: function name. |
1999 MaybeObject* maybe_result = GenerateMissBranch(); | 1999 MaybeObject* maybe_result = GenerateMissBranch(); |
2000 if (maybe_result->IsFailure()) return maybe_result; | 2000 if (maybe_result->IsFailure()) return maybe_result; |
2001 | 2001 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2179 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 2179 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
2180 rbx, rdx, rdi, name, &miss); | 2180 rbx, rdx, rdi, name, &miss); |
2181 } | 2181 } |
2182 break; | 2182 break; |
2183 } | 2183 } |
2184 | 2184 |
2185 default: | 2185 default: |
2186 UNREACHABLE(); | 2186 UNREACHABLE(); |
2187 } | 2187 } |
2188 | 2188 |
2189 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2189 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2190 ? CALL_AS_FUNCTION | 2190 ? CALL_AS_FUNCTION |
2191 : CALL_AS_METHOD; | 2191 : CALL_AS_METHOD; |
2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, | 2192 __ InvokeFunction(function, arguments(), JUMP_FUNCTION, |
2193 NullCallWrapper(), call_kind); | 2193 NullCallWrapper(), call_kind); |
2194 | 2194 |
2195 // Handle call cache miss. | 2195 // Handle call cache miss. |
2196 __ bind(&miss); | 2196 __ bind(&miss); |
2197 MaybeObject* maybe_result = GenerateMissBranch(); | 2197 MaybeObject* maybe_result = GenerateMissBranch(); |
2198 if (maybe_result->IsFailure()) return maybe_result; | 2198 if (maybe_result->IsFailure()) return maybe_result; |
2199 | 2199 |
(...skipping 20 matching lines...) Expand all Loading... |
2220 | 2220 |
2221 // Get the number of arguments. | 2221 // Get the number of arguments. |
2222 const int argc = arguments().immediate(); | 2222 const int argc = arguments().immediate(); |
2223 | 2223 |
2224 LookupResult lookup(isolate()); | 2224 LookupResult lookup(isolate()); |
2225 LookupPostInterceptor(holder, name, &lookup); | 2225 LookupPostInterceptor(holder, name, &lookup); |
2226 | 2226 |
2227 // Get the receiver from the stack. | 2227 // Get the receiver from the stack. |
2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2228 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2229 | 2229 |
2230 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_ic_state_); | 2230 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_); |
2231 MaybeObject* result = compiler.Compile(masm(), | 2231 MaybeObject* result = compiler.Compile(masm(), |
2232 object, | 2232 object, |
2233 holder, | 2233 holder, |
2234 name, | 2234 name, |
2235 &lookup, | 2235 &lookup, |
2236 rdx, | 2236 rdx, |
2237 rbx, | 2237 rbx, |
2238 rdi, | 2238 rdi, |
2239 rax, | 2239 rax, |
2240 &miss); | 2240 &miss); |
2241 if (result->IsFailure()) return result; | 2241 if (result->IsFailure()) return result; |
2242 | 2242 |
2243 // Restore receiver. | 2243 // Restore receiver. |
2244 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 2244 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
2245 | 2245 |
2246 // Check that the function really is a function. | 2246 // Check that the function really is a function. |
2247 __ JumpIfSmi(rax, &miss); | 2247 __ JumpIfSmi(rax, &miss); |
2248 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 2248 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
2249 __ j(not_equal, &miss); | 2249 __ j(not_equal, &miss); |
2250 | 2250 |
2251 // Patch the receiver on the stack with the global proxy if | 2251 // Patch the receiver on the stack with the global proxy if |
2252 // necessary. | 2252 // necessary. |
2253 if (object->IsGlobalObject()) { | 2253 if (object->IsGlobalObject()) { |
2254 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2254 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2255 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2255 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2256 } | 2256 } |
2257 | 2257 |
2258 // Invoke the function. | 2258 // Invoke the function. |
2259 __ movq(rdi, rax); | 2259 __ movq(rdi, rax); |
2260 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2260 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2261 ? CALL_AS_FUNCTION | 2261 ? CALL_AS_FUNCTION |
2262 : CALL_AS_METHOD; | 2262 : CALL_AS_METHOD; |
2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, | 2263 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, |
2264 NullCallWrapper(), call_kind); | 2264 NullCallWrapper(), call_kind); |
2265 | 2265 |
2266 // Handle load cache miss. | 2266 // Handle load cache miss. |
2267 __ bind(&miss); | 2267 __ bind(&miss); |
2268 MaybeObject* maybe_result = GenerateMissBranch(); | 2268 MaybeObject* maybe_result = GenerateMissBranch(); |
2269 if (maybe_result->IsFailure()) return maybe_result; | 2269 if (maybe_result->IsFailure()) return maybe_result; |
2270 | 2270 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 2313 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
2314 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 2314 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
2315 } | 2315 } |
2316 | 2316 |
2317 // Setup the context (function already in rdi). | 2317 // Setup the context (function already in rdi). |
2318 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 2318 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
2319 | 2319 |
2320 // Jump to the cached code (tail call). | 2320 // Jump to the cached code (tail call). |
2321 Counters* counters = isolate()->counters(); | 2321 Counters* counters = isolate()->counters(); |
2322 __ IncrementCounter(counters->call_global_inline(), 1); | 2322 __ IncrementCounter(counters->call_global_inline(), 1); |
2323 ASSERT(function->is_compiled()); | |
2324 ParameterCount expected(function->shared()->formal_parameter_count()); | 2323 ParameterCount expected(function->shared()->formal_parameter_count()); |
2325 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) | 2324 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
2326 ? CALL_AS_FUNCTION | 2325 ? CALL_AS_FUNCTION |
2327 : CALL_AS_METHOD; | 2326 : CALL_AS_METHOD; |
2328 if (V8::UseCrankshaft()) { | 2327 // We call indirectly through the code field in the function to |
2329 // TODO(kasperl): For now, we always call indirectly through the | 2328 // allow recompilation to take effect without changing any of the |
2330 // code field in the function to allow recompilation to take effect | 2329 // call sites. |
2331 // without changing any of the call sites. | 2330 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
2332 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 2331 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, |
2333 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, | 2332 NullCallWrapper(), call_kind); |
2334 NullCallWrapper(), call_kind); | 2333 |
2335 } else { | |
2336 Handle<Code> code(function->code()); | |
2337 __ InvokeCode(code, expected, arguments(), | |
2338 RelocInfo::CODE_TARGET, JUMP_FUNCTION, | |
2339 NullCallWrapper(), call_kind); | |
2340 } | |
2341 // Handle call cache miss. | 2334 // Handle call cache miss. |
2342 __ bind(&miss); | 2335 __ bind(&miss); |
2343 __ IncrementCounter(counters->call_global_inline_miss(), 1); | 2336 __ IncrementCounter(counters->call_global_inline_miss(), 1); |
2344 MaybeObject* maybe_result = GenerateMissBranch(); | 2337 MaybeObject* maybe_result = GenerateMissBranch(); |
2345 if (maybe_result->IsFailure()) return maybe_result; | 2338 if (maybe_result->IsFailure()) return maybe_result; |
2346 | 2339 |
2347 // Return the generated code. | 2340 // Return the generated code. |
2348 return GetCode(NORMAL, name); | 2341 return GetCode(NORMAL, name); |
2349 } | 2342 } |
2350 | 2343 |
(...skipping 1453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3804 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3797 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3805 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3798 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3806 } | 3799 } |
3807 | 3800 |
3808 | 3801 |
3809 #undef __ | 3802 #undef __ |
3810 | 3803 |
3811 } } // namespace v8::internal | 3804 } } // namespace v8::internal |
3812 | 3805 |
3813 #endif // V8_TARGET_ARCH_X64 | 3806 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |