OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
531 // Generate call to api function. | 531 // Generate call to api function. |
532 static void GenerateFastApiCall(MacroAssembler* masm, | 532 static void GenerateFastApiCall(MacroAssembler* masm, |
533 const CallOptimization& optimization, | 533 const CallOptimization& optimization, |
534 Register receiver, | 534 Register receiver, |
535 Register scratch, | 535 Register scratch, |
536 int argc, | 536 int argc, |
537 Register* values) { | 537 Register* values) { |
538 ASSERT(optimization.is_simple_api_call()); | 538 ASSERT(optimization.is_simple_api_call()); |
539 ASSERT(!receiver.is(scratch)); | 539 ASSERT(!receiver.is(scratch)); |
540 | 540 |
541 const int stack_space = kFastApiCallArguments + argc + 1; | 541 int fast_api_call_argc = argc + kFastApiCallArguments; |
542 // Copy return value. | 542 StackArgumentsAccessor args(rsp, fast_api_call_argc); |
543 __ movq(scratch, Operand(rsp, 0)); | 543 |
544 // Assign stack space for the call arguments. | 544 __ movq(scratch, StackOperandForReturnAddress(0)); |
545 __ subq(rsp, Immediate(stack_space * kPointerSize)); | 545 // Assign stack space for the call arguments and receiver. |
546 // Move the return address on top of the stack. | 546 __ subq(rsp, Immediate((fast_api_call_argc + 1) * kPointerSize)); |
547 __ movq(Operand(rsp, 0), scratch); | 547 __ movq(StackOperandForReturnAddress(0), scratch); |
548 // Write holder to stack frame. | 548 // Write holder to stack frame. |
549 __ movq(Operand(rsp, 1 * kPointerSize), receiver); | 549 __ movq(args.GetArgumentOperand(fast_api_call_argc), receiver); |
550 // Write receiver to stack frame. | 550 __ movq(args.GetReceiverOperand(), receiver); |
551 int index = stack_space; | |
552 __ movq(Operand(rsp, index-- * kPointerSize), receiver); | |
553 // Write the arguments to stack frame. | 551 // Write the arguments to stack frame. |
554 for (int i = 0; i < argc; i++) { | 552 for (int i = 0; i < argc; i++) { |
555 ASSERT(!receiver.is(values[i])); | 553 ASSERT(!receiver.is(values[i])); |
556 ASSERT(!scratch.is(values[i])); | 554 ASSERT(!scratch.is(values[i])); |
557 __ movq(Operand(rsp, index-- * kPointerSize), values[i]); | 555 __ movq(args.GetArgumentOperand(i + 1), values[i]); |
558 } | 556 } |
559 | 557 |
560 GenerateFastApiCall(masm, optimization, argc); | 558 GenerateFastApiCall(masm, optimization, argc); |
561 } | 559 } |
562 | 560 |
563 | 561 |
564 class CallInterceptorCompiler BASE_EMBEDDED { | 562 class CallInterceptorCompiler BASE_EMBEDDED { |
565 public: | 563 public: |
566 CallInterceptorCompiler(StubCompiler* stub_compiler, | 564 CallInterceptorCompiler(StubCompiler* stub_compiler, |
567 const ParameterCount& arguments, | 565 const ParameterCount& arguments, |
(...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2164 // If the object is not a JSObject or we got an unexpected number of | 2162 // If the object is not a JSObject or we got an unexpected number of |
2165 // arguments, bail out to the regular call. | 2163 // arguments, bail out to the regular call. |
2166 const int argc = arguments().immediate(); | 2164 const int argc = arguments().immediate(); |
2167 StackArgumentsAccessor args(rsp, argc); | 2165 StackArgumentsAccessor args(rsp, argc); |
2168 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2166 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2169 | 2167 |
2170 Label miss; | 2168 Label miss; |
2171 GenerateNameCheck(name, &miss); | 2169 GenerateNameCheck(name, &miss); |
2172 | 2170 |
2173 if (cell.is_null()) { | 2171 if (cell.is_null()) { |
2174 __ movq(rdx, args.GetArgumentOperand(argc - 1)); | 2172 __ movq(rdx, args.GetReceiverOperand()); |
2175 __ JumpIfSmi(rdx, &miss); | 2173 __ JumpIfSmi(rdx, &miss); |
2176 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2174 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, |
2177 name, &miss); | 2175 name, &miss); |
2178 } else { | 2176 } else { |
2179 ASSERT(cell->value() == *function); | 2177 ASSERT(cell->value() == *function); |
2180 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2178 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2181 &miss); | 2179 &miss); |
2182 GenerateLoadFunctionFromCell(cell, function, &miss); | 2180 GenerateLoadFunctionFromCell(cell, function, &miss); |
2183 } | 2181 } |
2184 | 2182 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2234 // -- rsp[(argc + 1) * 4] : receiver | 2232 // -- rsp[(argc + 1) * 4] : receiver |
2235 // ----------------------------------- | 2233 // ----------------------------------- |
2236 | 2234 |
2237 if (!CpuFeatures::IsSupported(SSE2)) { | 2235 if (!CpuFeatures::IsSupported(SSE2)) { |
2238 return Handle<Code>::null(); | 2236 return Handle<Code>::null(); |
2239 } | 2237 } |
2240 | 2238 |
2241 CpuFeatureScope use_sse2(masm(), SSE2); | 2239 CpuFeatureScope use_sse2(masm(), SSE2); |
2242 | 2240 |
2243 const int argc = arguments().immediate(); | 2241 const int argc = arguments().immediate(); |
2242 StackArgumentsAccessor args(rsp, argc); | |
2244 | 2243 |
2245 // If the object is not a JSObject or we got an unexpected number of | 2244 // If the object is not a JSObject or we got an unexpected number of |
2246 // arguments, bail out to the regular call. | 2245 // arguments, bail out to the regular call. |
2247 if (!object->IsJSObject() || argc != 1) { | 2246 if (!object->IsJSObject() || argc != 1) { |
2248 return Handle<Code>::null(); | 2247 return Handle<Code>::null(); |
2249 } | 2248 } |
2250 | 2249 |
2251 Label miss; | 2250 Label miss; |
2252 GenerateNameCheck(name, &miss); | 2251 GenerateNameCheck(name, &miss); |
2253 | 2252 |
2254 if (cell.is_null()) { | 2253 if (cell.is_null()) { |
2255 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 2254 __ movq(rdx, args.GetReceiverOperand()); |
2256 | 2255 |
2257 STATIC_ASSERT(kSmiTag == 0); | 2256 STATIC_ASSERT(kSmiTag == 0); |
2258 __ JumpIfSmi(rdx, &miss); | 2257 __ JumpIfSmi(rdx, &miss); |
2259 | 2258 |
2260 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2259 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, |
2261 name, &miss); | 2260 name, &miss); |
2262 } else { | 2261 } else { |
2263 ASSERT(cell->value() == *function); | 2262 ASSERT(cell->value() == *function); |
2264 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2263 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2265 &miss); | 2264 &miss); |
2266 GenerateLoadFunctionFromCell(cell, function, &miss); | 2265 GenerateLoadFunctionFromCell(cell, function, &miss); |
2267 } | 2266 } |
2268 | 2267 |
2269 // Load the (only) argument into rax. | 2268 // Load the (only) argument into rax. |
2270 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 2269 __ movq(rax, args.GetArgumentOperand(argc)); |
2271 | 2270 |
2272 // Check if the argument is a smi. | 2271 // Check if the argument is a smi. |
2273 Label smi; | 2272 Label smi; |
2274 STATIC_ASSERT(kSmiTag == 0); | 2273 STATIC_ASSERT(kSmiTag == 0); |
2275 __ JumpIfSmi(rax, &smi); | 2274 __ JumpIfSmi(rax, &smi); |
2276 | 2275 |
2277 // Check if the argument is a heap number and load its value into xmm0. | 2276 // Check if the argument is a heap number and load its value into xmm0. |
2278 Label slow; | 2277 Label slow; |
2279 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); | 2278 __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); |
2280 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); | 2279 __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2327 __ andpd(xmm1, xmm2); | 2326 __ andpd(xmm1, xmm2); |
2328 __ subsd(xmm0, xmm1); | 2327 __ subsd(xmm0, xmm1); |
2329 | 2328 |
2330 // Return a new heap number. | 2329 // Return a new heap number. |
2331 __ AllocateHeapNumber(rax, rbx, &slow); | 2330 __ AllocateHeapNumber(rax, rbx, &slow); |
2332 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); | 2331 __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); |
2333 __ ret(2 * kPointerSize); | 2332 __ ret(2 * kPointerSize); |
2334 | 2333 |
2335 // Return the argument (when it's an already round heap number). | 2334 // Return the argument (when it's an already round heap number). |
2336 __ bind(&already_round); | 2335 __ bind(&already_round); |
2337 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 2336 __ movq(rax, args.GetArgumentOperand(argc)); |
danno
2013/09/18 12:08:42
1 instead of argc
haitao.feng
2013/09/22 08:16:00
Done.
| |
2338 __ ret(2 * kPointerSize); | 2337 __ ret(2 * kPointerSize); |
2339 | 2338 |
2340 // Tail call the full function. We do not have to patch the receiver | 2339 // Tail call the full function. We do not have to patch the receiver |
2341 // because the function makes no use of it. | 2340 // because the function makes no use of it. |
2342 __ bind(&slow); | 2341 __ bind(&slow); |
2343 ParameterCount expected(function); | 2342 ParameterCount expected(function); |
2344 __ InvokeFunction(function, expected, arguments(), | 2343 __ InvokeFunction(function, expected, arguments(), |
2345 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); | 2344 JUMP_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); |
2346 | 2345 |
2347 __ bind(&miss); | 2346 __ bind(&miss); |
(...skipping 23 matching lines...) Expand all Loading... | |
2371 // If the object is not a JSObject or we got an unexpected number of | 2370 // If the object is not a JSObject or we got an unexpected number of |
2372 // arguments, bail out to the regular call. | 2371 // arguments, bail out to the regular call. |
2373 const int argc = arguments().immediate(); | 2372 const int argc = arguments().immediate(); |
2374 StackArgumentsAccessor args(rsp, argc); | 2373 StackArgumentsAccessor args(rsp, argc); |
2375 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2374 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2376 | 2375 |
2377 Label miss; | 2376 Label miss; |
2378 GenerateNameCheck(name, &miss); | 2377 GenerateNameCheck(name, &miss); |
2379 | 2378 |
2380 if (cell.is_null()) { | 2379 if (cell.is_null()) { |
2381 __ movq(rdx, args.GetArgumentOperand(argc - 1)); | 2380 __ movq(rdx, args.GetReceiverOperand()); |
2382 __ JumpIfSmi(rdx, &miss); | 2381 __ JumpIfSmi(rdx, &miss); |
2383 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, | 2382 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, |
2384 name, &miss); | 2383 name, &miss); |
2385 } else { | 2384 } else { |
2386 ASSERT(cell->value() == *function); | 2385 ASSERT(cell->value() == *function); |
2387 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 2386 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
2388 &miss); | 2387 &miss); |
2389 GenerateLoadFunctionFromCell(cell, function, &miss); | 2388 GenerateLoadFunctionFromCell(cell, function, &miss); |
2390 } | 2389 } |
2391 // Load the (only) argument into rax. | 2390 // Load the (only) argument into rax. |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3199 // ----------------------------------- | 3198 // ----------------------------------- |
3200 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3199 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); |
3201 } | 3200 } |
3202 | 3201 |
3203 | 3202 |
3204 #undef __ | 3203 #undef __ |
3205 | 3204 |
3206 } } // namespace v8::internal | 3205 } } // namespace v8::internal |
3207 | 3206 |
3208 #endif // V8_TARGET_ARCH_X64 | 3207 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |