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 3992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4003 Branch(done); | 4003 Branch(done); |
4004 } | 4004 } |
4005 } else { | 4005 } else { |
4006 Jump(adaptor, RelocInfo::CODE_TARGET); | 4006 Jump(adaptor, RelocInfo::CODE_TARGET); |
4007 } | 4007 } |
4008 bind(®ular_invoke); | 4008 bind(®ular_invoke); |
4009 } | 4009 } |
4010 } | 4010 } |
4011 | 4011 |
4012 | 4012 |
4013 void MacroAssembler::InvokeCode(Register code, | 4013 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, |
4014 Register new_target, | 4014 const ParameterCount& expected, |
4015 const ParameterCount& expected, | 4015 const ParameterCount& actual) { |
4016 const ParameterCount& actual, | 4016 Label skip_flooding; |
4017 InvokeFlag flag, | 4017 ExternalReference debug_step_action = |
4018 const CallWrapper& call_wrapper) { | 4018 ExternalReference::debug_last_step_action_address(isolate()); |
| 4019 li(t0, Operand(debug_step_action)); |
| 4020 lb(t0, MemOperand(t0)); |
| 4021 Branch(&skip_flooding, ne, t0, Operand(StepIn)); |
| 4022 { |
| 4023 FrameScope frame(this, |
| 4024 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); |
| 4025 if (expected.is_reg()) { |
| 4026 SmiTag(expected.reg()); |
| 4027 Push(expected.reg()); |
| 4028 } |
| 4029 if (actual.is_reg()) { |
| 4030 SmiTag(actual.reg()); |
| 4031 Push(actual.reg()); |
| 4032 } |
| 4033 if (new_target.is_valid()) { |
| 4034 Push(new_target); |
| 4035 } |
| 4036 Push(fun); |
| 4037 Push(fun); |
| 4038 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); |
| 4039 Pop(fun); |
| 4040 if (new_target.is_valid()) { |
| 4041 Pop(new_target); |
| 4042 } |
| 4043 if (actual.is_reg()) { |
| 4044 Pop(actual.reg()); |
| 4045 SmiUntag(actual.reg()); |
| 4046 } |
| 4047 if (expected.is_reg()) { |
| 4048 Pop(expected.reg()); |
| 4049 SmiUntag(expected.reg()); |
| 4050 } |
| 4051 } |
| 4052 bind(&skip_flooding); |
| 4053 } |
| 4054 |
| 4055 |
| 4056 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, |
| 4057 const ParameterCount& expected, |
| 4058 const ParameterCount& actual, |
| 4059 InvokeFlag flag, |
| 4060 const CallWrapper& call_wrapper) { |
4019 // You can't call a function without a valid frame. | 4061 // You can't call a function without a valid frame. |
4020 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4062 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 4063 DCHECK(function.is(a1)); |
| 4064 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); |
4021 | 4065 |
4022 // Ensure new target is passed in the correct register. Otherwise clear the | 4066 if (call_wrapper.NeedsDebugStepCheck()) { |
4023 // appropriate register in case new target is not given. | 4067 FloodFunctionIfStepping(function, new_target, expected, actual); |
4024 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); | 4068 } |
| 4069 |
| 4070 // Clear the new.target register if not given. |
4025 if (!new_target.is_valid()) { | 4071 if (!new_target.is_valid()) { |
4026 LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 4072 LoadRoot(a3, Heap::kUndefinedValueRootIndex); |
4027 } | 4073 } |
4028 | 4074 |
4029 Label done; | 4075 Label done; |
4030 bool definitely_mismatches = false; | 4076 bool definitely_mismatches = false; |
4031 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 4077 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
4032 call_wrapper); | 4078 call_wrapper); |
4033 if (!definitely_mismatches) { | 4079 if (!definitely_mismatches) { |
| 4080 // We call indirectly through the code field in the function to |
| 4081 // allow recompilation to take effect without changing any of the |
| 4082 // call sites. |
| 4083 Register code = t0; |
| 4084 lw(code, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
4034 if (flag == CALL_FUNCTION) { | 4085 if (flag == CALL_FUNCTION) { |
4035 call_wrapper.BeforeCall(CallSize(code)); | 4086 call_wrapper.BeforeCall(CallSize(code)); |
4036 Call(code); | 4087 Call(code); |
4037 call_wrapper.AfterCall(); | 4088 call_wrapper.AfterCall(); |
4038 } else { | 4089 } else { |
4039 DCHECK(flag == JUMP_FUNCTION); | 4090 DCHECK(flag == JUMP_FUNCTION); |
4040 Jump(code); | 4091 Jump(code); |
4041 } | 4092 } |
4042 // Continue here if InvokePrologue does handle the invocation due to | 4093 // Continue here if InvokePrologue does handle the invocation due to |
4043 // mismatched parameter counts. | 4094 // mismatched parameter counts. |
4044 bind(&done); | 4095 bind(&done); |
4045 } | 4096 } |
4046 } | 4097 } |
4047 | 4098 |
4048 | 4099 |
4049 void MacroAssembler::InvokeFunction(Register function, | 4100 void MacroAssembler::InvokeFunction(Register function, |
4050 Register new_target, | 4101 Register new_target, |
4051 const ParameterCount& actual, | 4102 const ParameterCount& actual, |
4052 InvokeFlag flag, | 4103 InvokeFlag flag, |
4053 const CallWrapper& call_wrapper) { | 4104 const CallWrapper& call_wrapper) { |
4054 // You can't call a function without a valid frame. | 4105 // You can't call a function without a valid frame. |
4055 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4106 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4056 | 4107 |
4057 // 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. |
4058 DCHECK(function.is(a1)); | 4109 DCHECK(function.is(a1)); |
4059 Register expected_reg = a2; | 4110 Register expected_reg = a2; |
4060 Register code_reg = t0; | 4111 Register temp_reg = t0; |
4061 | 4112 |
4062 lw(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 4113 lw(temp_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
4063 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4114 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4064 lw(expected_reg, | 4115 lw(expected_reg, |
4065 FieldMemOperand(code_reg, | 4116 FieldMemOperand(temp_reg, |
4066 SharedFunctionInfo::kFormalParameterCountOffset)); | 4117 SharedFunctionInfo::kFormalParameterCountOffset)); |
4067 sra(expected_reg, expected_reg, kSmiTagSize); | 4118 sra(expected_reg, expected_reg, kSmiTagSize); |
4068 lw(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
4069 | 4119 |
4070 ParameterCount expected(expected_reg); | 4120 ParameterCount expected(expected_reg); |
4071 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); | 4121 InvokeFunctionCode(function, new_target, expected, actual, flag, |
| 4122 call_wrapper); |
4072 } | 4123 } |
4073 | 4124 |
4074 | 4125 |
4075 void MacroAssembler::InvokeFunction(Register function, | 4126 void MacroAssembler::InvokeFunction(Register function, |
4076 const ParameterCount& expected, | 4127 const ParameterCount& expected, |
4077 const ParameterCount& actual, | 4128 const ParameterCount& actual, |
4078 InvokeFlag flag, | 4129 InvokeFlag flag, |
4079 const CallWrapper& call_wrapper) { | 4130 const CallWrapper& call_wrapper) { |
4080 // You can't call a function without a valid frame. | 4131 // You can't call a function without a valid frame. |
4081 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4132 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4082 | 4133 |
4083 // Contract with called JS functions requires that function is passed in a1. | 4134 // Contract with called JS functions requires that function is passed in a1. |
4084 DCHECK(function.is(a1)); | 4135 DCHECK(function.is(a1)); |
4085 | 4136 |
4086 // Get the function and setup the context. | 4137 // Get the function and setup the context. |
4087 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4138 lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4088 | 4139 |
4089 // We call indirectly through the code field in the function to | 4140 InvokeFunctionCode(a1, no_reg, expected, actual, flag, call_wrapper); |
4090 // allow recompilation to take effect without changing any of the | |
4091 // call sites. | |
4092 lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
4093 InvokeCode(t0, no_reg, expected, actual, flag, call_wrapper); | |
4094 } | 4141 } |
4095 | 4142 |
4096 | 4143 |
4097 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 4144 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
4098 const ParameterCount& expected, | 4145 const ParameterCount& expected, |
4099 const ParameterCount& actual, | 4146 const ParameterCount& actual, |
4100 InvokeFlag flag, | 4147 InvokeFlag flag, |
4101 const CallWrapper& call_wrapper) { | 4148 const CallWrapper& call_wrapper) { |
4102 li(a1, function); | 4149 li(a1, function); |
4103 InvokeFunction(a1, expected, actual, flag, call_wrapper); | 4150 InvokeFunction(a1, expected, actual, flag, call_wrapper); |
(...skipping 1713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5817 if (mag.shift > 0) sra(result, result, mag.shift); | 5864 if (mag.shift > 0) sra(result, result, mag.shift); |
5818 srl(at, dividend, 31); | 5865 srl(at, dividend, 31); |
5819 Addu(result, result, Operand(at)); | 5866 Addu(result, result, Operand(at)); |
5820 } | 5867 } |
5821 | 5868 |
5822 | 5869 |
5823 } // namespace internal | 5870 } // namespace internal |
5824 } // namespace v8 | 5871 } // namespace v8 |
5825 | 5872 |
5826 #endif // V8_TARGET_ARCH_MIPS | 5873 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |