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 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS64 | 9 #if V8_TARGET_ARCH_MIPS64 |
10 | 10 |
(...skipping 4341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4352 | 4352 |
4353 void MacroAssembler::TailCallStub(CodeStub* stub, | 4353 void MacroAssembler::TailCallStub(CodeStub* stub, |
4354 Condition cond, | 4354 Condition cond, |
4355 Register r1, | 4355 Register r1, |
4356 const Operand& r2, | 4356 const Operand& r2, |
4357 BranchDelaySlot bd) { | 4357 BranchDelaySlot bd) { |
4358 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd); | 4358 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd); |
4359 } | 4359 } |
4360 | 4360 |
4361 | 4361 |
4362 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | |
4363 int64_t offset = (ref0.address() - ref1.address()); | |
4364 DCHECK(static_cast<int>(offset) == offset); | |
4365 return static_cast<int>(offset); | |
4366 } | |
4367 | |
4368 | |
4369 void MacroAssembler::CallApiFunctionAndReturn( | |
4370 Register function_address, ExternalReference thunk_ref, int stack_space, | |
4371 MemOperand* stack_space_operand, MemOperand return_value_operand, | |
4372 MemOperand* context_restore_operand) { | |
4373 ExternalReference next_address = | |
4374 ExternalReference::handle_scope_next_address(isolate()); | |
4375 const int kNextOffset = 0; | |
4376 const int kLimitOffset = AddressOffset( | |
4377 ExternalReference::handle_scope_limit_address(isolate()), | |
4378 next_address); | |
4379 const int kLevelOffset = AddressOffset( | |
4380 ExternalReference::handle_scope_level_address(isolate()), | |
4381 next_address); | |
4382 | |
4383 DCHECK(function_address.is(a1) || function_address.is(a2)); | |
4384 | |
4385 Label profiler_disabled; | |
4386 Label end_profiler_check; | |
4387 li(t9, Operand(ExternalReference::is_profiling_address(isolate()))); | |
4388 lb(t9, MemOperand(t9, 0)); | |
4389 Branch(&profiler_disabled, eq, t9, Operand(zero_reg)); | |
4390 | |
4391 // Additional parameter is the address of the actual callback. | |
4392 li(t9, Operand(thunk_ref)); | |
4393 jmp(&end_profiler_check); | |
4394 | |
4395 bind(&profiler_disabled); | |
4396 mov(t9, function_address); | |
4397 bind(&end_profiler_check); | |
4398 | |
4399 // Allocate HandleScope in callee-save registers. | |
4400 li(s3, Operand(next_address)); | |
4401 ld(s0, MemOperand(s3, kNextOffset)); | |
4402 ld(s1, MemOperand(s3, kLimitOffset)); | |
4403 ld(s2, MemOperand(s3, kLevelOffset)); | |
4404 Daddu(s2, s2, Operand(1)); | |
4405 sd(s2, MemOperand(s3, kLevelOffset)); | |
4406 | |
4407 if (FLAG_log_timer_events) { | |
4408 FrameScope frame(this, StackFrame::MANUAL); | |
4409 PushSafepointRegisters(); | |
4410 PrepareCallCFunction(1, a0); | |
4411 li(a0, Operand(ExternalReference::isolate_address(isolate()))); | |
4412 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); | |
4413 PopSafepointRegisters(); | |
4414 } | |
4415 | |
4416 // Native call returns to the DirectCEntry stub which redirects to the | |
4417 // return address pushed on stack (could have moved after GC). | |
4418 // DirectCEntry stub itself is generated early and never moves. | |
4419 DirectCEntryStub stub(isolate()); | |
4420 stub.GenerateCall(this, t9); | |
4421 | |
4422 if (FLAG_log_timer_events) { | |
4423 FrameScope frame(this, StackFrame::MANUAL); | |
4424 PushSafepointRegisters(); | |
4425 PrepareCallCFunction(1, a0); | |
4426 li(a0, Operand(ExternalReference::isolate_address(isolate()))); | |
4427 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | |
4428 PopSafepointRegisters(); | |
4429 } | |
4430 | |
4431 Label promote_scheduled_exception; | |
4432 Label exception_handled; | |
4433 Label delete_allocated_handles; | |
4434 Label leave_exit_frame; | |
4435 Label return_value_loaded; | |
4436 | |
4437 // Load value from ReturnValue. | |
4438 ld(v0, return_value_operand); | |
4439 bind(&return_value_loaded); | |
4440 | |
4441 // No more valid handles (the result handle was the last one). Restore | |
4442 // previous handle scope. | |
4443 sd(s0, MemOperand(s3, kNextOffset)); | |
4444 if (emit_debug_code()) { | |
4445 ld(a1, MemOperand(s3, kLevelOffset)); | |
4446 Check(eq, kUnexpectedLevelAfterReturnFromApiCall, a1, Operand(s2)); | |
4447 } | |
4448 Dsubu(s2, s2, Operand(1)); | |
4449 sd(s2, MemOperand(s3, kLevelOffset)); | |
4450 ld(at, MemOperand(s3, kLimitOffset)); | |
4451 Branch(&delete_allocated_handles, ne, s1, Operand(at)); | |
4452 | |
4453 // Check if the function scheduled an exception. | |
4454 bind(&leave_exit_frame); | |
4455 LoadRoot(a4, Heap::kTheHoleValueRootIndex); | |
4456 li(at, Operand(ExternalReference::scheduled_exception_address(isolate()))); | |
4457 ld(a5, MemOperand(at)); | |
4458 Branch(&promote_scheduled_exception, ne, a4, Operand(a5)); | |
4459 bind(&exception_handled); | |
4460 | |
4461 bool restore_context = context_restore_operand != NULL; | |
4462 if (restore_context) { | |
4463 ld(cp, *context_restore_operand); | |
4464 } | |
4465 if (stack_space_operand != NULL) { | |
4466 lw(s0, *stack_space_operand); | |
4467 } else { | |
4468 li(s0, Operand(stack_space)); | |
4469 } | |
4470 LeaveExitFrame(false, s0, !restore_context, EMIT_RETURN, | |
4471 stack_space_operand != NULL); | |
4472 bind(&promote_scheduled_exception); | |
4473 { | |
4474 FrameScope frame(this, StackFrame::INTERNAL); | |
4475 CallExternalReference( | |
4476 ExternalReference(Runtime::kPromoteScheduledException, isolate()), | |
4477 0); | |
4478 } | |
4479 jmp(&exception_handled); | |
4480 | |
4481 // HandleScope limit has changed. Delete allocated extensions. | |
4482 bind(&delete_allocated_handles); | |
4483 sd(s1, MemOperand(s3, kLimitOffset)); | |
4484 mov(s0, v0); | |
4485 mov(a0, v0); | |
4486 PrepareCallCFunction(1, s1); | |
4487 li(a0, Operand(ExternalReference::isolate_address(isolate()))); | |
4488 CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate()), | |
4489 1); | |
4490 mov(v0, s0); | |
4491 jmp(&leave_exit_frame); | |
4492 } | |
4493 | |
4494 | |
4495 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { | 4362 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
4496 return has_frame_ || !stub->SometimesSetsUpAFrame(); | 4363 return has_frame_ || !stub->SometimesSetsUpAFrame(); |
4497 } | 4364 } |
4498 | 4365 |
4499 | 4366 |
4500 void MacroAssembler::IndexFromHash(Register hash, Register index) { | 4367 void MacroAssembler::IndexFromHash(Register hash, Register index) { |
4501 // If the hash field contains an array index pick it out. The assert checks | 4368 // If the hash field contains an array index pick it out. The assert checks |
4502 // that the constants for the maximum number of digits for an array index | 4369 // that the constants for the maximum number of digits for an array index |
4503 // cached in the hash field and the number of bits reserved for it does not | 4370 // cached in the hash field and the number of bits reserved for it does not |
4504 // conflict. | 4371 // conflict. |
(...skipping 1816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6321 } | 6188 } |
6322 if (mag.shift > 0) sra(result, result, mag.shift); | 6189 if (mag.shift > 0) sra(result, result, mag.shift); |
6323 srl(at, dividend, 31); | 6190 srl(at, dividend, 31); |
6324 Addu(result, result, Operand(at)); | 6191 Addu(result, result, Operand(at)); |
6325 } | 6192 } |
6326 | 6193 |
6327 | 6194 |
6328 } } // namespace v8::internal | 6195 } } // namespace v8::internal |
6329 | 6196 |
6330 #endif // V8_TARGET_ARCH_MIPS64 | 6197 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |