| 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 |