OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2428 // rax: number of arguments including receiver | 2428 // rax: number of arguments including receiver |
2429 // rbx: pointer to C function (C callee-saved) | 2429 // rbx: pointer to C function (C callee-saved) |
2430 // rbp: frame pointer of calling JS frame (restored after C call) | 2430 // rbp: frame pointer of calling JS frame (restored after C call) |
2431 // rsp: stack pointer (restored after C call) | 2431 // rsp: stack pointer (restored after C call) |
2432 // rsi: current context (restored) | 2432 // rsi: current context (restored) |
2433 | 2433 |
2434 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2434 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2435 | 2435 |
2436 // Enter the exit frame that transitions from JavaScript to C++. | 2436 // Enter the exit frame that transitions from JavaScript to C++. |
2437 #ifdef _WIN64 | 2437 #ifdef _WIN64 |
2438 int arg_stack_space = (result_size_ < 2 ? 2 : 4); | 2438 int arg_stack_space = (result_size() < 2 ? 2 : 4); |
2439 #else | 2439 #else // _WIN64 |
2440 int arg_stack_space = 0; | 2440 int arg_stack_space = 0; |
2441 #endif | 2441 #endif // _WIN64 |
2442 __ EnterExitFrame(arg_stack_space, save_doubles_); | 2442 __ EnterExitFrame(arg_stack_space, save_doubles()); |
2443 | 2443 |
2444 // rbx: pointer to builtin function (C callee-saved). | 2444 // rbx: pointer to builtin function (C callee-saved). |
2445 // rbp: frame pointer of exit frame (restored after C call). | 2445 // rbp: frame pointer of exit frame (restored after C call). |
2446 // rsp: stack pointer (restored after C call). | 2446 // rsp: stack pointer (restored after C call). |
2447 // r14: number of arguments including receiver (C callee-saved). | 2447 // r14: number of arguments including receiver (C callee-saved). |
2448 // r15: argv pointer (C callee-saved). | 2448 // r15: argv pointer (C callee-saved). |
2449 | 2449 |
2450 // Simple results returned in rax (both AMD64 and Win64 calling conventions). | 2450 // Simple results returned in rax (both AMD64 and Win64 calling conventions). |
2451 // Complex results must be written to address passed as first argument. | 2451 // Complex results must be written to address passed as first argument. |
2452 // AMD64 calling convention: a struct of two pointers in rax+rdx | 2452 // AMD64 calling convention: a struct of two pointers in rax+rdx |
2453 | 2453 |
2454 // Check stack alignment. | 2454 // Check stack alignment. |
2455 if (FLAG_debug_code) { | 2455 if (FLAG_debug_code) { |
2456 __ CheckStackAlignment(); | 2456 __ CheckStackAlignment(); |
2457 } | 2457 } |
2458 | 2458 |
2459 // Call C function. | 2459 // Call C function. |
2460 #ifdef _WIN64 | 2460 #ifdef _WIN64 |
2461 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. | 2461 // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. |
2462 // Pass argv and argc as two parameters. The arguments object will | 2462 // Pass argv and argc as two parameters. The arguments object will |
2463 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). | 2463 // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). |
2464 if (result_size_ < 2) { | 2464 if (result_size() < 2) { |
2465 // Pass a pointer to the Arguments object as the first argument. | 2465 // Pass a pointer to the Arguments object as the first argument. |
2466 // Return result in single register (rax). | 2466 // Return result in single register (rax). |
2467 __ movp(rcx, r14); // argc. | 2467 __ movp(rcx, r14); // argc. |
2468 __ movp(rdx, r15); // argv. | 2468 __ movp(rdx, r15); // argv. |
2469 __ Move(r8, ExternalReference::isolate_address(isolate())); | 2469 __ Move(r8, ExternalReference::isolate_address(isolate())); |
2470 } else { | 2470 } else { |
2471 DCHECK_EQ(2, result_size_); | 2471 DCHECK_EQ(2, result_size()); |
2472 // Pass a pointer to the result location as the first argument. | 2472 // Pass a pointer to the result location as the first argument. |
2473 __ leap(rcx, StackSpaceOperand(2)); | 2473 __ leap(rcx, StackSpaceOperand(2)); |
2474 // Pass a pointer to the Arguments object as the second argument. | 2474 // Pass a pointer to the Arguments object as the second argument. |
2475 __ movp(rdx, r14); // argc. | 2475 __ movp(rdx, r14); // argc. |
2476 __ movp(r8, r15); // argv. | 2476 __ movp(r8, r15); // argv. |
2477 __ Move(r9, ExternalReference::isolate_address(isolate())); | 2477 __ Move(r9, ExternalReference::isolate_address(isolate())); |
2478 } | 2478 } |
2479 | 2479 |
2480 #else // _WIN64 | 2480 #else // _WIN64 |
2481 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. | 2481 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9. |
2482 __ movp(rdi, r14); // argc. | 2482 __ movp(rdi, r14); // argc. |
2483 __ movp(rsi, r15); // argv. | 2483 __ movp(rsi, r15); // argv. |
2484 __ Move(rdx, ExternalReference::isolate_address(isolate())); | 2484 __ Move(rdx, ExternalReference::isolate_address(isolate())); |
2485 #endif | 2485 #endif // _WIN64 |
2486 __ call(rbx); | 2486 __ call(rbx); |
2487 // Result is in rax - do not destroy this register! | 2487 // Result is in rax - do not destroy this register! |
2488 | 2488 |
2489 #ifdef _WIN64 | 2489 #ifdef _WIN64 |
2490 // If return value is on the stack, pop it to registers. | 2490 // If return value is on the stack, pop it to registers. |
2491 if (result_size_ > 1) { | 2491 if (result_size() > 1) { |
2492 DCHECK_EQ(2, result_size_); | 2492 DCHECK_EQ(2, result_size()); |
2493 // Read result values stored on stack. Result is stored | 2493 // Read result values stored on stack. Result is stored |
2494 // above the four argument mirror slots and the two | 2494 // above the four argument mirror slots and the two |
2495 // Arguments object slots. | 2495 // Arguments object slots. |
2496 __ movq(rax, Operand(rsp, 6 * kRegisterSize)); | 2496 __ movq(rax, Operand(rsp, 6 * kRegisterSize)); |
2497 __ movq(rdx, Operand(rsp, 7 * kRegisterSize)); | 2497 __ movq(rdx, Operand(rsp, 7 * kRegisterSize)); |
2498 } | 2498 } |
2499 #endif | 2499 #endif // _WIN64 |
2500 | 2500 |
2501 // Runtime functions should not return 'the hole'. Allowing it to escape may | 2501 // Runtime functions should not return 'the hole'. Allowing it to escape may |
2502 // lead to crashes in the IC code later. | 2502 // lead to crashes in the IC code later. |
2503 if (FLAG_debug_code) { | 2503 if (FLAG_debug_code) { |
2504 Label okay; | 2504 Label okay; |
2505 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); | 2505 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); |
2506 __ j(not_equal, &okay, Label::kNear); | 2506 __ j(not_equal, &okay, Label::kNear); |
2507 __ int3(); | 2507 __ int3(); |
2508 __ bind(&okay); | 2508 __ bind(&okay); |
2509 } | 2509 } |
(...skipping 13 matching lines...) Expand all Loading... |
2523 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); | 2523 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
2524 Operand pending_exception_operand = | 2524 Operand pending_exception_operand = |
2525 masm->ExternalOperand(pending_exception_address); | 2525 masm->ExternalOperand(pending_exception_address); |
2526 __ cmpp(r14, pending_exception_operand); | 2526 __ cmpp(r14, pending_exception_operand); |
2527 __ j(equal, &okay, Label::kNear); | 2527 __ j(equal, &okay, Label::kNear); |
2528 __ int3(); | 2528 __ int3(); |
2529 __ bind(&okay); | 2529 __ bind(&okay); |
2530 } | 2530 } |
2531 | 2531 |
2532 // Exit the JavaScript to C++ exit frame. | 2532 // Exit the JavaScript to C++ exit frame. |
2533 __ LeaveExitFrame(save_doubles_); | 2533 __ LeaveExitFrame(save_doubles()); |
2534 __ ret(0); | 2534 __ ret(0); |
2535 | 2535 |
2536 // Handling of exception. | 2536 // Handling of exception. |
2537 __ bind(&exception_returned); | 2537 __ bind(&exception_returned); |
2538 | 2538 |
2539 // Retrieve the pending exception. | 2539 // Retrieve the pending exception. |
2540 Operand pending_exception_operand = | 2540 Operand pending_exception_operand = |
2541 masm->ExternalOperand(pending_exception_address); | 2541 masm->ExternalOperand(pending_exception_address); |
2542 __ movp(rax, pending_exception_operand); | 2542 __ movp(rax, pending_exception_operand); |
2543 | 2543 |
(...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4976 return_value_operand, | 4976 return_value_operand, |
4977 NULL); | 4977 NULL); |
4978 } | 4978 } |
4979 | 4979 |
4980 | 4980 |
4981 #undef __ | 4981 #undef __ |
4982 | 4982 |
4983 } } // namespace v8::internal | 4983 } } // namespace v8::internal |
4984 | 4984 |
4985 #endif // V8_TARGET_ARCH_X64 | 4985 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |