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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4215 Branch(done); | 4215 Branch(done); |
4216 } | 4216 } |
4217 } else { | 4217 } else { |
4218 Jump(adaptor, RelocInfo::CODE_TARGET); | 4218 Jump(adaptor, RelocInfo::CODE_TARGET); |
4219 } | 4219 } |
4220 bind(®ular_invoke); | 4220 bind(®ular_invoke); |
4221 } | 4221 } |
4222 } | 4222 } |
4223 | 4223 |
4224 | 4224 |
4225 void MacroAssembler::InvokeCode(Register code, | 4225 void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, |
4226 Register new_target, | 4226 const ParameterCount& expected, |
4227 const ParameterCount& expected, | 4227 const ParameterCount& actual) { |
4228 const ParameterCount& actual, | 4228 Label skip_flooding; |
4229 InvokeFlag flag, | 4229 ExternalReference debug_step_action = |
4230 const CallWrapper& call_wrapper) { | 4230 ExternalReference::debug_last_step_action_address(isolate()); |
| 4231 li(t0, Operand(debug_step_action)); |
| 4232 lb(t0, MemOperand(t0)); |
| 4233 Branch(&skip_flooding, ne, t0, Operand(StepIn)); |
| 4234 { |
| 4235 FrameScope frame(this, |
| 4236 has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); |
| 4237 if (expected.is_reg()) { |
| 4238 SmiTag(expected.reg()); |
| 4239 Push(expected.reg()); |
| 4240 } |
| 4241 if (actual.is_reg()) { |
| 4242 SmiTag(actual.reg()); |
| 4243 Push(actual.reg()); |
| 4244 } |
| 4245 if (new_target.is_valid()) { |
| 4246 Push(new_target); |
| 4247 } |
| 4248 Push(fun); |
| 4249 Push(fun); |
| 4250 CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); |
| 4251 Pop(fun); |
| 4252 if (new_target.is_valid()) { |
| 4253 Pop(new_target); |
| 4254 } |
| 4255 if (actual.is_reg()) { |
| 4256 Pop(actual.reg()); |
| 4257 SmiUntag(actual.reg()); |
| 4258 } |
| 4259 if (expected.is_reg()) { |
| 4260 Pop(expected.reg()); |
| 4261 SmiUntag(expected.reg()); |
| 4262 } |
| 4263 } |
| 4264 bind(&skip_flooding); |
| 4265 } |
| 4266 |
| 4267 |
| 4268 void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, |
| 4269 const ParameterCount& expected, |
| 4270 const ParameterCount& actual, |
| 4271 InvokeFlag flag, |
| 4272 const CallWrapper& call_wrapper) { |
4231 // You can't call a function without a valid frame. | 4273 // You can't call a function without a valid frame. |
4232 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4274 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
| 4275 DCHECK(function.is(a1)); |
| 4276 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); |
4233 | 4277 |
4234 // Ensure new target is passed in the correct register. Otherwise clear the | 4278 if (call_wrapper.NeedsDebugStepCheck()) { |
4235 // appropriate register in case new target is not given. | 4279 FloodFunctionIfStepping(function, new_target, expected, actual); |
4236 DCHECK_IMPLIES(new_target.is_valid(), new_target.is(a3)); | 4280 } |
| 4281 |
| 4282 // Clear the new.target register if not given. |
4237 if (!new_target.is_valid()) { | 4283 if (!new_target.is_valid()) { |
4238 LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 4284 LoadRoot(a3, Heap::kUndefinedValueRootIndex); |
4239 } | 4285 } |
4240 | 4286 |
4241 Label done; | 4287 Label done; |
4242 bool definitely_mismatches = false; | 4288 bool definitely_mismatches = false; |
4243 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, | 4289 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
4244 call_wrapper); | 4290 call_wrapper); |
4245 if (!definitely_mismatches) { | 4291 if (!definitely_mismatches) { |
| 4292 // We call indirectly through the code field in the function to |
| 4293 // allow recompilation to take effect without changing any of the |
| 4294 // call sites. |
| 4295 Register code = t0; |
| 4296 ld(code, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); |
4246 if (flag == CALL_FUNCTION) { | 4297 if (flag == CALL_FUNCTION) { |
4247 call_wrapper.BeforeCall(CallSize(code)); | 4298 call_wrapper.BeforeCall(CallSize(code)); |
4248 Call(code); | 4299 Call(code); |
4249 call_wrapper.AfterCall(); | 4300 call_wrapper.AfterCall(); |
4250 } else { | 4301 } else { |
4251 DCHECK(flag == JUMP_FUNCTION); | 4302 DCHECK(flag == JUMP_FUNCTION); |
4252 Jump(code); | 4303 Jump(code); |
4253 } | 4304 } |
4254 // Continue here if InvokePrologue does handle the invocation due to | 4305 // Continue here if InvokePrologue does handle the invocation due to |
4255 // mismatched parameter counts. | 4306 // mismatched parameter counts. |
4256 bind(&done); | 4307 bind(&done); |
4257 } | 4308 } |
4258 } | 4309 } |
4259 | 4310 |
4260 | 4311 |
4261 void MacroAssembler::InvokeFunction(Register function, | 4312 void MacroAssembler::InvokeFunction(Register function, |
4262 Register new_target, | 4313 Register new_target, |
4263 const ParameterCount& actual, | 4314 const ParameterCount& actual, |
4264 InvokeFlag flag, | 4315 InvokeFlag flag, |
4265 const CallWrapper& call_wrapper) { | 4316 const CallWrapper& call_wrapper) { |
4266 // You can't call a function without a valid frame. | 4317 // You can't call a function without a valid frame. |
4267 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4318 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4268 | 4319 |
4269 // Contract with called JS functions requires that function is passed in a1. | 4320 // Contract with called JS functions requires that function is passed in a1. |
4270 DCHECK(function.is(a1)); | 4321 DCHECK(function.is(a1)); |
4271 Register expected_reg = a2; | 4322 Register expected_reg = a2; |
4272 Register code_reg = t0; | 4323 Register temp_reg = t0; |
4273 ld(code_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 4324 ld(temp_reg, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
4274 ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4325 ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4275 // The argument count is stored as int32_t on 64-bit platforms. | 4326 // The argument count is stored as int32_t on 64-bit platforms. |
4276 // TODO(plind): Smi on 32-bit platforms. | 4327 // TODO(plind): Smi on 32-bit platforms. |
4277 lw(expected_reg, | 4328 lw(expected_reg, |
4278 FieldMemOperand(code_reg, | 4329 FieldMemOperand(temp_reg, |
4279 SharedFunctionInfo::kFormalParameterCountOffset)); | 4330 SharedFunctionInfo::kFormalParameterCountOffset)); |
4280 ld(code_reg, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
4281 ParameterCount expected(expected_reg); | 4331 ParameterCount expected(expected_reg); |
4282 InvokeCode(code_reg, new_target, expected, actual, flag, call_wrapper); | 4332 InvokeFunctionCode(a1, new_target, expected, actual, flag, call_wrapper); |
4283 } | 4333 } |
4284 | 4334 |
4285 | 4335 |
4286 void MacroAssembler::InvokeFunction(Register function, | 4336 void MacroAssembler::InvokeFunction(Register function, |
4287 const ParameterCount& expected, | 4337 const ParameterCount& expected, |
4288 const ParameterCount& actual, | 4338 const ParameterCount& actual, |
4289 InvokeFlag flag, | 4339 InvokeFlag flag, |
4290 const CallWrapper& call_wrapper) { | 4340 const CallWrapper& call_wrapper) { |
4291 // You can't call a function without a valid frame. | 4341 // You can't call a function without a valid frame. |
4292 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 4342 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
4293 | 4343 |
4294 // Contract with called JS functions requires that function is passed in a1. | 4344 // Contract with called JS functions requires that function is passed in a1. |
4295 DCHECK(function.is(a1)); | 4345 DCHECK(function.is(a1)); |
4296 | 4346 |
4297 // Get the function and setup the context. | 4347 // Get the function and setup the context. |
4298 ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 4348 ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
4299 | 4349 |
4300 // We call indirectly through the code field in the function to | 4350 InvokeFunctionCode(a1, no_reg, expected, actual, flag, call_wrapper); |
4301 // allow recompilation to take effect without changing any of the | |
4302 // call sites. | |
4303 ld(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | |
4304 InvokeCode(t0, no_reg, expected, actual, flag, call_wrapper); | |
4305 } | 4351 } |
4306 | 4352 |
4307 | 4353 |
4308 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, | 4354 void MacroAssembler::InvokeFunction(Handle<JSFunction> function, |
4309 const ParameterCount& expected, | 4355 const ParameterCount& expected, |
4310 const ParameterCount& actual, | 4356 const ParameterCount& actual, |
4311 InvokeFlag flag, | 4357 InvokeFlag flag, |
4312 const CallWrapper& call_wrapper) { | 4358 const CallWrapper& call_wrapper) { |
4313 li(a1, function); | 4359 li(a1, function); |
4314 InvokeFunction(a1, expected, actual, flag, call_wrapper); | 4360 InvokeFunction(a1, expected, actual, flag, call_wrapper); |
(...skipping 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6238 if (mag.shift > 0) sra(result, result, mag.shift); | 6284 if (mag.shift > 0) sra(result, result, mag.shift); |
6239 srl(at, dividend, 31); | 6285 srl(at, dividend, 31); |
6240 Addu(result, result, Operand(at)); | 6286 Addu(result, result, Operand(at)); |
6241 } | 6287 } |
6242 | 6288 |
6243 | 6289 |
6244 } // namespace internal | 6290 } // namespace internal |
6245 } // namespace v8 | 6291 } // namespace v8 |
6246 | 6292 |
6247 #endif // V8_TARGET_ARCH_MIPS64 | 6293 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |