| 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 |