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 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |