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