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_ARM | 9 #if V8_TARGET_ARCH_ARM |
10 | 10 |
(...skipping 2343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2354 DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. | 2354 DCHECK(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. |
2355 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); | 2355 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond); |
2356 } | 2356 } |
2357 | 2357 |
2358 | 2358 |
2359 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { | 2359 void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) { |
2360 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); | 2360 Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); |
2361 } | 2361 } |
2362 | 2362 |
2363 | 2363 |
2364 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | |
2365 return ref0.address() - ref1.address(); | |
2366 } | |
2367 | |
2368 | |
2369 void MacroAssembler::CallApiFunctionAndReturn( | |
2370 Register function_address, ExternalReference thunk_ref, int stack_space, | |
2371 MemOperand* stack_space_operand, MemOperand return_value_operand, | |
2372 MemOperand* context_restore_operand) { | |
2373 ExternalReference next_address = | |
2374 ExternalReference::handle_scope_next_address(isolate()); | |
2375 const int kNextOffset = 0; | |
2376 const int kLimitOffset = AddressOffset( | |
2377 ExternalReference::handle_scope_limit_address(isolate()), | |
2378 next_address); | |
2379 const int kLevelOffset = AddressOffset( | |
2380 ExternalReference::handle_scope_level_address(isolate()), | |
2381 next_address); | |
2382 | |
2383 DCHECK(function_address.is(r1) || function_address.is(r2)); | |
2384 | |
2385 Label profiler_disabled; | |
2386 Label end_profiler_check; | |
2387 mov(r9, Operand(ExternalReference::is_profiling_address(isolate()))); | |
2388 ldrb(r9, MemOperand(r9, 0)); | |
2389 cmp(r9, Operand(0)); | |
2390 b(eq, &profiler_disabled); | |
2391 | |
2392 // Additional parameter is the address of the actual callback. | |
2393 mov(r3, Operand(thunk_ref)); | |
2394 jmp(&end_profiler_check); | |
2395 | |
2396 bind(&profiler_disabled); | |
2397 Move(r3, function_address); | |
2398 bind(&end_profiler_check); | |
2399 | |
2400 // Allocate HandleScope in callee-save registers. | |
2401 mov(r9, Operand(next_address)); | |
2402 ldr(r4, MemOperand(r9, kNextOffset)); | |
2403 ldr(r5, MemOperand(r9, kLimitOffset)); | |
2404 ldr(r6, MemOperand(r9, kLevelOffset)); | |
2405 add(r6, r6, Operand(1)); | |
2406 str(r6, MemOperand(r9, kLevelOffset)); | |
2407 | |
2408 if (FLAG_log_timer_events) { | |
2409 FrameScope frame(this, StackFrame::MANUAL); | |
2410 PushSafepointRegisters(); | |
2411 PrepareCallCFunction(1, r0); | |
2412 mov(r0, Operand(ExternalReference::isolate_address(isolate()))); | |
2413 CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); | |
2414 PopSafepointRegisters(); | |
2415 } | |
2416 | |
2417 // Native call returns to the DirectCEntry stub which redirects to the | |
2418 // return address pushed on stack (could have moved after GC). | |
2419 // DirectCEntry stub itself is generated early and never moves. | |
2420 DirectCEntryStub stub(isolate()); | |
2421 stub.GenerateCall(this, r3); | |
2422 | |
2423 if (FLAG_log_timer_events) { | |
2424 FrameScope frame(this, StackFrame::MANUAL); | |
2425 PushSafepointRegisters(); | |
2426 PrepareCallCFunction(1, r0); | |
2427 mov(r0, Operand(ExternalReference::isolate_address(isolate()))); | |
2428 CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); | |
2429 PopSafepointRegisters(); | |
2430 } | |
2431 | |
2432 Label promote_scheduled_exception; | |
2433 Label exception_handled; | |
2434 Label delete_allocated_handles; | |
2435 Label leave_exit_frame; | |
2436 Label return_value_loaded; | |
2437 | |
2438 // load value from ReturnValue | |
2439 ldr(r0, return_value_operand); | |
2440 bind(&return_value_loaded); | |
2441 // No more valid handles (the result handle was the last one). Restore | |
2442 // previous handle scope. | |
2443 str(r4, MemOperand(r9, kNextOffset)); | |
2444 if (emit_debug_code()) { | |
2445 ldr(r1, MemOperand(r9, kLevelOffset)); | |
2446 cmp(r1, r6); | |
2447 Check(eq, kUnexpectedLevelAfterReturnFromApiCall); | |
2448 } | |
2449 sub(r6, r6, Operand(1)); | |
2450 str(r6, MemOperand(r9, kLevelOffset)); | |
2451 ldr(ip, MemOperand(r9, kLimitOffset)); | |
2452 cmp(r5, ip); | |
2453 b(ne, &delete_allocated_handles); | |
2454 | |
2455 // Check if the function scheduled an exception. | |
2456 bind(&leave_exit_frame); | |
2457 LoadRoot(r4, Heap::kTheHoleValueRootIndex); | |
2458 mov(ip, Operand(ExternalReference::scheduled_exception_address(isolate()))); | |
2459 ldr(r5, MemOperand(ip)); | |
2460 cmp(r4, r5); | |
2461 b(ne, &promote_scheduled_exception); | |
2462 bind(&exception_handled); | |
2463 | |
2464 bool restore_context = context_restore_operand != NULL; | |
2465 if (restore_context) { | |
2466 ldr(cp, *context_restore_operand); | |
2467 } | |
2468 // LeaveExitFrame expects unwind space to be in a register. | |
2469 if (stack_space_operand != NULL) { | |
2470 ldr(r4, *stack_space_operand); | |
2471 } else { | |
2472 mov(r4, Operand(stack_space)); | |
2473 } | |
2474 LeaveExitFrame(false, r4, !restore_context, stack_space_operand != NULL); | |
2475 mov(pc, lr); | |
2476 | |
2477 bind(&promote_scheduled_exception); | |
2478 { | |
2479 FrameScope frame(this, StackFrame::INTERNAL); | |
2480 CallExternalReference( | |
2481 ExternalReference(Runtime::kPromoteScheduledException, isolate()), | |
2482 0); | |
2483 } | |
2484 jmp(&exception_handled); | |
2485 | |
2486 // HandleScope limit has changed. Delete allocated extensions. | |
2487 bind(&delete_allocated_handles); | |
2488 str(r5, MemOperand(r9, kLimitOffset)); | |
2489 mov(r4, r0); | |
2490 PrepareCallCFunction(1, r5); | |
2491 mov(r0, Operand(ExternalReference::isolate_address(isolate()))); | |
2492 CallCFunction( | |
2493 ExternalReference::delete_handle_scope_extensions(isolate()), 1); | |
2494 mov(r0, r4); | |
2495 jmp(&leave_exit_frame); | |
2496 } | |
2497 | |
2498 | |
2499 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { | 2364 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { |
2500 return has_frame_ || !stub->SometimesSetsUpAFrame(); | 2365 return has_frame_ || !stub->SometimesSetsUpAFrame(); |
2501 } | 2366 } |
2502 | 2367 |
2503 | 2368 |
2504 void MacroAssembler::IndexFromHash(Register hash, Register index) { | 2369 void MacroAssembler::IndexFromHash(Register hash, Register index) { |
2505 // If the hash field contains an array index pick it out. The assert checks | 2370 // If the hash field contains an array index pick it out. The assert checks |
2506 // that the constants for the maximum number of digits for an array index | 2371 // that the constants for the maximum number of digits for an array index |
2507 // cached in the hash field and the number of bits reserved for it does not | 2372 // cached in the hash field and the number of bits reserved for it does not |
2508 // conflict. | 2373 // conflict. |
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4092 } | 3957 } |
4093 } | 3958 } |
4094 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3959 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
4095 add(result, result, Operand(dividend, LSR, 31)); | 3960 add(result, result, Operand(dividend, LSR, 31)); |
4096 } | 3961 } |
4097 | 3962 |
4098 } // namespace internal | 3963 } // namespace internal |
4099 } // namespace v8 | 3964 } // namespace v8 |
4100 | 3965 |
4101 #endif // V8_TARGET_ARCH_ARM | 3966 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |