OLD | NEW |
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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 4855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4866 | 4866 |
4867 Label fast_elements_case; | 4867 Label fast_elements_case; |
4868 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); | 4868 __ Branch(&fast_elements_case, eq, a3, Operand(FAST_ELEMENTS)); |
4869 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 4869 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
4870 | 4870 |
4871 __ bind(&fast_elements_case); | 4871 __ bind(&fast_elements_case); |
4872 GenerateCase(masm, FAST_ELEMENTS); | 4872 GenerateCase(masm, FAST_ELEMENTS); |
4873 } | 4873 } |
4874 | 4874 |
4875 | 4875 |
4876 void CallApiFunctionStub::Generate(MacroAssembler* masm) { | 4876 static void CallApiFunctionStubHelper(MacroAssembler* masm, |
| 4877 const ParameterCount& argc, |
| 4878 bool return_first_arg, |
| 4879 bool call_data_undefined) { |
4877 // ----------- S t a t e ------------- | 4880 // ----------- S t a t e ------------- |
4878 // -- a0 : callee | 4881 // -- a0 : callee |
4879 // -- a4 : call_data | 4882 // -- a4 : call_data |
4880 // -- a2 : holder | 4883 // -- a2 : holder |
4881 // -- a1 : api_function_address | 4884 // -- a1 : api_function_address |
| 4885 // -- a3 : number of arguments if argc is a register |
4882 // -- cp : context | 4886 // -- cp : context |
4883 // -- | 4887 // -- |
4884 // -- sp[0] : last argument | 4888 // -- sp[0] : last argument |
4885 // -- ... | 4889 // -- ... |
4886 // -- sp[(argc - 1)* 4] : first argument | 4890 // -- sp[(argc - 1)* 4] : first argument |
4887 // -- sp[argc * 4] : receiver | 4891 // -- sp[argc * 4] : receiver |
4888 // ----------------------------------- | 4892 // ----------------------------------- |
4889 | 4893 |
4890 Register callee = a0; | 4894 Register callee = a0; |
4891 Register call_data = a4; | 4895 Register call_data = a4; |
4892 Register holder = a2; | 4896 Register holder = a2; |
4893 Register api_function_address = a1; | 4897 Register api_function_address = a1; |
4894 Register context = cp; | 4898 Register context = cp; |
4895 | 4899 |
4896 int argc = this->argc(); | |
4897 bool is_store = this->is_store(); | |
4898 bool call_data_undefined = this->call_data_undefined(); | |
4899 | |
4900 typedef FunctionCallbackArguments FCA; | 4900 typedef FunctionCallbackArguments FCA; |
4901 | 4901 |
4902 STATIC_ASSERT(FCA::kContextSaveIndex == 6); | 4902 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
4903 STATIC_ASSERT(FCA::kCalleeIndex == 5); | 4903 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
4904 STATIC_ASSERT(FCA::kDataIndex == 4); | 4904 STATIC_ASSERT(FCA::kDataIndex == 4); |
4905 STATIC_ASSERT(FCA::kReturnValueOffset == 3); | 4905 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
4906 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); | 4906 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
4907 STATIC_ASSERT(FCA::kIsolateIndex == 1); | 4907 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
4908 STATIC_ASSERT(FCA::kHolderIndex == 0); | 4908 STATIC_ASSERT(FCA::kHolderIndex == 0); |
4909 STATIC_ASSERT(FCA::kArgsLength == 7); | 4909 STATIC_ASSERT(FCA::kArgsLength == 7); |
4910 | 4910 |
| 4911 DCHECK(argc.is_immediate() || a3.is(argc.reg())); |
| 4912 |
4911 // Save context, callee and call data. | 4913 // Save context, callee and call data. |
4912 __ Push(context, callee, call_data); | 4914 __ Push(context, callee, call_data); |
4913 // Load context from callee. | 4915 // Load context from callee. |
4914 __ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset)); | 4916 __ ld(context, FieldMemOperand(callee, JSFunction::kContextOffset)); |
4915 | 4917 |
4916 Register scratch = call_data; | 4918 Register scratch = call_data; |
4917 if (!call_data_undefined) { | 4919 if (!call_data_undefined) { |
4918 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 4920 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
4919 } | 4921 } |
4920 // Push return value and default return value. | 4922 // Push return value and default return value. |
4921 __ Push(scratch, scratch); | 4923 __ Push(scratch, scratch); |
4922 __ li(scratch, | 4924 __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
4923 Operand(ExternalReference::isolate_address(isolate()))); | |
4924 // Push isolate and holder. | 4925 // Push isolate and holder. |
4925 __ Push(scratch, holder); | 4926 __ Push(scratch, holder); |
4926 | 4927 |
4927 // Prepare arguments. | 4928 // Prepare arguments. |
4928 __ mov(scratch, sp); | 4929 __ mov(scratch, sp); |
4929 | 4930 |
4930 // Allocate the v8::Arguments structure in the arguments' space since | 4931 // Allocate the v8::Arguments structure in the arguments' space since |
4931 // it's not controlled by GC. | 4932 // it's not controlled by GC. |
4932 const int kApiStackSpace = 4; | 4933 const int kApiStackSpace = 4; |
4933 | 4934 |
4934 FrameScope frame_scope(masm, StackFrame::MANUAL); | 4935 FrameScope frame_scope(masm, StackFrame::MANUAL); |
4935 __ EnterExitFrame(false, kApiStackSpace); | 4936 __ EnterExitFrame(false, kApiStackSpace); |
4936 | 4937 |
4937 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); | 4938 DCHECK(!api_function_address.is(a0) && !scratch.is(a0)); |
4938 // a0 = FunctionCallbackInfo& | 4939 // a0 = FunctionCallbackInfo& |
4939 // Arguments is after the return address. | 4940 // Arguments is after the return address. |
4940 __ Daddu(a0, sp, Operand(1 * kPointerSize)); | 4941 __ Daddu(a0, sp, Operand(1 * kPointerSize)); |
4941 // FunctionCallbackInfo::implicit_args_ | 4942 // FunctionCallbackInfo::implicit_args_ |
4942 __ sd(scratch, MemOperand(a0, 0 * kPointerSize)); | 4943 __ sd(scratch, MemOperand(a0, 0 * kPointerSize)); |
4943 // FunctionCallbackInfo::values_ | 4944 if (argc.is_immediate()) { |
4944 __ Daddu(at, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize)); | 4945 // FunctionCallbackInfo::values_ |
4945 __ sd(at, MemOperand(a0, 1 * kPointerSize)); | 4946 __ Daddu(at, scratch, |
4946 // FunctionCallbackInfo::length_ = argc | 4947 Operand((FCA::kArgsLength - 1 + argc.immediate()) * kPointerSize)); |
4947 __ li(at, Operand(argc)); | 4948 __ sd(at, MemOperand(a0, 1 * kPointerSize)); |
4948 __ sd(at, MemOperand(a0, 2 * kPointerSize)); | 4949 // FunctionCallbackInfo::length_ = argc |
4949 // FunctionCallbackInfo::is_construct_call = 0 | 4950 __ li(at, Operand(argc.immediate())); |
4950 __ sd(zero_reg, MemOperand(a0, 3 * kPointerSize)); | 4951 __ sd(at, MemOperand(a0, 2 * kPointerSize)); |
| 4952 // FunctionCallbackInfo::is_construct_call_ = 0 |
| 4953 __ sd(zero_reg, MemOperand(a0, 3 * kPointerSize)); |
| 4954 } else { |
| 4955 // FunctionCallbackInfo::values_ |
| 4956 __ dsll(at, argc.reg(), kPointerSizeLog2); |
| 4957 __ Daddu(at, at, scratch); |
| 4958 __ Daddu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 4959 __ sd(at, MemOperand(a0, 1 * kPointerSize)); |
| 4960 // FunctionCallbackInfo::length_ = argc |
| 4961 __ sd(argc.reg(), MemOperand(a0, 2 * kPointerSize)); |
| 4962 // FunctionCallbackInfo::is_construct_call_ |
| 4963 __ Daddu(argc.reg(), argc.reg(), Operand(FCA::kArgsLength + 1)); |
| 4964 __ dsll(at, argc.reg(), kPointerSizeLog2); |
| 4965 __ sd(at, MemOperand(a0, 3 * kPointerSize)); |
| 4966 } |
4951 | 4967 |
4952 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; | |
4953 ExternalReference thunk_ref = | 4968 ExternalReference thunk_ref = |
4954 ExternalReference::invoke_function_callback(isolate()); | 4969 ExternalReference::invoke_function_callback(masm->isolate()); |
4955 | 4970 |
4956 AllowExternalCallThatCantCauseGC scope(masm); | 4971 AllowExternalCallThatCantCauseGC scope(masm); |
4957 MemOperand context_restore_operand( | 4972 MemOperand context_restore_operand( |
4958 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); | 4973 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); |
4959 // Stores return the first js argument. | 4974 // Stores return the first js argument. |
4960 int return_value_offset = 0; | 4975 int return_value_offset = 0; |
4961 if (is_store) { | 4976 if (return_first_arg) { |
4962 return_value_offset = 2 + FCA::kArgsLength; | 4977 return_value_offset = 2 + FCA::kArgsLength; |
4963 } else { | 4978 } else { |
4964 return_value_offset = 2 + FCA::kReturnValueOffset; | 4979 return_value_offset = 2 + FCA::kReturnValueOffset; |
4965 } | 4980 } |
4966 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); | 4981 MemOperand return_value_operand(fp, return_value_offset * kPointerSize); |
| 4982 int stack_space = 0; |
| 4983 MemOperand is_construct_call_operand = MemOperand(sp, 4 * kPointerSize); |
| 4984 MemOperand* stack_space_operand = &is_construct_call_operand; |
| 4985 if (argc.is_immediate()) { |
| 4986 stack_space = argc.immediate() + FCA::kArgsLength + 1; |
| 4987 stack_space_operand = NULL; |
| 4988 } |
| 4989 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, stack_space, |
| 4990 stack_space_operand, return_value_operand, |
| 4991 &context_restore_operand); |
| 4992 } |
4967 | 4993 |
4968 __ CallApiFunctionAndReturn(api_function_address, | 4994 |
4969 thunk_ref, | 4995 void CallApiFunctionStub::Generate(MacroAssembler* masm) { |
4970 kStackUnwindSpace, | 4996 bool call_data_undefined = this->call_data_undefined(); |
4971 return_value_operand, | 4997 CallApiFunctionStubHelper(masm, ParameterCount(a3), false, |
4972 &context_restore_operand); | 4998 call_data_undefined); |
| 4999 } |
| 5000 |
| 5001 |
| 5002 void CallApiAccessorStub::Generate(MacroAssembler* masm) { |
| 5003 bool is_store = this->is_store(); |
| 5004 int argc = is_store ? 1 : 0; |
| 5005 bool call_data_undefined = this->call_data_undefined(); |
| 5006 CallApiFunctionStubHelper(masm, ParameterCount(argc), is_store, |
| 5007 call_data_undefined); |
4973 } | 5008 } |
4974 | 5009 |
4975 | 5010 |
4976 void CallApiGetterStub::Generate(MacroAssembler* masm) { | 5011 void CallApiGetterStub::Generate(MacroAssembler* masm) { |
4977 // ----------- S t a t e ------------- | 5012 // ----------- S t a t e ------------- |
4978 // -- sp[0] : name | 5013 // -- sp[0] : name |
4979 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object | 5014 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object |
4980 // -- ... | 5015 // -- ... |
4981 // -- a2 : api_function_address | 5016 // -- a2 : api_function_address |
4982 // ----------------------------------- | 5017 // ----------------------------------- |
(...skipping 10 matching lines...) Expand all Loading... |
4993 | 5028 |
4994 // Create PropertyAccessorInfo instance on the stack above the exit frame with | 5029 // Create PropertyAccessorInfo instance on the stack above the exit frame with |
4995 // a1 (internal::Object** args_) as the data. | 5030 // a1 (internal::Object** args_) as the data. |
4996 __ sd(a1, MemOperand(sp, 1 * kPointerSize)); | 5031 __ sd(a1, MemOperand(sp, 1 * kPointerSize)); |
4997 __ Daddu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo& | 5032 __ Daddu(a1, sp, Operand(1 * kPointerSize)); // a1 = AccessorInfo& |
4998 | 5033 |
4999 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 5034 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
5000 | 5035 |
5001 ExternalReference thunk_ref = | 5036 ExternalReference thunk_ref = |
5002 ExternalReference::invoke_accessor_getter_callback(isolate()); | 5037 ExternalReference::invoke_accessor_getter_callback(isolate()); |
5003 __ CallApiFunctionAndReturn(api_function_address, | 5038 __ CallApiFunctionAndReturn(api_function_address, thunk_ref, |
5004 thunk_ref, | 5039 kStackUnwindSpace, NULL, |
5005 kStackUnwindSpace, | 5040 MemOperand(fp, 6 * kPointerSize), NULL); |
5006 MemOperand(fp, 6 * kPointerSize), | |
5007 NULL); | |
5008 } | 5041 } |
5009 | 5042 |
5010 | 5043 |
5011 #undef __ | 5044 #undef __ |
5012 | 5045 |
5013 } } // namespace v8::internal | 5046 } } // namespace v8::internal |
5014 | 5047 |
5015 #endif // V8_TARGET_ARCH_MIPS64 | 5048 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |