Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 860013002: move CallApiFunctionAndReturn to code-stubs-* (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm64/macro-assembler-arm64.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 4663 matching lines...) Expand 10 before | Expand all | Expand 10 after
4674 Label fast_elements_case; 4674 Label fast_elements_case;
4675 __ cmp(ecx, Immediate(FAST_ELEMENTS)); 4675 __ cmp(ecx, Immediate(FAST_ELEMENTS));
4676 __ j(equal, &fast_elements_case); 4676 __ j(equal, &fast_elements_case);
4677 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 4677 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
4678 4678
4679 __ bind(&fast_elements_case); 4679 __ bind(&fast_elements_case);
4680 GenerateCase(masm, FAST_ELEMENTS); 4680 GenerateCase(masm, FAST_ELEMENTS);
4681 } 4681 }
4682 4682
4683 4683
4684 // Generates an Operand for saving parameters after PrepareCallApiFunction.
4685 static Operand ApiParameterOperand(int index) {
4686 return Operand(esp, index * kPointerSize);
4687 }
4688
4689
4690 // Prepares stack to put arguments (aligns and so on). Reserves
4691 // space for return value if needed (assumes the return value is a handle).
4692 // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
4693 // etc. Saves context (esi). If space was reserved for return value then
4694 // stores the pointer to the reserved slot into esi.
4695 static void PrepareCallApiFunction(MacroAssembler* masm, int argc) {
4696 __ EnterApiExitFrame(argc);
4697 if (__ emit_debug_code()) {
4698 __ mov(esi, Immediate(bit_cast<int32_t>(kZapValue)));
4699 }
4700 }
4701
4702
4703 // Calls an API function. Allocates HandleScope, extracts returned value
4704 // from handle and propagates exceptions. Clobbers ebx, edi and
4705 // caller-save registers. Restores context. On return removes
4706 // stack_space * kPointerSize (GCed).
4707 static void CallApiFunctionAndReturn(MacroAssembler* masm,
4708 Register function_address,
4709 ExternalReference thunk_ref,
4710 Operand thunk_last_arg, int stack_space,
4711 Operand* stack_space_operand,
4712 Operand return_value_operand,
4713 Operand* context_restore_operand) {
4714 Isolate* isolate = masm->isolate();
4715
4716 ExternalReference next_address =
4717 ExternalReference::handle_scope_next_address(isolate);
4718 ExternalReference limit_address =
4719 ExternalReference::handle_scope_limit_address(isolate);
4720 ExternalReference level_address =
4721 ExternalReference::handle_scope_level_address(isolate);
4722
4723 DCHECK(edx.is(function_address));
4724 // Allocate HandleScope in callee-save registers.
4725 __ mov(ebx, Operand::StaticVariable(next_address));
4726 __ mov(edi, Operand::StaticVariable(limit_address));
4727 __ add(Operand::StaticVariable(level_address), Immediate(1));
4728
4729 if (FLAG_log_timer_events) {
4730 FrameScope frame(masm, StackFrame::MANUAL);
4731 __ PushSafepointRegisters();
4732 __ PrepareCallCFunction(1, eax);
4733 __ mov(Operand(esp, 0),
4734 Immediate(ExternalReference::isolate_address(isolate)));
4735 __ CallCFunction(ExternalReference::log_enter_external_function(isolate),
4736 1);
4737 __ PopSafepointRegisters();
4738 }
4739
4740
4741 Label profiler_disabled;
4742 Label end_profiler_check;
4743 __ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
4744 __ cmpb(Operand(eax, 0), 0);
4745 __ j(zero, &profiler_disabled);
4746
4747 // Additional parameter is the address of the actual getter function.
4748 __ mov(thunk_last_arg, function_address);
4749 // Call the api function.
4750 __ mov(eax, Immediate(thunk_ref));
4751 __ call(eax);
4752 __ jmp(&end_profiler_check);
4753
4754 __ bind(&profiler_disabled);
4755 // Call the api function.
4756 __ call(function_address);
4757 __ bind(&end_profiler_check);
4758
4759 if (FLAG_log_timer_events) {
4760 FrameScope frame(masm, StackFrame::MANUAL);
4761 __ PushSafepointRegisters();
4762 __ PrepareCallCFunction(1, eax);
4763 __ mov(Operand(esp, 0),
4764 Immediate(ExternalReference::isolate_address(isolate)));
4765 __ CallCFunction(ExternalReference::log_leave_external_function(isolate),
4766 1);
4767 __ PopSafepointRegisters();
4768 }
4769
4770 Label prologue;
4771 // Load the value from ReturnValue
4772 __ mov(eax, return_value_operand);
4773
4774 Label promote_scheduled_exception;
4775 Label exception_handled;
4776 Label delete_allocated_handles;
4777 Label leave_exit_frame;
4778
4779 __ bind(&prologue);
4780 // No more valid handles (the result handle was the last one). Restore
4781 // previous handle scope.
4782 __ mov(Operand::StaticVariable(next_address), ebx);
4783 __ sub(Operand::StaticVariable(level_address), Immediate(1));
4784 __ Assert(above_equal, kInvalidHandleScopeLevel);
4785 __ cmp(edi, Operand::StaticVariable(limit_address));
4786 __ j(not_equal, &delete_allocated_handles);
4787 __ bind(&leave_exit_frame);
4788
4789 // Check if the function scheduled an exception.
4790 ExternalReference scheduled_exception_address =
4791 ExternalReference::scheduled_exception_address(isolate);
4792 __ cmp(Operand::StaticVariable(scheduled_exception_address),
4793 Immediate(isolate->factory()->the_hole_value()));
4794 __ j(not_equal, &promote_scheduled_exception);
4795 __ bind(&exception_handled);
4796
4797 #if DEBUG
4798 // Check if the function returned a valid JavaScript value.
4799 Label ok;
4800 Register return_value = eax;
4801 Register map = ecx;
4802
4803 __ JumpIfSmi(return_value, &ok, Label::kNear);
4804 __ mov(map, FieldOperand(return_value, HeapObject::kMapOffset));
4805
4806 __ CmpInstanceType(map, LAST_NAME_TYPE);
4807 __ j(below_equal, &ok, Label::kNear);
4808
4809 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
4810 __ j(above_equal, &ok, Label::kNear);
4811
4812 __ cmp(map, isolate->factory()->heap_number_map());
4813 __ j(equal, &ok, Label::kNear);
4814
4815 __ cmp(return_value, isolate->factory()->undefined_value());
4816 __ j(equal, &ok, Label::kNear);
4817
4818 __ cmp(return_value, isolate->factory()->true_value());
4819 __ j(equal, &ok, Label::kNear);
4820
4821 __ cmp(return_value, isolate->factory()->false_value());
4822 __ j(equal, &ok, Label::kNear);
4823
4824 __ cmp(return_value, isolate->factory()->null_value());
4825 __ j(equal, &ok, Label::kNear);
4826
4827 __ Abort(kAPICallReturnedInvalidObject);
4828
4829 __ bind(&ok);
4830 #endif
4831
4832 bool restore_context = context_restore_operand != NULL;
4833 if (restore_context) {
4834 __ mov(esi, *context_restore_operand);
4835 }
4836 if (stack_space_operand != nullptr) {
4837 __ mov(ebx, *stack_space_operand);
4838 }
4839 __ LeaveApiExitFrame(!restore_context);
4840 if (stack_space_operand != nullptr) {
4841 DCHECK_EQ(0, stack_space);
4842 __ pop(ecx);
4843 __ add(esp, ebx);
4844 __ jmp(ecx);
4845 } else {
4846 __ ret(stack_space * kPointerSize);
4847 }
4848
4849 __ bind(&promote_scheduled_exception);
4850 {
4851 FrameScope frame(masm, StackFrame::INTERNAL);
4852 __ CallRuntime(Runtime::kPromoteScheduledException, 0);
4853 }
4854 __ jmp(&exception_handled);
4855
4856 // HandleScope limit has changed. Delete allocated extensions.
4857 ExternalReference delete_extensions =
4858 ExternalReference::delete_handle_scope_extensions(isolate);
4859 __ bind(&delete_allocated_handles);
4860 __ mov(Operand::StaticVariable(limit_address), edi);
4861 __ mov(edi, eax);
4862 __ mov(Operand(esp, 0),
4863 Immediate(ExternalReference::isolate_address(isolate)));
4864 __ mov(eax, Immediate(delete_extensions));
4865 __ call(eax);
4866 __ mov(eax, edi);
4867 __ jmp(&leave_exit_frame);
4868 }
4869
4870
4684 static void CallApiFunctionStubHelper(MacroAssembler* masm, 4871 static void CallApiFunctionStubHelper(MacroAssembler* masm,
4685 const ParameterCount& argc, 4872 const ParameterCount& argc,
4686 bool return_first_arg, 4873 bool return_first_arg,
4687 bool call_data_undefined) { 4874 bool call_data_undefined) {
4688 // ----------- S t a t e ------------- 4875 // ----------- S t a t e -------------
4689 // -- eax : callee 4876 // -- eax : callee
4690 // -- ebx : call_data 4877 // -- ebx : call_data
4691 // -- ecx : holder 4878 // -- ecx : holder
4692 // -- edx : api_function_address 4879 // -- edx : api_function_address
4693 // -- esi : context 4880 // -- esi : context
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4756 // API function gets reference to the v8::Arguments. If CPU profiler 4943 // API function gets reference to the v8::Arguments. If CPU profiler
4757 // is enabled wrapper function will be called and we need to pass 4944 // is enabled wrapper function will be called and we need to pass
4758 // address of the callback as additional parameter, always allocate 4945 // address of the callback as additional parameter, always allocate
4759 // space for it. 4946 // space for it.
4760 const int kApiArgc = 1 + 1; 4947 const int kApiArgc = 1 + 1;
4761 4948
4762 // Allocate the v8::Arguments structure in the arguments' space since 4949 // Allocate the v8::Arguments structure in the arguments' space since
4763 // it's not controlled by GC. 4950 // it's not controlled by GC.
4764 const int kApiStackSpace = 4; 4951 const int kApiStackSpace = 4;
4765 4952
4766 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); 4953 PrepareCallApiFunction(masm, kApiArgc + kApiStackSpace);
4767 4954
4768 // FunctionCallbackInfo::implicit_args_. 4955 // FunctionCallbackInfo::implicit_args_.
4769 __ mov(ApiParameterOperand(2), scratch); 4956 __ mov(ApiParameterOperand(2), scratch);
4770 if (argc.is_immediate()) { 4957 if (argc.is_immediate()) {
4771 __ add(scratch, 4958 __ add(scratch,
4772 Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize)); 4959 Immediate((argc.immediate() + FCA::kArgsLength - 1) * kPointerSize));
4773 // FunctionCallbackInfo::values_. 4960 // FunctionCallbackInfo::values_.
4774 __ mov(ApiParameterOperand(3), scratch); 4961 __ mov(ApiParameterOperand(3), scratch);
4775 // FunctionCallbackInfo::length_. 4962 // FunctionCallbackInfo::length_.
4776 __ Move(ApiParameterOperand(4), Immediate(argc.immediate())); 4963 __ Move(ApiParameterOperand(4), Immediate(argc.immediate()));
(...skipping 29 matching lines...) Expand all
4806 return_value_offset = 2 + FCA::kReturnValueOffset; 4993 return_value_offset = 2 + FCA::kReturnValueOffset;
4807 } 4994 }
4808 Operand return_value_operand(ebp, return_value_offset * kPointerSize); 4995 Operand return_value_operand(ebp, return_value_offset * kPointerSize);
4809 int stack_space = 0; 4996 int stack_space = 0;
4810 Operand is_construct_call_operand = ApiParameterOperand(5); 4997 Operand is_construct_call_operand = ApiParameterOperand(5);
4811 Operand* stack_space_operand = &is_construct_call_operand; 4998 Operand* stack_space_operand = &is_construct_call_operand;
4812 if (argc.is_immediate()) { 4999 if (argc.is_immediate()) {
4813 stack_space = argc.immediate() + FCA::kArgsLength + 1; 5000 stack_space = argc.immediate() + FCA::kArgsLength + 1;
4814 stack_space_operand = nullptr; 5001 stack_space_operand = nullptr;
4815 } 5002 }
4816 __ CallApiFunctionAndReturn( 5003 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
4817 api_function_address, thunk_ref, ApiParameterOperand(1), stack_space, 5004 ApiParameterOperand(1), stack_space,
4818 stack_space_operand, return_value_operand, &context_restore_operand); 5005 stack_space_operand, return_value_operand,
5006 &context_restore_operand);
4819 } 5007 }
4820 5008
4821 5009
4822 void CallApiFunctionStub::Generate(MacroAssembler* masm) { 5010 void CallApiFunctionStub::Generate(MacroAssembler* masm) {
4823 // TODO(dcarney): make eax contain the function address. 5011 // TODO(dcarney): make eax contain the function address.
4824 bool call_data_undefined = this->call_data_undefined(); 5012 bool call_data_undefined = this->call_data_undefined();
4825 CallApiFunctionStubHelper(masm, ParameterCount(edi), false, 5013 CallApiFunctionStubHelper(masm, ParameterCount(edi), false,
4826 call_data_undefined); 5014 call_data_undefined);
4827 } 5015 }
4828 5016
(...skipping 23 matching lines...) Expand all
4852 // Allocate space for opional callback address parameter in case 5040 // Allocate space for opional callback address parameter in case
4853 // CPU profiler is active. 5041 // CPU profiler is active.
4854 const int kApiArgc = 2 + 1; 5042 const int kApiArgc = 2 + 1;
4855 5043
4856 Register api_function_address = edx; 5044 Register api_function_address = edx;
4857 Register scratch = ebx; 5045 Register scratch = ebx;
4858 5046
4859 // load address of name 5047 // load address of name
4860 __ lea(scratch, Operand(esp, 1 * kPointerSize)); 5048 __ lea(scratch, Operand(esp, 1 * kPointerSize));
4861 5049
4862 __ PrepareCallApiFunction(kApiArgc); 5050 PrepareCallApiFunction(masm, kApiArgc);
4863 __ mov(ApiParameterOperand(0), scratch); // name. 5051 __ mov(ApiParameterOperand(0), scratch); // name.
4864 __ add(scratch, Immediate(kPointerSize)); 5052 __ add(scratch, Immediate(kPointerSize));
4865 __ mov(ApiParameterOperand(1), scratch); // arguments pointer. 5053 __ mov(ApiParameterOperand(1), scratch); // arguments pointer.
4866 5054
4867 ExternalReference thunk_ref = 5055 ExternalReference thunk_ref =
4868 ExternalReference::invoke_accessor_getter_callback(isolate()); 5056 ExternalReference::invoke_accessor_getter_callback(isolate());
4869 5057
4870 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, 5058 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref,
4871 ApiParameterOperand(2), kStackSpace, nullptr, 5059 ApiParameterOperand(2), kStackSpace, nullptr,
4872 Operand(ebp, 7 * kPointerSize), NULL); 5060 Operand(ebp, 7 * kPointerSize), NULL);
4873 } 5061 }
4874 5062
4875 5063
4876 #undef __ 5064 #undef __
4877 5065
4878 } } // namespace v8::internal 5066 } } // namespace v8::internal
4879 5067
4880 #endif // V8_TARGET_ARCH_IA32 5068 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm64/macro-assembler-arm64.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698