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

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

Issue 7086029: Fix a number of IC stubs to correctly set the call kind. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Load global object from rsi on x64. Created 9 years, 6 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/mjsunit/bugs/bug-1412.js » ('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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // object. 471 // object.
472 return masm->TryCallApiFunctionAndReturn(&fun, 472 return masm->TryCallApiFunctionAndReturn(&fun,
473 argc + kFastApiCallArguments + 1); 473 argc + kFastApiCallArguments + 1);
474 } 474 }
475 475
476 476
477 class CallInterceptorCompiler BASE_EMBEDDED { 477 class CallInterceptorCompiler BASE_EMBEDDED {
478 public: 478 public:
479 CallInterceptorCompiler(StubCompiler* stub_compiler, 479 CallInterceptorCompiler(StubCompiler* stub_compiler,
480 const ParameterCount& arguments, 480 const ParameterCount& arguments,
481 Register name) 481 Register name,
482 Code::ExtraICState extra_ic_state)
482 : stub_compiler_(stub_compiler), 483 : stub_compiler_(stub_compiler),
483 arguments_(arguments), 484 arguments_(arguments),
484 name_(name) {} 485 name_(name),
486 extra_ic_state_(extra_ic_state) {}
485 487
486 MaybeObject* Compile(MacroAssembler* masm, 488 MaybeObject* Compile(MacroAssembler* masm,
487 JSObject* object, 489 JSObject* object,
488 JSObject* holder, 490 JSObject* holder,
489 String* name, 491 String* name,
490 LookupResult* lookup, 492 LookupResult* lookup,
491 Register receiver, 493 Register receiver,
492 Register scratch1, 494 Register scratch1,
493 Register scratch2, 495 Register scratch2,
494 Register scratch3, 496 Register scratch3,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 ASSERT(depth2 == kInvalidProtoDepth); 601 ASSERT(depth2 == kInvalidProtoDepth);
600 } 602 }
601 603
602 // Invoke function. 604 // Invoke function.
603 if (can_do_fast_api_call) { 605 if (can_do_fast_api_call) {
604 MaybeObject* result = GenerateFastApiCall(masm, 606 MaybeObject* result = GenerateFastApiCall(masm,
605 optimization, 607 optimization,
606 arguments_.immediate()); 608 arguments_.immediate());
607 if (result->IsFailure()) return result; 609 if (result->IsFailure()) return result;
608 } else { 610 } else {
611 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
612 ? CALL_AS_FUNCTION
613 : CALL_AS_METHOD;
609 __ InvokeFunction(optimization.constant_function(), arguments_, 614 __ InvokeFunction(optimization.constant_function(), arguments_,
610 JUMP_FUNCTION); 615 JUMP_FUNCTION, NullCallWrapper(), call_kind);
611 } 616 }
612 617
613 // Deferred code for fast API call case---clean preallocated space. 618 // Deferred code for fast API call case---clean preallocated space.
614 if (can_do_fast_api_call) { 619 if (can_do_fast_api_call) {
615 __ bind(&miss_cleanup); 620 __ bind(&miss_cleanup);
616 FreeSpaceForFastApiCall(masm, scratch1); 621 FreeSpaceForFastApiCall(masm, scratch1);
617 __ jmp(miss_label); 622 __ jmp(miss_label);
618 } 623 }
619 624
620 // Invoke a regular function. 625 // Invoke a regular function.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 __ pop(receiver); // Restore the holder. 684 __ pop(receiver); // Restore the holder.
680 __ LeaveInternalFrame(); 685 __ LeaveInternalFrame();
681 686
682 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 687 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
683 __ j(not_equal, interceptor_succeeded); 688 __ j(not_equal, interceptor_succeeded);
684 } 689 }
685 690
686 StubCompiler* stub_compiler_; 691 StubCompiler* stub_compiler_;
687 const ParameterCount& arguments_; 692 const ParameterCount& arguments_;
688 Register name_; 693 Register name_;
694 Code::ExtraICState extra_ic_state_;
689 }; 695 };
690 696
691 697
692 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 698 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
693 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 699 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC);
694 Code* code = NULL; 700 Code* code = NULL;
695 if (kind == Code::LOAD_IC) { 701 if (kind == Code::LOAD_IC) {
696 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss); 702 code = masm->isolate()->builtins()->builtin(Builtins::kLoadIC_Miss);
697 } else { 703 } else {
698 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss); 704 code = masm->isolate()->builtins()->builtin(Builtins::kKeyedLoadIC_Miss);
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 __ j(not_equal, &miss); 1347 __ j(not_equal, &miss);
1342 1348
1343 // Patch the receiver on the stack with the global proxy if 1349 // Patch the receiver on the stack with the global proxy if
1344 // necessary. 1350 // necessary.
1345 if (object->IsGlobalObject()) { 1351 if (object->IsGlobalObject()) {
1346 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 1352 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
1347 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 1353 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
1348 } 1354 }
1349 1355
1350 // Invoke the function. 1356 // Invoke the function.
1351 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION); 1357 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1358 ? CALL_AS_FUNCTION
1359 : CALL_AS_METHOD;
1360 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
1361 NullCallWrapper(), call_kind);
1352 1362
1353 // Handle call cache miss. 1363 // Handle call cache miss.
1354 __ bind(&miss); 1364 __ bind(&miss);
1355 MaybeObject* maybe_result = GenerateMissBranch(); 1365 MaybeObject* maybe_result = GenerateMissBranch();
1356 if (maybe_result->IsFailure()) return maybe_result; 1366 if (maybe_result->IsFailure()) return maybe_result;
1357 1367
1358 // Return the generated code. 1368 // Return the generated code.
1359 return GetCode(FIELD, name); 1369 return GetCode(FIELD, name);
1360 } 1370 }
1361 1371
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1824 StringCharFromCodeGenerator char_from_code_generator(code, rax); 1834 StringCharFromCodeGenerator char_from_code_generator(code, rax);
1825 char_from_code_generator.GenerateFast(masm()); 1835 char_from_code_generator.GenerateFast(masm());
1826 __ ret(2 * kPointerSize); 1836 __ ret(2 * kPointerSize);
1827 1837
1828 StubRuntimeCallHelper call_helper; 1838 StubRuntimeCallHelper call_helper;
1829 char_from_code_generator.GenerateSlow(masm(), call_helper); 1839 char_from_code_generator.GenerateSlow(masm(), call_helper);
1830 1840
1831 // Tail call the full function. We do not have to patch the receiver 1841 // Tail call the full function. We do not have to patch the receiver
1832 // because the function makes no use of it. 1842 // because the function makes no use of it.
1833 __ bind(&slow); 1843 __ bind(&slow);
1834 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 1844 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1845 ? CALL_AS_FUNCTION
1846 : CALL_AS_METHOD;
1847 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1848 NullCallWrapper(), call_kind);
1835 1849
1836 __ bind(&miss); 1850 __ bind(&miss);
1837 // rcx: function name. 1851 // rcx: function name.
1838 MaybeObject* maybe_result = GenerateMissBranch(); 1852 MaybeObject* maybe_result = GenerateMissBranch();
1839 if (maybe_result->IsFailure()) return maybe_result; 1853 if (maybe_result->IsFailure()) return maybe_result;
1840 1854
1841 // Return the generated code. 1855 // Return the generated code.
1842 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 1856 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
1843 } 1857 }
1844 1858
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 // number. We still have the sign mask in rdi. 1951 // number. We still have the sign mask in rdi.
1938 __ bind(&negative_sign); 1952 __ bind(&negative_sign);
1939 __ xor_(rbx, rdi); 1953 __ xor_(rbx, rdi);
1940 __ AllocateHeapNumber(rax, rdx, &slow); 1954 __ AllocateHeapNumber(rax, rdx, &slow);
1941 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 1955 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rbx);
1942 __ ret(2 * kPointerSize); 1956 __ ret(2 * kPointerSize);
1943 1957
1944 // Tail call the full function. We do not have to patch the receiver 1958 // Tail call the full function. We do not have to patch the receiver
1945 // because the function makes no use of it. 1959 // because the function makes no use of it.
1946 __ bind(&slow); 1960 __ bind(&slow);
1947 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 1961 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
1962 ? CALL_AS_FUNCTION
1963 : CALL_AS_METHOD;
1964 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
1965 NullCallWrapper(), call_kind);
1948 1966
1949 __ bind(&miss); 1967 __ bind(&miss);
1950 // rcx: function name. 1968 // rcx: function name.
1951 MaybeObject* maybe_result = GenerateMissBranch(); 1969 MaybeObject* maybe_result = GenerateMissBranch();
1952 if (maybe_result->IsFailure()) return maybe_result; 1970 if (maybe_result->IsFailure()) return maybe_result;
1953 1971
1954 // Return the generated code. 1972 // Return the generated code.
1955 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); 1973 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name);
1956 } 1974 }
1957 1975
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, 2149 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
2132 rbx, rdx, rdi, name, &miss); 2150 rbx, rdx, rdi, name, &miss);
2133 } 2151 }
2134 break; 2152 break;
2135 } 2153 }
2136 2154
2137 default: 2155 default:
2138 UNREACHABLE(); 2156 UNREACHABLE();
2139 } 2157 }
2140 2158
2141 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); 2159 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
2160 ? CALL_AS_FUNCTION
2161 : CALL_AS_METHOD;
2162 __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
2163 NullCallWrapper(), call_kind);
2142 2164
2143 // Handle call cache miss. 2165 // Handle call cache miss.
2144 __ bind(&miss); 2166 __ bind(&miss);
2145 MaybeObject* maybe_result = GenerateMissBranch(); 2167 MaybeObject* maybe_result = GenerateMissBranch();
2146 if (maybe_result->IsFailure()) return maybe_result; 2168 if (maybe_result->IsFailure()) return maybe_result;
2147 2169
2148 // Return the generated code. 2170 // Return the generated code.
2149 return GetCode(function); 2171 return GetCode(function);
2150 } 2172 }
2151 2173
(...skipping 16 matching lines...) Expand all
2168 2190
2169 // Get the number of arguments. 2191 // Get the number of arguments.
2170 const int argc = arguments().immediate(); 2192 const int argc = arguments().immediate();
2171 2193
2172 LookupResult lookup; 2194 LookupResult lookup;
2173 LookupPostInterceptor(holder, name, &lookup); 2195 LookupPostInterceptor(holder, name, &lookup);
2174 2196
2175 // Get the receiver from the stack. 2197 // Get the receiver from the stack.
2176 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2198 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2177 2199
2178 CallInterceptorCompiler compiler(this, arguments(), rcx); 2200 CallInterceptorCompiler compiler(this, arguments(), rcx, extra_ic_state_);
2179 MaybeObject* result = compiler.Compile(masm(), 2201 MaybeObject* result = compiler.Compile(masm(),
2180 object, 2202 object,
2181 holder, 2203 holder,
2182 name, 2204 name,
2183 &lookup, 2205 &lookup,
2184 rdx, 2206 rdx,
2185 rbx, 2207 rbx,
2186 rdi, 2208 rdi,
2187 rax, 2209 rax,
2188 &miss); 2210 &miss);
2189 if (result->IsFailure()) return result; 2211 if (result->IsFailure()) return result;
2190 2212
2191 // Restore receiver. 2213 // Restore receiver.
2192 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 2214 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
2193 2215
2194 // Check that the function really is a function. 2216 // Check that the function really is a function.
2195 __ JumpIfSmi(rax, &miss); 2217 __ JumpIfSmi(rax, &miss);
2196 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 2218 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
2197 __ j(not_equal, &miss); 2219 __ j(not_equal, &miss);
2198 2220
2199 // Patch the receiver on the stack with the global proxy if 2221 // Patch the receiver on the stack with the global proxy if
2200 // necessary. 2222 // necessary.
2201 if (object->IsGlobalObject()) { 2223 if (object->IsGlobalObject()) {
2202 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2224 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
2203 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 2225 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
2204 } 2226 }
2205 2227
2206 // Invoke the function. 2228 // Invoke the function.
2207 __ movq(rdi, rax); 2229 __ movq(rdi, rax);
2208 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION); 2230 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
2231 ? CALL_AS_FUNCTION
2232 : CALL_AS_METHOD;
2233 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
2234 NullCallWrapper(), call_kind);
2209 2235
2210 // Handle load cache miss. 2236 // Handle load cache miss.
2211 __ bind(&miss); 2237 __ bind(&miss);
2212 MaybeObject* maybe_result = GenerateMissBranch(); 2238 MaybeObject* maybe_result = GenerateMissBranch();
2213 if (maybe_result->IsFailure()) return maybe_result; 2239 if (maybe_result->IsFailure()) return maybe_result;
2214 2240
2215 // Return the generated code. 2241 // Return the generated code.
2216 return GetCode(INTERCEPTOR, name); 2242 return GetCode(INTERCEPTOR, name);
2217 } 2243 }
2218 2244
2219 2245
2220 MaybeObject* CallStubCompiler::CompileCallGlobal( 2246 MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object,
2221 JSObject* object, 2247 GlobalObject* holder,
2222 GlobalObject* holder, 2248 JSGlobalPropertyCell* cell,
2223 JSGlobalPropertyCell* cell, 2249 JSFunction* function,
2224 JSFunction* function, 2250 String* name) {
2225 String* name,
2226 Code::ExtraICState extra_ic_state) {
2227 // ----------- S t a t e ------------- 2251 // ----------- S t a t e -------------
2228 // rcx : function name 2252 // rcx : function name
2229 // rsp[0] : return address 2253 // rsp[0] : return address
2230 // rsp[8] : argument argc 2254 // rsp[8] : argument argc
2231 // rsp[16] : argument argc - 1 2255 // rsp[16] : argument argc - 1
2232 // ... 2256 // ...
2233 // rsp[argc * 8] : argument 1 2257 // rsp[argc * 8] : argument 1
2234 // rsp[(argc + 1) * 8] : argument 0 = receiver 2258 // rsp[(argc + 1) * 8] : argument 0 = receiver
2235 // ----------------------------------- 2259 // -----------------------------------
2236 2260
(...skipping 24 matching lines...) Expand all
2261 } 2285 }
2262 2286
2263 // Setup the context (function already in rdi). 2287 // Setup the context (function already in rdi).
2264 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2288 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2265 2289
2266 // Jump to the cached code (tail call). 2290 // Jump to the cached code (tail call).
2267 Counters* counters = isolate()->counters(); 2291 Counters* counters = isolate()->counters();
2268 __ IncrementCounter(counters->call_global_inline(), 1); 2292 __ IncrementCounter(counters->call_global_inline(), 1);
2269 ASSERT(function->is_compiled()); 2293 ASSERT(function->is_compiled());
2270 ParameterCount expected(function->shared()->formal_parameter_count()); 2294 ParameterCount expected(function->shared()->formal_parameter_count());
2271 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state) 2295 CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_)
2272 ? CALL_AS_FUNCTION 2296 ? CALL_AS_FUNCTION
2273 : CALL_AS_METHOD; 2297 : CALL_AS_METHOD;
2274 if (V8::UseCrankshaft()) { 2298 if (V8::UseCrankshaft()) {
2275 // TODO(kasperl): For now, we always call indirectly through the 2299 // TODO(kasperl): For now, we always call indirectly through the
2276 // code field in the function to allow recompilation to take effect 2300 // code field in the function to allow recompilation to take effect
2277 // without changing any of the call sites. 2301 // without changing any of the call sites.
2278 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2302 __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2279 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION, 2303 __ InvokeCode(rdx, expected, arguments(), JUMP_FUNCTION,
2280 NullCallWrapper(), call_kind); 2304 NullCallWrapper(), call_kind);
2281 } else { 2305 } else {
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3601 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3625 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3602 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3626 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3603 } 3627 }
3604 3628
3605 3629
3606 #undef __ 3630 #undef __
3607 3631
3608 } } // namespace v8::internal 3632 } } // namespace v8::internal
3609 3633
3610 #endif // V8_TARGET_ARCH_X64 3634 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/mjsunit/bugs/bug-1412.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698