| 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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 381     Register name, | 381     Register name, | 
| 382     Handle<JSObject> holder_obj, | 382     Handle<JSObject> holder_obj, | 
| 383     IC::UtilityId id) { | 383     IC::UtilityId id) { | 
| 384   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 384   PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 
| 385   __ CallExternalReference( | 385   __ CallExternalReference( | 
| 386       ExternalReference(IC_Utility(id), masm->isolate()), | 386       ExternalReference(IC_Utility(id), masm->isolate()), | 
| 387       StubCache::kInterceptorArgsLength); | 387       StubCache::kInterceptorArgsLength); | 
| 388 } | 388 } | 
| 389 | 389 | 
| 390 | 390 | 
| 391 // Number of pointers to be reserved on stack for fast API call. |  | 
| 392 static const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; |  | 
| 393 |  | 
| 394 |  | 
| 395 static void GenerateFastApiCallBody(MacroAssembler* masm, | 391 static void GenerateFastApiCallBody(MacroAssembler* masm, | 
| 396                                     const CallOptimization& optimization, | 392                                     const CallOptimization& optimization, | 
| 397                                     int argc, | 393                                     int argc, | 
| 398                                     Register holder, | 394                                     Register holder_in, | 
| 399                                     Register scratch1, | 395                                     bool restore_context) { | 
| 400                                     Register scratch2, | 396   ASSERT(optimization.is_simple_api_call()); | 
| 401                                     Register scratch3, | 397 | 
| 402                                     bool restore_context); | 398   // Abi for CallApiFunctionStub. | 
|  | 399   Register callee = rax; | 
|  | 400   Register call_data = rbx; | 
|  | 401   Register holder = rcx; | 
|  | 402   Register api_function_address = rdx; | 
|  | 403 | 
|  | 404   // Put holder in place. | 
|  | 405   __ Move(holder, holder_in); | 
|  | 406 | 
|  | 407   Register scratch = rdi; | 
|  | 408 | 
|  | 409   Isolate* isolate = masm->isolate(); | 
|  | 410   Handle<JSFunction> function = optimization.constant_function(); | 
|  | 411   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 
|  | 412   Handle<Object> call_data_obj(api_call_info->data(), isolate); | 
|  | 413 | 
|  | 414   // Put callee in place. | 
|  | 415   __ Move(callee, function); | 
|  | 416 | 
|  | 417   bool call_data_undefined = false; | 
|  | 418   // Put call_data in place. | 
|  | 419   if (isolate->heap()->InNewSpace(*call_data_obj)) { | 
|  | 420     __ Move(scratch, api_call_info); | 
|  | 421     __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); | 
|  | 422   } else if (call_data_obj->IsUndefined()) { | 
|  | 423     call_data_undefined = true; | 
|  | 424     __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); | 
|  | 425   } else { | 
|  | 426     __ Move(call_data, call_data_obj); | 
|  | 427   } | 
|  | 428 | 
|  | 429   // Put api_function_address in place. | 
|  | 430   Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 
|  | 431   __ Move( | 
|  | 432       api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); | 
|  | 433 | 
|  | 434   // Jump to stub. | 
|  | 435   CallApiFunctionStub stub(restore_context, call_data_undefined, argc); | 
|  | 436   __ TailCallStub(&stub); | 
|  | 437 } | 
| 403 | 438 | 
| 404 | 439 | 
| 405 // Generates call to API function. | 440 // Generates call to API function. | 
| 406 static void GenerateFastApiCall(MacroAssembler* masm, | 441 static void GenerateFastApiCall(MacroAssembler* masm, | 
| 407                                 const CallOptimization& optimization, | 442                                 const CallOptimization& optimization, | 
| 408                                 int argc, | 443                                 int argc, | 
| 409                                 Handle<Map> map_to_holder, | 444                                 Handle<Map> map_to_holder, | 
| 410                                 CallOptimization::HolderLookup holder_lookup) { | 445                                 CallOptimization::HolderLookup holder_lookup) { | 
| 411   Counters* counters = masm->isolate()->counters(); | 446   Counters* counters = masm->isolate()->counters(); | 
| 412   __ IncrementCounter(counters->call_const_fast_api(), 1); | 447   __ IncrementCounter(counters->call_const_fast_api(), 1); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 432         } | 467         } | 
| 433       } | 468       } | 
| 434      break; | 469      break; | 
| 435     case CallOptimization::kHolderNotFound: | 470     case CallOptimization::kHolderNotFound: | 
| 436       UNREACHABLE(); | 471       UNREACHABLE(); | 
| 437   } | 472   } | 
| 438   GenerateFastApiCallBody(masm, | 473   GenerateFastApiCallBody(masm, | 
| 439                           optimization, | 474                           optimization, | 
| 440                           argc, | 475                           argc, | 
| 441                           holder_reg, | 476                           holder_reg, | 
| 442                           rbx, |  | 
| 443                           rcx, |  | 
| 444                           rdx, |  | 
| 445                           false); | 477                           false); | 
| 446 } | 478 } | 
| 447 | 479 | 
| 448 | 480 | 
| 449 // Generate call to api function. | 481 // Generate call to api function. | 
| 450 // This function uses push() to generate smaller, faster code than |  | 
| 451 // the version above. It is an optimization that should will be removed |  | 
| 452 // when api call ICs are generated in hydrogen. |  | 
| 453 static void GenerateFastApiCall(MacroAssembler* masm, | 482 static void GenerateFastApiCall(MacroAssembler* masm, | 
| 454                                 const CallOptimization& optimization, | 483                                 const CallOptimization& optimization, | 
| 455                                 Register receiver, | 484                                 Register receiver, | 
| 456                                 Register scratch1, | 485                                 Register scratch1, | 
| 457                                 Register scratch2, |  | 
| 458                                 Register scratch3, |  | 
| 459                                 int argc, | 486                                 int argc, | 
| 460                                 Register* values) { | 487                                 Register* values) { | 
| 461   __ PopReturnAddressTo(scratch1); | 488   __ PopReturnAddressTo(scratch1); | 
| 462   // receiver | 489   // receiver | 
| 463   __ push(receiver); | 490   __ push(receiver); | 
| 464   // Write the arguments to stack frame. | 491   // Write the arguments to stack frame. | 
| 465   for (int i = 0; i < argc; i++) { | 492   for (int i = 0; i < argc; i++) { | 
| 466     Register arg = values[argc-1-i]; | 493     Register arg = values[argc-1-i]; | 
| 467     ASSERT(!receiver.is(arg)); | 494     ASSERT(!receiver.is(arg)); | 
| 468     ASSERT(!scratch1.is(arg)); | 495     ASSERT(!scratch1.is(arg)); | 
| 469     ASSERT(!scratch2.is(arg)); |  | 
| 470     ASSERT(!scratch3.is(arg)); |  | 
| 471     __ push(arg); | 496     __ push(arg); | 
| 472   } | 497   } | 
| 473   __ PushReturnAddressFrom(scratch1); | 498   __ PushReturnAddressFrom(scratch1); | 
| 474   // Stack now matches JSFunction abi. | 499   // Stack now matches JSFunction abi. | 
| 475   GenerateFastApiCallBody(masm, | 500   GenerateFastApiCallBody(masm, | 
| 476                           optimization, | 501                           optimization, | 
| 477                           argc, | 502                           argc, | 
| 478                           receiver, | 503                           receiver, | 
| 479                           scratch1, |  | 
| 480                           scratch2, |  | 
| 481                           scratch3, |  | 
| 482                           true); | 504                           true); | 
| 483 } | 505 } | 
| 484 | 506 | 
| 485 | 507 | 
| 486 static void GenerateFastApiCallBody(MacroAssembler* masm, |  | 
| 487                                     const CallOptimization& optimization, |  | 
| 488                                     int argc, |  | 
| 489                                     Register holder, |  | 
| 490                                     Register scratch1, |  | 
| 491                                     Register scratch2, |  | 
| 492                                     Register scratch3, |  | 
| 493                                     bool restore_context) { |  | 
| 494   // ----------- S t a t e ------------- |  | 
| 495   //  -- rsp[0]              : return address |  | 
| 496   //  -- rsp[8]              : last argument |  | 
| 497   //  -- ... |  | 
| 498   //  -- rsp[argc * 8]       : first argument |  | 
| 499   //  -- rsp[(argc + 1) * 8] : receiver |  | 
| 500   // ----------------------------------- |  | 
| 501   ASSERT(optimization.is_simple_api_call()); |  | 
| 502 |  | 
| 503   typedef FunctionCallbackArguments FCA; |  | 
| 504 |  | 
| 505   STATIC_ASSERT(FCA::kHolderIndex == 0); |  | 
| 506   STATIC_ASSERT(FCA::kIsolateIndex == 1); |  | 
| 507   STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |  | 
| 508   STATIC_ASSERT(FCA::kReturnValueOffset == 3); |  | 
| 509   STATIC_ASSERT(FCA::kDataIndex == 4); |  | 
| 510   STATIC_ASSERT(FCA::kCalleeIndex == 5); |  | 
| 511   STATIC_ASSERT(FCA::kContextSaveIndex == 6); |  | 
| 512   STATIC_ASSERT(FCA::kArgsLength == 7); |  | 
| 513 |  | 
| 514   __ PopReturnAddressTo(scratch1); |  | 
| 515 |  | 
| 516   ASSERT(!holder.is(rsi)); |  | 
| 517   // context save |  | 
| 518   __ push(rsi); |  | 
| 519 |  | 
| 520   // Get the function and setup the context. |  | 
| 521   Handle<JSFunction> function = optimization.constant_function(); |  | 
| 522   __ Move(scratch2, function); |  | 
| 523   __ push(scratch2); |  | 
| 524   __ movp(rsi, FieldOperand(scratch2, JSFunction::kContextOffset)); |  | 
| 525 |  | 
| 526   Isolate* isolate = masm->isolate(); |  | 
| 527   Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |  | 
| 528   Handle<Object> call_data(api_call_info->data(), isolate); |  | 
| 529   // Push data from ExecutableAccessorInfo. |  | 
| 530   bool call_data_undefined = false; |  | 
| 531   if (isolate->heap()->InNewSpace(*call_data)) { |  | 
| 532     __ Move(scratch2, api_call_info); |  | 
| 533     __ movp(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset)); |  | 
| 534   } else if (call_data->IsUndefined()) { |  | 
| 535     call_data_undefined = true; |  | 
| 536     __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); |  | 
| 537   } else { |  | 
| 538     __ Move(scratch3, call_data); |  | 
| 539   } |  | 
| 540   // call data |  | 
| 541   __ push(scratch3); |  | 
| 542   if (!call_data_undefined) { |  | 
| 543     __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); |  | 
| 544   } |  | 
| 545   // return value |  | 
| 546   __ push(scratch3); |  | 
| 547   // return value default |  | 
| 548   __ push(scratch3); |  | 
| 549   // isolate |  | 
| 550   __ Move(scratch3, |  | 
| 551           ExternalReference::isolate_address(masm->isolate())); |  | 
| 552   __ push(scratch3); |  | 
| 553   // holder |  | 
| 554   __ push(holder); |  | 
| 555 |  | 
| 556   ASSERT(!scratch1.is(rax)); |  | 
| 557   __ movp(rax, rsp); |  | 
| 558   // Push return address back on stack. |  | 
| 559   __ PushReturnAddressFrom(scratch1); |  | 
| 560 |  | 
| 561   // Function address is a foreign pointer outside V8's heap. |  | 
| 562   Address function_address = v8::ToCData<Address>(api_call_info->callback()); |  | 
| 563 |  | 
| 564   // Allocate the v8::Arguments structure in the arguments' space since |  | 
| 565   // it's not controlled by GC. |  | 
| 566   const int kApiStackSpace = 4; |  | 
| 567 |  | 
| 568   __ PrepareCallApiFunction(kApiStackSpace); |  | 
| 569 |  | 
| 570   __ movp(StackSpaceOperand(0), rax);  // FunctionCallbackInfo::implicit_args_. |  | 
| 571   __ addq(rax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize)); |  | 
| 572   __ movp(StackSpaceOperand(1), rax);  // FunctionCallbackInfo::values_. |  | 
| 573   __ Set(StackSpaceOperand(2), argc);  // FunctionCallbackInfo::length_. |  | 
| 574   // FunctionCallbackInfo::is_construct_call_. |  | 
| 575   __ Set(StackSpaceOperand(3), 0); |  | 
| 576 |  | 
| 577 #if defined(__MINGW64__) || defined(_WIN64) |  | 
| 578   Register arguments_arg = rcx; |  | 
| 579   Register callback_arg = rdx; |  | 
| 580 #else |  | 
| 581   Register arguments_arg = rdi; |  | 
| 582   Register callback_arg = rsi; |  | 
| 583 #endif |  | 
| 584 |  | 
| 585   // v8::InvocationCallback's argument. |  | 
| 586   __ lea(arguments_arg, StackSpaceOperand(0)); |  | 
| 587 |  | 
| 588   Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |  | 
| 589 |  | 
| 590   StackArgumentsAccessor args_from_rbp(rbp, kFastApiCallArguments, |  | 
| 591                                        ARGUMENTS_DONT_CONTAIN_RECEIVER); |  | 
| 592   Operand context_restore_operand = args_from_rbp.GetArgumentOperand( |  | 
| 593       kFastApiCallArguments - 1 - FCA::kContextSaveIndex); |  | 
| 594   Operand return_value_operand = args_from_rbp.GetArgumentOperand( |  | 
| 595       kFastApiCallArguments - 1 - FCA::kReturnValueOffset); |  | 
| 596   __ CallApiFunctionAndReturn( |  | 
| 597       function_address, |  | 
| 598       thunk_address, |  | 
| 599       callback_arg, |  | 
| 600       argc + kFastApiCallArguments + 1, |  | 
| 601       return_value_operand, |  | 
| 602       restore_context ? &context_restore_operand : NULL); |  | 
| 603 } |  | 
| 604 |  | 
| 605 |  | 
| 606 class CallInterceptorCompiler BASE_EMBEDDED { | 508 class CallInterceptorCompiler BASE_EMBEDDED { | 
| 607  public: | 509  public: | 
| 608   CallInterceptorCompiler(CallStubCompiler* stub_compiler, | 510   CallInterceptorCompiler(CallStubCompiler* stub_compiler, | 
| 609                           const ParameterCount& arguments, | 511                           const ParameterCount& arguments, | 
| 610                           Register name) | 512                           Register name) | 
| 611       : stub_compiler_(stub_compiler), | 513       : stub_compiler_(stub_compiler), | 
| 612         arguments_(arguments), | 514         arguments_(arguments), | 
| 613         name_(name) {} | 515         name_(name) {} | 
| 614 | 516 | 
| 615   void Compile(MacroAssembler* masm, | 517   void Compile(MacroAssembler* masm, | 
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1272                             representation); | 1174                             representation); | 
| 1273     GenerateTailCall(masm(), stub.GetCode(isolate())); | 1175     GenerateTailCall(masm(), stub.GetCode(isolate())); | 
| 1274   } | 1176   } | 
| 1275 } | 1177 } | 
| 1276 | 1178 | 
| 1277 | 1179 | 
| 1278 void LoadStubCompiler::GenerateLoadCallback( | 1180 void LoadStubCompiler::GenerateLoadCallback( | 
| 1279     const CallOptimization& call_optimization) { | 1181     const CallOptimization& call_optimization) { | 
| 1280   GenerateFastApiCall( | 1182   GenerateFastApiCall( | 
| 1281       masm(), call_optimization, receiver(), | 1183       masm(), call_optimization, receiver(), | 
| 1282       scratch1(), scratch2(), name(), 0, NULL); | 1184       scratch1(), 0, NULL); | 
| 1283 } | 1185 } | 
| 1284 | 1186 | 
| 1285 | 1187 | 
| 1286 void LoadStubCompiler::GenerateLoadCallback( | 1188 void LoadStubCompiler::GenerateLoadCallback( | 
| 1287     Register reg, | 1189     Register reg, | 
| 1288     Handle<ExecutableAccessorInfo> callback) { | 1190     Handle<ExecutableAccessorInfo> callback) { | 
| 1289   // Insert additional parameters into the stack frame above return address. | 1191   // Insert additional parameters into the stack frame above return address. | 
| 1290   ASSERT(!scratch4().is(reg)); | 1192   ASSERT(!scratch4().is(reg)); | 
| 1291   __ PopReturnAddressTo(scratch4()); | 1193   __ PopReturnAddressTo(scratch4()); | 
| 1292 | 1194 | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1343 | 1245 | 
| 1344   // v8::PropertyAccessorInfo::args_. | 1246   // v8::PropertyAccessorInfo::args_. | 
| 1345   __ movp(StackSpaceOperand(0), rax); | 1247   __ movp(StackSpaceOperand(0), rax); | 
| 1346 | 1248 | 
| 1347   // The context register (rsi) has been saved in PrepareCallApiFunction and | 1249   // The context register (rsi) has been saved in PrepareCallApiFunction and | 
| 1348   // could be used to pass arguments. | 1250   // could be used to pass arguments. | 
| 1349   __ lea(accessor_info_arg, StackSpaceOperand(0)); | 1251   __ lea(accessor_info_arg, StackSpaceOperand(0)); | 
| 1350 | 1252 | 
| 1351   Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); | 1253   Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); | 
| 1352 | 1254 | 
|  | 1255   Register api_function_address = rdx; | 
|  | 1256   __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); | 
|  | 1257 | 
| 1353   // The name handler is counted as an argument. | 1258   // The name handler is counted as an argument. | 
| 1354   StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); | 1259   StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); | 
| 1355   Operand return_value_operand = args.GetArgumentOperand( | 1260   Operand return_value_operand = args.GetArgumentOperand( | 
| 1356       PropertyCallbackArguments::kArgsLength - 1 - | 1261       PropertyCallbackArguments::kArgsLength - 1 - | 
| 1357       PropertyCallbackArguments::kReturnValueOffset); | 1262       PropertyCallbackArguments::kReturnValueOffset); | 
| 1358   __ CallApiFunctionAndReturn(getter_address, | 1263   __ CallApiFunctionAndReturn(api_function_address, | 
| 1359                               thunk_address, | 1264                               thunk_address, | 
| 1360                               getter_arg, | 1265                               getter_arg, | 
| 1361                               kStackSpace, | 1266                               kStackSpace, | 
| 1362                               return_value_operand, | 1267                               return_value_operand, | 
| 1363                               NULL); | 1268                               NULL); | 
| 1364 } | 1269 } | 
| 1365 | 1270 | 
| 1366 | 1271 | 
| 1367 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { | 1272 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { | 
| 1368   // Return the constant value. | 1273   // Return the constant value. | 
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1785 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 1690 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 
| 1786     Handle<JSObject> object, | 1691     Handle<JSObject> object, | 
| 1787     Handle<JSObject> holder, | 1692     Handle<JSObject> holder, | 
| 1788     Handle<Name> name, | 1693     Handle<Name> name, | 
| 1789     const CallOptimization& call_optimization) { | 1694     const CallOptimization& call_optimization) { | 
| 1790   HandlerFrontend(IC::CurrentTypeOf(object, isolate()), | 1695   HandlerFrontend(IC::CurrentTypeOf(object, isolate()), | 
| 1791                   receiver(), holder, name); | 1696                   receiver(), holder, name); | 
| 1792 | 1697 | 
| 1793   Register values[] = { value() }; | 1698   Register values[] = { value() }; | 
| 1794   GenerateFastApiCall( | 1699   GenerateFastApiCall( | 
| 1795       masm(), call_optimization, receiver(), scratch1(), | 1700       masm(), call_optimization, receiver(), | 
| 1796       scratch2(), this->name(), 1, values); | 1701       scratch1(), 1, values); | 
| 1797 | 1702 | 
| 1798   // Return the generated code. | 1703   // Return the generated code. | 
| 1799   return GetCode(kind(), Code::FAST, name); | 1704   return GetCode(kind(), Code::FAST, name); | 
| 1800 } | 1705 } | 
| 1801 | 1706 | 
| 1802 | 1707 | 
| 1803 #undef __ | 1708 #undef __ | 
| 1804 #define __ ACCESS_MASM(masm) | 1709 #define __ ACCESS_MASM(masm) | 
| 1805 | 1710 | 
| 1806 | 1711 | 
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2112   // ----------------------------------- | 2017   // ----------------------------------- | 
| 2113   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2018   TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 
| 2114 } | 2019 } | 
| 2115 | 2020 | 
| 2116 | 2021 | 
| 2117 #undef __ | 2022 #undef __ | 
| 2118 | 2023 | 
| 2119 } }  // namespace v8::internal | 2024 } }  // namespace v8::internal | 
| 2120 | 2025 | 
| 2121 #endif  // V8_TARGET_ARCH_X64 | 2026 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|