Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 5108003: API call code refactoring (x64). (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 491
492 492
493 static int Offset(ExternalReference ref0, ExternalReference ref1) { 493 static int Offset(ExternalReference ref0, ExternalReference ref1) {
494 int64_t offset = (ref0.address() - ref1.address()); 494 int64_t offset = (ref0.address() - ref1.address());
495 // Check that fits into int. 495 // Check that fits into int.
496 ASSERT(static_cast<int>(offset) == offset); 496 ASSERT(static_cast<int>(offset) == offset);
497 return static_cast<int>(offset); 497 return static_cast<int>(offset);
498 } 498 }
499 499
500 500
501 void MacroAssembler::PrepareCallApiFunction(int stack_space, 501 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
502 int arg_stack_space) {
503 #ifdef _WIN64 502 #ifdef _WIN64
504 // We need to prepare a slot for result handle on stack and put 503 // We need to prepare a slot for result handle on stack and put
505 // a pointer to it into 1st arg register. 504 // a pointer to it into 1st arg register.
506 EnterApiExitFrame(stack_space, arg_stack_space + 1); 505 EnterApiExitFrame(arg_stack_space + 1);
507 506
508 // rcx must be used to pass the pointer to the return value slot. 507 // rcx must be used to pass the pointer to the return value slot.
509 lea(rcx, StackSpaceOperand(arg_stack_space)); 508 lea(rcx, StackSpaceOperand(arg_stack_space));
510 #else 509 #else
511 EnterApiExitFrame(stack_space, arg_stack_space); 510 EnterApiExitFrame(arg_stack_space);
512 #endif 511 #endif
513 } 512 }
514 513
515 514
516 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( 515 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
517 ApiFunction* function) { 516 ApiFunction* function, int stack_space) {
518 Label empty_result; 517 Label empty_result;
519 Label prologue; 518 Label prologue;
520 Label promote_scheduled_exception; 519 Label promote_scheduled_exception;
521 Label delete_allocated_handles; 520 Label delete_allocated_handles;
522 Label leave_exit_frame; 521 Label leave_exit_frame;
523 Label write_back; 522 Label write_back;
524 523
525 ExternalReference next_address = 524 ExternalReference next_address =
526 ExternalReference::handle_scope_next_address(); 525 ExternalReference::handle_scope_next_address();
527 const int kNextOffset = 0; 526 const int kNextOffset = 0;
528 const int kLimitOffset = Offset( 527 const int kLimitOffset = Offset(
529 ExternalReference::handle_scope_limit_address(), 528 ExternalReference::handle_scope_limit_address(),
530 next_address); 529 next_address);
531 const int kLevelOffset = Offset( 530 const int kLevelOffset = Offset(
532 ExternalReference::handle_scope_level_address(), 531 ExternalReference::handle_scope_level_address(),
533 next_address); 532 next_address);
534 ExternalReference scheduled_exception_address = 533 ExternalReference scheduled_exception_address =
535 ExternalReference::scheduled_exception_address(); 534 ExternalReference::scheduled_exception_address();
536 535
537 // Allocate HandleScope in callee-save registers. 536 // Allocate HandleScope in callee-save registers.
538 Register prev_next_address_reg = r14; 537 Register prev_next_address_reg = r14;
539 Register prev_limit_reg = rbx; 538 Register prev_limit_reg = rbx;
540 Register base_reg = kSmiConstantRegister; 539 Register base_reg = r12;
541 movq(base_reg, next_address); 540 movq(base_reg, next_address);
542 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); 541 movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
543 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 542 movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
544 addl(Operand(base_reg, kLevelOffset), Immediate(1)); 543 addl(Operand(base_reg, kLevelOffset), Immediate(1));
545 // Call the api function! 544 // Call the api function!
546 movq(rax, 545 movq(rax,
547 reinterpret_cast<int64_t>(function->address()), 546 reinterpret_cast<int64_t>(function->address()),
548 RelocInfo::RUNTIME_ENTRY); 547 RelocInfo::RUNTIME_ENTRY);
549 call(rax); 548 call(rax);
550 549
551 #ifdef _WIN64 550 #ifdef _WIN64
552 // rax keeps a pointer to v8::Handle, unpack it. 551 // rax keeps a pointer to v8::Handle, unpack it.
553 movq(rax, Operand(rax, 0)); 552 movq(rax, Operand(rax, 0));
554 #endif 553 #endif
555 // Check if the result handle holds 0. 554 // Check if the result handle holds 0.
556 testq(rax, rax); 555 testq(rax, rax);
557 j(zero, &empty_result); 556 j(zero, &empty_result);
558 // It was non-zero. Dereference to get the result value. 557 // It was non-zero. Dereference to get the result value.
559 movq(rax, Operand(rax, 0)); 558 movq(rax, Operand(rax, 0));
560 bind(&prologue); 559 bind(&prologue);
561 560
562 // No more valid handles (the result handle was the last one). Restore 561 // No more valid handles (the result handle was the last one). Restore
563 // previous handle scope. 562 // previous handle scope.
564 subl(Operand(base_reg, kLevelOffset), Immediate(1)); 563 subl(Operand(base_reg, kLevelOffset), Immediate(1));
565 movq(Operand(base_reg, kNextOffset), prev_next_address_reg); 564 movq(Operand(base_reg, kNextOffset), prev_next_address_reg);
566 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 565 cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset));
567 j(not_equal, &delete_allocated_handles); 566 j(not_equal, &delete_allocated_handles);
568 bind(&leave_exit_frame); 567 bind(&leave_exit_frame);
569 InitializeSmiConstantRegister();
570 568
571 // Check if the function scheduled an exception. 569 // Check if the function scheduled an exception.
572 movq(rsi, scheduled_exception_address); 570 movq(rsi, scheduled_exception_address);
573 Cmp(Operand(rsi, 0), Factory::the_hole_value()); 571 Cmp(Operand(rsi, 0), Factory::the_hole_value());
574 j(not_equal, &promote_scheduled_exception); 572 j(not_equal, &promote_scheduled_exception);
575 573
576 LeaveExitFrame(); 574 LeaveApiExitFrame();
577 ret(0); 575 ret(stack_space * kPointerSize);
578 576
579 bind(&promote_scheduled_exception); 577 bind(&promote_scheduled_exception);
580 MaybeObject* result = TryTailCallRuntime(Runtime::kPromoteScheduledException, 578 MaybeObject* result = TryTailCallRuntime(Runtime::kPromoteScheduledException,
581 0, 1); 579 0, 1);
582 if (result->IsFailure()) { 580 if (result->IsFailure()) {
583 return result; 581 return result;
584 } 582 }
585 583
586 bind(&empty_result); 584 bind(&empty_result);
587 // It was zero; the result is undefined. 585 // It was zero; the result is undefined.
(...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 1769
1772 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, 1770 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
1773 // so it must be retained across the C-call. 1771 // so it must be retained across the C-call.
1774 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 1772 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
1775 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); 1773 lea(r12, Operand(rbp, r14, times_pointer_size, offset));
1776 1774
1777 EnterExitFrameEpilogue(arg_stack_space); 1775 EnterExitFrameEpilogue(arg_stack_space);
1778 } 1776 }
1779 1777
1780 1778
1781 void MacroAssembler::EnterApiExitFrame(int stack_space, 1779 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
1782 int arg_stack_space) {
1783 EnterExitFramePrologue(false); 1780 EnterExitFramePrologue(false);
1784
1785 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
1786 // so it must be retained across the C-call.
1787 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
1788 lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset));
1789
1790 EnterExitFrameEpilogue(arg_stack_space); 1781 EnterExitFrameEpilogue(arg_stack_space);
1791 } 1782 }
1792 1783
1793 1784
1794 void MacroAssembler::LeaveExitFrame(int result_size) { 1785 void MacroAssembler::LeaveExitFrame() {
1795 // Registers: 1786 // Registers:
1796 // r12 : argv 1787 // r12 : argv
1797 1788
1798 // Get the return address from the stack and restore the frame pointer. 1789 // Get the return address from the stack and restore the frame pointer.
1799 movq(rcx, Operand(rbp, 1 * kPointerSize)); 1790 movq(rcx, Operand(rbp, 1 * kPointerSize));
1800 movq(rbp, Operand(rbp, 0 * kPointerSize)); 1791 movq(rbp, Operand(rbp, 0 * kPointerSize));
1801 1792
1802 // Pop everything up to and including the arguments and the receiver 1793 // Pop everything up to and including the arguments and the receiver
1803 // from the caller stack. 1794 // from the caller stack.
1804 lea(rsp, Operand(r12, 1 * kPointerSize)); 1795 lea(rsp, Operand(r12, 1 * kPointerSize));
1805 1796
1797 // Push the return address to get ready to return.
1798 push(rcx);
1799
1800 LeaveExitFrameEpilogue();
1801 }
1802
1803
1804 void MacroAssembler::LeaveApiExitFrame() {
1805 movq(rsp, rbp);
1806 pop(rbp);
1807
1808 LeaveExitFrameEpilogue();
1809 }
1810
1811
1812 void MacroAssembler::LeaveExitFrameEpilogue() {
1806 // Restore current context from top and clear it in debug mode. 1813 // Restore current context from top and clear it in debug mode.
1807 ExternalReference context_address(Top::k_context_address); 1814 ExternalReference context_address(Top::k_context_address);
1808 movq(kScratchRegister, context_address); 1815 movq(kScratchRegister, context_address);
1809 movq(rsi, Operand(kScratchRegister, 0)); 1816 movq(rsi, Operand(kScratchRegister, 0));
1810 #ifdef DEBUG 1817 #ifdef DEBUG
1811 movq(Operand(kScratchRegister, 0), Immediate(0)); 1818 movq(Operand(kScratchRegister, 0), Immediate(0));
1812 #endif 1819 #endif
1813 1820
1814 // Push the return address to get ready to return.
1815 push(rcx);
1816
1817 // Clear the top frame. 1821 // Clear the top frame.
1818 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); 1822 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
1819 movq(kScratchRegister, c_entry_fp_address); 1823 movq(kScratchRegister, c_entry_fp_address);
1820 movq(Operand(kScratchRegister, 0), Immediate(0)); 1824 movq(Operand(kScratchRegister, 0), Immediate(0));
1821 } 1825 }
1822 1826
1823 1827
1824 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 1828 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
1825 Register scratch, 1829 Register scratch,
1826 Label* miss) { 1830 Label* miss) {
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 CPU::FlushICache(address_, size_); 2329 CPU::FlushICache(address_, size_);
2326 2330
2327 // Check that the code was patched as expected. 2331 // Check that the code was patched as expected.
2328 ASSERT(masm_.pc_ == address_ + size_); 2332 ASSERT(masm_.pc_ == address_ + size_);
2329 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2333 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2330 } 2334 }
2331 2335
2332 } } // namespace v8::internal 2336 } } // namespace v8::internal
2333 2337
2334 #endif // V8_TARGET_ARCH_X64 2338 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698