OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 5411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5422 __ movp(Operand(base_reg, kLimitOffset), prev_limit_reg); | 5422 __ movp(Operand(base_reg, kLimitOffset), prev_limit_reg); |
5423 __ movp(prev_limit_reg, rax); | 5423 __ movp(prev_limit_reg, rax); |
5424 __ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate)); | 5424 __ LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate)); |
5425 __ LoadAddress(rax, | 5425 __ LoadAddress(rax, |
5426 ExternalReference::delete_handle_scope_extensions(isolate)); | 5426 ExternalReference::delete_handle_scope_extensions(isolate)); |
5427 __ call(rax); | 5427 __ call(rax); |
5428 __ movp(rax, prev_limit_reg); | 5428 __ movp(rax, prev_limit_reg); |
5429 __ jmp(&leave_exit_frame); | 5429 __ jmp(&leave_exit_frame); |
5430 } | 5430 } |
5431 | 5431 |
5432 static void CallApiFunctionStubHelper(MacroAssembler* masm, | 5432 void CallApiCallbackStub::Generate(MacroAssembler* masm) { |
5433 const ParameterCount& argc, | |
5434 bool return_first_arg, | |
5435 bool call_data_undefined, bool is_lazy) { | |
5436 // ----------- S t a t e ------------- | 5433 // ----------- S t a t e ------------- |
5437 // -- rdi : callee | 5434 // -- rdi : callee |
5438 // -- rbx : call_data | 5435 // -- rbx : call_data |
5439 // -- rcx : holder | 5436 // -- rcx : holder |
5440 // -- rdx : api_function_address | 5437 // -- rdx : api_function_address |
5441 // -- rsi : context | 5438 // -- rsi : context |
5442 // -- rax : number of arguments if argc is a register | 5439 // -- rax : number of arguments if argc is a register |
5443 // -- rsp[0] : return address | 5440 // -- rsp[0] : return address |
5444 // -- rsp[8] : last argument | 5441 // -- rsp[8] : last argument |
5445 // -- ... | 5442 // -- ... |
(...skipping 12 matching lines...) Expand all Loading... |
5458 | 5455 |
5459 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 5456 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
5460 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 5457 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
5461 STATIC_ASSERT(FCA::kDataIndex == 4); | 5458 STATIC_ASSERT(FCA::kDataIndex == 4); |
5462 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 5459 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
5463 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 5460 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
5464 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 5461 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
5465 STATIC_ASSERT(FCA::kHolderIndex == 0); | 5462 STATIC_ASSERT(FCA::kHolderIndex == 0); |
5466 STATIC_ASSERT(FCA::kArgsLength == 7); | 5463 STATIC_ASSERT(FCA::kArgsLength == 7); |
5467 | 5464 |
5468 DCHECK(argc.is_immediate() || rax.is(argc.reg())); | |
5469 | |
5470 __ PopReturnAddressTo(return_address); | 5465 __ PopReturnAddressTo(return_address); |
5471 | 5466 |
5472 // context save | 5467 // context save |
5473 __ Push(context); | 5468 __ Push(context); |
5474 | 5469 |
5475 // callee | 5470 // callee |
5476 __ Push(callee); | 5471 __ Push(callee); |
5477 | 5472 |
5478 // call data | 5473 // call data |
5479 __ Push(call_data); | 5474 __ Push(call_data); |
5480 Register scratch = call_data; | 5475 Register scratch = call_data; |
5481 if (!call_data_undefined) { | 5476 if (!this->call_data_undefined()) { |
5482 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 5477 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
5483 } | 5478 } |
5484 // return value | 5479 // return value |
5485 __ Push(scratch); | 5480 __ Push(scratch); |
5486 // return value default | 5481 // return value default |
5487 __ Push(scratch); | 5482 __ Push(scratch); |
5488 // isolate | 5483 // isolate |
5489 __ Move(scratch, ExternalReference::isolate_address(masm->isolate())); | 5484 __ Move(scratch, ExternalReference::isolate_address(masm->isolate())); |
5490 __ Push(scratch); | 5485 __ Push(scratch); |
5491 // holder | 5486 // holder |
5492 __ Push(holder); | 5487 __ Push(holder); |
5493 | 5488 |
5494 __ movp(scratch, rsp); | 5489 __ movp(scratch, rsp); |
5495 // Push return address back on stack. | 5490 // Push return address back on stack. |
5496 __ PushReturnAddressFrom(return_address); | 5491 __ PushReturnAddressFrom(return_address); |
5497 | 5492 |
5498 if (!is_lazy) { | 5493 if (!this->is_lazy()) { |
5499 // load context from callee | 5494 // load context from callee |
5500 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset)); | 5495 __ movp(context, FieldOperand(callee, JSFunction::kContextOffset)); |
5501 } | 5496 } |
5502 | 5497 |
5503 // Allocate the v8::Arguments structure in the arguments' space since | 5498 // Allocate the v8::Arguments structure in the arguments' space since |
5504 // it's not controlled by GC. | 5499 // it's not controlled by GC. |
5505 const int kApiStackSpace = 4; | 5500 const int kApiStackSpace = 4; |
5506 | 5501 |
5507 PrepareCallApiFunction(masm, kApiStackSpace); | 5502 PrepareCallApiFunction(masm, kApiStackSpace); |
5508 | 5503 |
5509 // FunctionCallbackInfo::implicit_args_. | 5504 // FunctionCallbackInfo::implicit_args_. |
| 5505 int argc = this->argc(); |
5510 __ movp(StackSpaceOperand(0), scratch); | 5506 __ movp(StackSpaceOperand(0), scratch); |
5511 if (argc.is_immediate()) { | 5507 __ addp(scratch, Immediate((argc + FCA::kArgsLength - 1) * kPointerSize)); |
5512 __ addp(scratch, Immediate((argc.immediate() + FCA::kArgsLength - 1) * | 5508 // FunctionCallbackInfo::values_. |
5513 kPointerSize)); | 5509 __ movp(StackSpaceOperand(1), scratch); |
5514 // FunctionCallbackInfo::values_. | 5510 // FunctionCallbackInfo::length_. |
5515 __ movp(StackSpaceOperand(1), scratch); | 5511 __ Set(StackSpaceOperand(2), argc); |
5516 // FunctionCallbackInfo::length_. | 5512 // FunctionCallbackInfo::is_construct_call_. |
5517 __ Set(StackSpaceOperand(2), argc.immediate()); | 5513 __ Set(StackSpaceOperand(3), 0); |
5518 // FunctionCallbackInfo::is_construct_call_. | |
5519 __ Set(StackSpaceOperand(3), 0); | |
5520 } else { | |
5521 __ leap(scratch, Operand(scratch, argc.reg(), times_pointer_size, | |
5522 (FCA::kArgsLength - 1) * kPointerSize)); | |
5523 // FunctionCallbackInfo::values_. | |
5524 __ movp(StackSpaceOperand(1), scratch); | |
5525 // FunctionCallbackInfo::length_. | |
5526 __ movp(StackSpaceOperand(2), argc.reg()); | |
5527 // FunctionCallbackInfo::is_construct_call_. | |
5528 __ leap(argc.reg(), Operand(argc.reg(), times_pointer_size, | |
5529 (FCA::kArgsLength + 1) * kPointerSize)); | |
5530 __ movp(StackSpaceOperand(3), argc.reg()); | |
5531 } | |
5532 | 5514 |
5533 #if defined(__MINGW64__) || defined(_WIN64) | 5515 #if defined(__MINGW64__) || defined(_WIN64) |
5534 Register arguments_arg = rcx; | 5516 Register arguments_arg = rcx; |
5535 Register callback_arg = rdx; | 5517 Register callback_arg = rdx; |
5536 #else | 5518 #else |
5537 Register arguments_arg = rdi; | 5519 Register arguments_arg = rdi; |
5538 Register callback_arg = rsi; | 5520 Register callback_arg = rsi; |
5539 #endif | 5521 #endif |
5540 | 5522 |
5541 // It's okay if api_function_address == callback_arg | 5523 // It's okay if api_function_address == callback_arg |
5542 // but not arguments_arg | 5524 // but not arguments_arg |
5543 DCHECK(!api_function_address.is(arguments_arg)); | 5525 DCHECK(!api_function_address.is(arguments_arg)); |
5544 | 5526 |
5545 // v8::InvocationCallback's argument. | 5527 // v8::InvocationCallback's argument. |
5546 __ leap(arguments_arg, StackSpaceOperand(0)); | 5528 __ leap(arguments_arg, StackSpaceOperand(0)); |
5547 | 5529 |
5548 ExternalReference thunk_ref = | 5530 ExternalReference thunk_ref = |
5549 ExternalReference::invoke_function_callback(masm->isolate()); | 5531 ExternalReference::invoke_function_callback(masm->isolate()); |
5550 | 5532 |
5551 // Accessor for FunctionCallbackInfo and first js arg. | 5533 // Accessor for FunctionCallbackInfo and first js arg. |
5552 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1, | 5534 StackArgumentsAccessor args_from_rbp(rbp, FCA::kArgsLength + 1, |
5553 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 5535 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
5554 Operand context_restore_operand = args_from_rbp.GetArgumentOperand( | 5536 Operand context_restore_operand = args_from_rbp.GetArgumentOperand( |
5555 FCA::kArgsLength - FCA::kContextSaveIndex); | 5537 FCA::kArgsLength - FCA::kContextSaveIndex); |
5556 Operand is_construct_call_operand = StackSpaceOperand(3); | 5538 Operand is_construct_call_operand = StackSpaceOperand(3); |
5557 Operand return_value_operand = args_from_rbp.GetArgumentOperand( | 5539 Operand return_value_operand = args_from_rbp.GetArgumentOperand( |
5558 return_first_arg ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset); | 5540 this->is_store() ? 0 : FCA::kArgsLength - FCA::kReturnValueOffset); |
5559 int stack_space = 0; | 5541 int stack_space = 0; |
5560 Operand* stack_space_operand = &is_construct_call_operand; | 5542 Operand* stack_space_operand = &is_construct_call_operand; |
5561 if (argc.is_immediate()) { | 5543 stack_space = argc + FCA::kArgsLength + 1; |
5562 stack_space = argc.immediate() + FCA::kArgsLength + 1; | 5544 stack_space_operand = nullptr; |
5563 stack_space_operand = nullptr; | |
5564 } | |
5565 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg, | 5545 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, callback_arg, |
5566 stack_space, stack_space_operand, | 5546 stack_space, stack_space_operand, |
5567 return_value_operand, &context_restore_operand); | 5547 return_value_operand, &context_restore_operand); |
5568 } | 5548 } |
5569 | 5549 |
5570 | 5550 |
5571 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | |
5572 bool call_data_undefined = this->call_data_undefined(); | |
5573 CallApiFunctionStubHelper(masm, ParameterCount(rax), false, | |
5574 call_data_undefined, false); | |
5575 } | |
5576 | |
5577 | |
5578 void CallApiAccessorStub::Generate(MacroAssembler* masm) { | |
5579 bool is_store = this->is_store(); | |
5580 int argc = this->argc(); | |
5581 bool call_data_undefined = this->call_data_undefined(); | |
5582 bool is_lazy = this->is_lazy(); | |
5583 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, | |
5584 call_data_undefined, is_lazy); | |
5585 } | |
5586 | |
5587 | |
5588 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5551 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
5589 // ----------- S t a t e ------------- | 5552 // ----------- S t a t e ------------- |
5590 // -- rsp[0] : return address | 5553 // -- rsp[0] : return address |
5591 // -- rsp[8] : name | 5554 // -- rsp[8] : name |
5592 // -- rsp[16 .. (16 + kArgsLength*8)] : v8::PropertyCallbackInfo::args_ | 5555 // -- rsp[16 .. (16 + kArgsLength*8)] : v8::PropertyCallbackInfo::args_ |
5593 // -- ... | 5556 // -- ... |
5594 // -- r8 : api_function_address | 5557 // -- r8 : api_function_address |
5595 // ----------------------------------- | 5558 // ----------------------------------- |
5596 | 5559 |
5597 #if defined(__MINGW64__) || defined(_WIN64) | 5560 #if defined(__MINGW64__) || defined(_WIN64) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5643 NULL); | 5606 NULL); |
5644 } | 5607 } |
5645 | 5608 |
5646 | 5609 |
5647 #undef __ | 5610 #undef __ |
5648 | 5611 |
5649 } // namespace internal | 5612 } // namespace internal |
5650 } // namespace v8 | 5613 } // namespace v8 |
5651 | 5614 |
5652 #endif // V8_TARGET_ARCH_X64 | 5615 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |