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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 8357010: Handlify the stub cache lookup and patching for CallIC and KeyedCallIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Do not assume functions are compiled when specializing. Created 9 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/test-debug.cc » ('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 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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/test-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698