 Chromium Code Reviews
 Chromium Code Reviews Issue 22267005:
  Use StackArgumenstAccessor and kPCOnStackSize/kFPOnStackSize to compute stack address/operand  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 22267005:
  Use StackArgumenstAccessor and kPCOnStackSize/kFPOnStackSize to compute stack address/operand  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 |