| 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 } | 440 } |
| 441 | 441 |
| 442 | 442 |
| 443 // Generates call to API function. | 443 // Generates call to API function. |
| 444 static void GenerateFastApiCall(MacroAssembler* masm, | 444 static void GenerateFastApiCall(MacroAssembler* masm, |
| 445 const CallOptimization& optimization, | 445 const CallOptimization& optimization, |
| 446 int argc, | 446 int argc, |
| 447 bool restore_context) { | 447 bool restore_context) { |
| 448 // ----------- S t a t e ------------- | 448 // ----------- S t a t e ------------- |
| 449 // -- rsp[0] : return address | 449 // -- rsp[0] : return address |
| 450 // -- rsp[8] : context save | 450 // -- rsp[8] - rsp[58] : FunctionCallbackInfo, incl. |
| 451 // -- rsp[16] : object passing the type check | 451 // : object passing the type check |
| 452 // (last fast api call extra argument, | 452 // (set by CheckPrototypes) |
| 453 // set by CheckPrototypes) | |
| 454 // -- rsp[24] : api function | |
| 455 // (first fast api call extra argument) | |
| 456 // -- rsp[32] : api call data | |
| 457 // -- rsp[40] : isolate | |
| 458 // -- rsp[48] : ReturnValue default value | |
| 459 // -- rsp[56] : ReturnValue | |
| 460 // | |
| 461 // -- rsp[64] : last argument | 453 // -- rsp[64] : last argument |
| 462 // -- ... | 454 // -- ... |
| 463 // -- rsp[(argc + 7) * 8] : first argument | 455 // -- rsp[(argc + 7) * 8] : first argument |
| 464 // -- rsp[(argc + 8) * 8] : receiver | 456 // -- rsp[(argc + 8) * 8] : receiver |
| 465 // ----------------------------------- | 457 // ----------------------------------- |
| 466 int api_call_argc = argc + kFastApiCallArguments; | 458 typedef FunctionCallbackArguments FCA; |
| 467 StackArgumentsAccessor args(rsp, api_call_argc); | 459 StackArgumentsAccessor args(rsp, argc + kFastApiCallArguments); |
| 468 | 460 |
| 469 // Save calling context. | 461 // Save calling context. |
| 470 __ movq(args.GetArgumentOperand(api_call_argc), rsi); | 462 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kContextSaveIndex), rsi); |
| 471 | 463 |
| 472 // Get the function and setup the context. | 464 // Get the function and setup the context. |
| 473 Handle<JSFunction> function = optimization.constant_function(); | 465 Handle<JSFunction> function = optimization.constant_function(); |
| 474 __ LoadHeapObject(rdi, function); | 466 __ LoadHeapObject(rdi, function); |
| 475 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 467 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 476 // Pass the additional arguments. | 468 // Construct the FunctionCallbackInfo on the stack. |
| 477 __ movq(args.GetArgumentOperand(api_call_argc - 2), rdi); | 469 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kCalleeIndex), rdi); |
| 478 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 470 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 479 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 471 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
| 480 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 472 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 481 __ Move(rcx, api_call_info); | 473 __ Move(rcx, api_call_info); |
| 482 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); | 474 __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); |
| 483 __ movq(args.GetArgumentOperand(api_call_argc - 3), rbx); | 475 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), rbx); |
| 484 } else { | 476 } else { |
| 485 __ Move(args.GetArgumentOperand(api_call_argc - 3), call_data); | 477 __ Move(args.GetArgumentOperand(argc + 1 - FCA::kDataIndex), call_data); |
| 486 } | 478 } |
| 487 __ movq(kScratchRegister, | 479 __ movq(kScratchRegister, |
| 488 ExternalReference::isolate_address(masm->isolate())); | 480 ExternalReference::isolate_address(masm->isolate())); |
| 489 __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister); | 481 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kIsolateIndex), |
| 482 kScratchRegister); |
| 490 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); | 483 __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); |
| 491 __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister); | 484 __ movq( |
| 492 __ movq(args.GetArgumentOperand(api_call_argc - 6), kScratchRegister); | 485 args.GetArgumentOperand(argc + 1 - FCA::kReturnValueDefaultValueIndex), |
| 486 kScratchRegister); |
| 487 __ movq(args.GetArgumentOperand(argc + 1 - FCA::kReturnValueOffset), |
| 488 kScratchRegister); |
| 493 | 489 |
| 494 // Prepare arguments. | 490 // Prepare arguments. |
| 495 STATIC_ASSERT(kFastApiCallArguments == 7); | 491 STATIC_ASSERT(kFastApiCallArguments == 7); |
| 496 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); | 492 __ lea(rbx, Operand(rsp, kFastApiCallArguments * kPointerSize)); |
| 497 | 493 |
| 498 // Function address is a foreign pointer outside V8's heap. | 494 // Function address is a foreign pointer outside V8's heap. |
| 499 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 495 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
| 500 | 496 |
| 501 // Allocate the v8::Arguments structure in the arguments' space since | 497 // Allocate the v8::Arguments structure in the arguments' space since |
| 502 // it's not controlled by GC. | 498 // it's not controlled by GC. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 517 #else | 513 #else |
| 518 Register arguments_arg = rdi; | 514 Register arguments_arg = rdi; |
| 519 Register callback_arg = rsi; | 515 Register callback_arg = rsi; |
| 520 #endif | 516 #endif |
| 521 | 517 |
| 522 // v8::InvocationCallback's argument. | 518 // v8::InvocationCallback's argument. |
| 523 __ lea(arguments_arg, StackSpaceOperand(0)); | 519 __ lea(arguments_arg, StackSpaceOperand(0)); |
| 524 | 520 |
| 525 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); | 521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); |
| 526 | 522 |
| 527 Operand context_restore_operand(rbp, 2 * kPointerSize); | 523 Operand context_restore_operand( |
| 524 rbp, (kFastApiCallArguments + 1 + FCA::kContextSaveIndex) * kPointerSize); |
| 528 Operand return_value_operand( | 525 Operand return_value_operand( |
| 529 rbp, (kFastApiCallArguments + 1) * kPointerSize); | 526 rbp, |
| 530 __ CallApiFunctionAndReturn(function_address, | 527 (kFastApiCallArguments + 1 + FCA::kReturnValueOffset) * kPointerSize); |
| 531 thunk_address, | 528 __ CallApiFunctionAndReturn( |
| 532 callback_arg, | 529 function_address, |
| 533 api_call_argc + 1, | 530 thunk_address, |
| 534 return_value_operand, | 531 callback_arg, |
| 535 restore_context ? | 532 argc + kFastApiCallArguments + 1, |
| 536 &context_restore_operand : NULL); | 533 return_value_operand, |
| 534 restore_context ? &context_restore_operand : NULL); |
| 537 } | 535 } |
| 538 | 536 |
| 539 | 537 |
| 540 // Generate call to api function. | 538 // Generate call to api function. |
| 541 static void GenerateFastApiCall(MacroAssembler* masm, | 539 static void GenerateFastApiCall(MacroAssembler* masm, |
| 542 const CallOptimization& optimization, | 540 const CallOptimization& optimization, |
| 543 Register receiver, | 541 Register receiver, |
| 544 Register scratch, | 542 Register scratch, |
| 545 int argc, | 543 int argc, |
| 546 Register* values) { | 544 Register* values) { |
| (...skipping 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3172 // ----------------------------------- | 3170 // ----------------------------------- |
| 3173 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3171 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); |
| 3174 } | 3172 } |
| 3175 | 3173 |
| 3176 | 3174 |
| 3177 #undef __ | 3175 #undef __ |
| 3178 | 3176 |
| 3179 } } // namespace v8::internal | 3177 } } // namespace v8::internal |
| 3180 | 3178 |
| 3181 #endif // V8_TARGET_ARCH_X64 | 3179 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |