OLD | NEW |
1 | 1 |
2 // Copyright 2012 the V8 project authors. All rights reserved. | 2 // Copyright 2012 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_MIPS | 8 #if V8_TARGET_ARCH_MIPS |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 4017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4028 Branch(done); | 4028 Branch(done); |
4029 } | 4029 } |
4030 } else { | 4030 } else { |
4031 Jump(adaptor, RelocInfo::CODE_TARGET); | 4031 Jump(adaptor, RelocInfo::CODE_TARGET); |
4032 } | 4032 } |
4033 bind(®ular_invoke); | 4033 bind(®ular_invoke); |
4034 } | 4034 } |
4035 } | 4035 } |
4036 | 4036 |
4037 | 4037 |
4038 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, | 4038 void MacroAssembler::InvokeCode(Register code, |
4039 const ParameterCount& expected, | 4039 Register new_target, |
4040 const ParameterCount& actual) { | 4040 const ParameterCount& expected, |
4041 Label skip_flooding; | 4041 const ParameterCount& actual, |
4042 ExternalReference debug_step_action = | 4042 InvokeFlag flag, |
4043 ExternalReference::debug_last_step_action_address(isolate()); | 4043 const CallWrapper& call_wrapper) { |
4044 li(t0, Operand(debug_step_action)); | |
4045 lb(t0, MemOperand(t0)); | |
4046 Branch(&skip_flooding, ne, t0, Operand(StepIn)); | |
4047 { | |
4048 FrameScope frame(this, | |
4049 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); | |
4050 if (expected.is_reg()) { | |
4051 SmiTag(expected.reg()); | |
4052 Push(expected.reg()); | |
4053 } | |
4054 if (actual.is_reg()) { | |
4055 SmiTag(actual.reg()); | |
4056 Push(actual.reg()); | |
4057 } | |
4058 if (new_target.is_valid()) { | |
4059 Push(new_target); | |
4060 } | |
4061 Push(fun); | |
4062 Push(fun); | |
4063 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); | |
4064 Pop(fun); | |
4065 if (new_target.is_valid()) { | |
4066 Pop(new_target); | |
4067 } | |
4068 if (actual.is_reg()) { | |
4069 Pop(actual.reg()); | |
4070 SmiUntag(actual.reg()); | |
4071 } | |
4072 if (expected.is_reg()) { | |
4073 Pop(expected.reg()); | |
4074 SmiUntag(expected.reg()); | |
4075 } | |
4076 } | |
4077 bind(&skip_flooding); | |
4078 } | |
4079 | |
4080 | |
4081 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, | |
4082 const ParameterCount& expected, | |
4083 const ParameterCount& actual, | |
4084 InvokeFlag flag, | |
4085 const CallWrapper& call_wrapper) { | |
4086 // You can't call a function without a valid frame. | 4044 // You can't call a function without a valid frame. |
4087 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4045 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4088 DCHECK(function.is(a1)); | 4046 |
| 4047 // Ensure new target is passed in the correct register. Otherwise clear the |
| 4048 // appropriate register in case new target is not given. |
4089 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); | 4049 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); |
4090 | |
4091 if (call_wrapper.NeedsDebugStepCheck()) { | |
4092 FloodFunctionIfStepping(function, new_target, expected, actual); | |
4093 } | |
4094 | |
4095 // Clear the new.target register if not given. | |
4096 if (!new_target.is_valid()) { | 4050 if (!new_target.is_valid()) { |
4097 LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 4051 LoadRoot(a3, Heap::kUndefinedValueRootIndex); |
4098 } | 4052 } |
4099 | 4053 |
4100 Label done; | 4054 Label done; |
4101 bool definitely_mismatches = false; | 4055 bool definitely_mismatches = false; |
4102 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 4056 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
4103 call_wrapper); | 4057 call_wrapper); |
4104 if (!definitely_mismatches) { | 4058 if (!definitely_mismatches) { |
4105 // We call indirectly through the code field in the function to | |
4106 // allow recompilation to take effect without changing any of the | |
4107 // call sites. | |
4108 Register code = t0; | |
4109 lw(code, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | |
4110 if (flag == CALL_FUNCTION) { | 4059 if (flag == CALL_FUNCTION) { |
4111 call_wrapper.BeforeCall(CallSize(code)); | 4060 call_wrapper.BeforeCall(CallSize(code)); |
4112 Call(code); | 4061 Call(code); |
4113 call_wrapper.AfterCall(); | 4062 call_wrapper.AfterCall(); |
4114 } else { | 4063 } else { |
4115 DCHECK(flag == JUMP_FUNCTION); | 4064 DCHECK(flag == JUMP_FUNCTION); |
4116 Jump(code); | 4065 Jump(code); |
4117 } | 4066 } |
4118 // Continue here if InvokePrologue does handle the invocation due to | 4067 // Continue here if InvokePrologue does handle the invocation due to |
4119 // mismatched parameter counts. | 4068 // mismatched parameter counts. |
4120 bind(&done); | 4069 bind(&done); |
4121 } | 4070 } |
4122 } | 4071 } |
4123 | 4072 |
4124 | 4073 |
4125 void MacroAssembler::InvokeFunction(Register function, | 4074 void MacroAssembler::InvokeFunction(Register function, |
4126 Register new_target, | 4075 Register new_target, |
4127 const ParameterCount& actual, | 4076 const ParameterCount& actual, |
4128 InvokeFlag flag, | 4077 InvokeFlag flag, |
4129 const CallWrapper& call_wrapper) { | 4078 const CallWrapper& call_wrapper) { |
4130 // You can't call a function without a valid frame. | 4079 // You can't call a function without a valid frame. |
4131 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4080 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4132 | 4081 |
4133 // Contract with called JS functions requires that function is passed in a1. | 4082 // Contract with called JS functions requires that function is passed in a1. |
4134 DCHECK(function.is(a1)); | 4083 DCHECK(function.is(a1)); |
4135 Register expected_reg = a2; | 4084 Register expected_reg = a2; |
4136 Register temp_reg = t0; | 4085 Register code_reg = t0; |
4137 | 4086 |
4138 lw(temp_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 4087 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
4139 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4088 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4140 lw(expected_reg, | 4089 lw(expected_reg, |
4141 FieldMemOperand(temp_reg, | 4090 FieldMemOperand(code_reg, |
4142 SharedFunctionInfo::kFormalParameterCountOffset)); | 4091 SharedFunctionInfo::kFormalParameterCountOffset)); |
4143 sra(expected_reg, expected_reg, kSmiTagSize); | 4092 sra(expected_reg, expected_reg, kSmiTagSize); |
| 4093 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
4144 | 4094 |
4145 ParameterCount expected(expected_reg); | 4095 ParameterCount expected(expected_reg); |
4146 InvokeFunctionCode(function, new_target, expected, actual, flag, | 4096 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); |
4147 call_wrapper); | |
4148 } | 4097 } |
4149 | 4098 |
4150 | 4099 |
4151 void MacroAssembler::InvokeFunction(Register function, | 4100 void MacroAssembler::InvokeFunction(Register function, |
4152 const ParameterCount& expected, | 4101 const ParameterCount& expected, |
4153 const ParameterCount& actual, | 4102 const ParameterCount& actual, |
4154 InvokeFlag flag, | 4103 InvokeFlag flag, |
4155 const CallWrapper& call_wrapper) { | 4104 const CallWrapper& call_wrapper) { |
4156 // You can't call a function without a valid frame. | 4105 // You can't call a function without a valid frame. |
4157 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4106 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4158 | 4107 |
4159 // Contract with called JS functions requires that function is passed in a1. | 4108 // Contract with called JS functions requires that function is passed in a1. |
4160 DCHECK(function.is(a1)); | 4109 DCHECK(function.is(a1)); |
4161 | 4110 |
4162 // Get the function and setup the context. | 4111 // Get the function and setup the context. |
4163 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4112 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4164 | 4113 |
4165 InvokeFunctionCode(a1, no_reg, expected, actual, flag, call_wrapper); | 4114 // We call indirectly through the code field in the function to |
| 4115 // allow recompilation to take effect without changing any of the |
| 4116 // call sites. |
| 4117 lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 4118 InvokeCode(t0, no_reg, expected, actual, flag, call_wrapper); |
4166 } | 4119 } |
4167 | 4120 |
4168 | 4121 |
4169 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 4122 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
4170 const ParameterCount& expected, | 4123 const ParameterCount& expected, |
4171 const ParameterCount& actual, | 4124 const ParameterCount& actual, |
4172 InvokeFlag flag, | 4125 InvokeFlag flag, |
4173 const CallWrapper& call_wrapper) { | 4126 const CallWrapper& call_wrapper) { |
4174 li(a1, function); | 4127 li(a1, function); |
4175 InvokeFunction(a1, expected, actual, flag, call_wrapper); | 4128 InvokeFunction(a1, expected, actual, flag, call_wrapper); |
(...skipping 1714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 if (mag.shift > 0) sra(result, result, mag.shift); | 5843 if (mag.shift > 0) sra(result, result, mag.shift); |
5891 srl(at, dividend, 31); | 5844 srl(at, dividend, 31); |
5892 Addu(result, result, Operand(at)); | 5845 Addu(result, result, Operand(at)); |
5893 } | 5846 } |
5894 | 5847 |
5895 | 5848 |
5896 } // namespace internal | 5849 } // namespace internal |
5897 } // namespace v8 | 5850 } // namespace v8 |
5898 | 5851 |
5899 #endif // V8_TARGET_ARCH_MIPS | 5852 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |