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

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

Issue 8391045: Handlify the remaining CallStubCompiler functions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 int3(); 523 int3();
524 } 524 }
525 525
526 526
527 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) { 527 void MacroAssembler::CallStub(CodeStub* stub, unsigned ast_id) {
528 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 528 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs
529 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 529 Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
530 } 530 }
531 531
532 532
533 MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub) {
534 ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs.
535 MaybeObject* result = stub->TryGetCode();
536 if (!result->IsFailure()) {
537 call(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
538 RelocInfo::CODE_TARGET);
539 }
540 return result;
541 }
542
543
544 void MacroAssembler::TailCallStub(CodeStub* stub) { 533 void MacroAssembler::TailCallStub(CodeStub* stub) {
545 ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe()); 534 ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe());
546 Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 535 Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
547 } 536 }
548 537
549 538
550 MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub) {
551 MaybeObject* result = stub->TryGetCode();
552 if (!result->IsFailure()) {
553 jmp(Handle<Code>(Code::cast(result->ToObjectUnchecked())),
554 RelocInfo::CODE_TARGET);
555 }
556 return result;
557 }
558
559
560 void MacroAssembler::StubReturn(int argc) { 539 void MacroAssembler::StubReturn(int argc) {
561 ASSERT(argc >= 1 && generating_stub()); 540 ASSERT(argc >= 1 && generating_stub());
562 ret((argc - 1) * kPointerSize); 541 ret((argc - 1) * kPointerSize);
563 } 542 }
564 543
565 544
566 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 545 bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
567 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false; 546 if (!has_frame_ && stub->SometimesSetsUpAFrame()) return false;
568 return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe(); 547 return allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe();
569 } 548 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 582
604 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { 583 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
605 const Runtime::Function* function = Runtime::FunctionForId(id); 584 const Runtime::Function* function = Runtime::FunctionForId(id);
606 Set(rax, function->nargs); 585 Set(rax, function->nargs);
607 LoadAddress(rbx, ExternalReference(function, isolate())); 586 LoadAddress(rbx, ExternalReference(function, isolate()));
608 CEntryStub ces(1, kSaveFPRegs); 587 CEntryStub ces(1, kSaveFPRegs);
609 CallStub(&ces); 588 CallStub(&ces);
610 } 589 }
611 590
612 591
613 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
614 int num_arguments) {
615 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
616 }
617
618
619 void MacroAssembler::CallRuntime(const Runtime::Function* f, 592 void MacroAssembler::CallRuntime(const Runtime::Function* f,
620 int num_arguments) { 593 int num_arguments) {
621 // If the expected number of arguments of the runtime function is 594 // If the expected number of arguments of the runtime function is
622 // constant, we check that the actual number of arguments match the 595 // constant, we check that the actual number of arguments match the
623 // expectation. 596 // expectation.
624 if (f->nargs >= 0 && f->nargs != num_arguments) { 597 if (f->nargs >= 0 && f->nargs != num_arguments) {
625 IllegalOperation(num_arguments); 598 IllegalOperation(num_arguments);
626 return; 599 return;
627 } 600 }
628 601
629 // TODO(1236192): Most runtime routines don't need the number of 602 // TODO(1236192): Most runtime routines don't need the number of
630 // arguments passed in because it is constant. At some point we 603 // arguments passed in because it is constant. At some point we
631 // should remove this need and make the runtime routine entry code 604 // should remove this need and make the runtime routine entry code
632 // smarter. 605 // smarter.
633 Set(rax, num_arguments); 606 Set(rax, num_arguments);
634 LoadAddress(rbx, ExternalReference(f, isolate())); 607 LoadAddress(rbx, ExternalReference(f, isolate()));
635 CEntryStub ces(f->result_size); 608 CEntryStub ces(f->result_size);
636 CallStub(&ces); 609 CallStub(&ces);
637 } 610 }
638 611
639 612
640 MaybeObject* MacroAssembler::TryCallRuntime(const Runtime::Function* f,
641 int num_arguments) {
642 if (f->nargs >= 0 && f->nargs != num_arguments) {
643 IllegalOperation(num_arguments);
644 // Since we did not call the stub, there was no allocation failure.
645 // Return some non-failure object.
646 return HEAP->undefined_value();
647 }
648
649 // TODO(1236192): Most runtime routines don't need the number of
650 // arguments passed in because it is constant. At some point we
651 // should remove this need and make the runtime routine entry code
652 // smarter.
653 Set(rax, num_arguments);
654 LoadAddress(rbx, ExternalReference(f, isolate()));
655 CEntryStub ces(f->result_size);
656 return TryCallStub(&ces);
657 }
658
659
660 void MacroAssembler::CallExternalReference(const ExternalReference& ext, 613 void MacroAssembler::CallExternalReference(const ExternalReference& ext,
661 int num_arguments) { 614 int num_arguments) {
662 Set(rax, num_arguments); 615 Set(rax, num_arguments);
663 LoadAddress(rbx, ext); 616 LoadAddress(rbx, ext);
664 617
665 CEntryStub stub(1); 618 CEntryStub stub(1);
666 CallStub(&stub); 619 CallStub(&stub);
667 } 620 }
668 621
669 622
670 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 623 void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
671 int num_arguments, 624 int num_arguments,
672 int result_size) { 625 int result_size) {
673 // ----------- S t a t e ------------- 626 // ----------- S t a t e -------------
674 // -- rsp[0] : return address 627 // -- rsp[0] : return address
675 // -- rsp[8] : argument num_arguments - 1 628 // -- rsp[8] : argument num_arguments - 1
676 // ... 629 // ...
677 // -- rsp[8 * num_arguments] : argument 0 (receiver) 630 // -- rsp[8 * num_arguments] : argument 0 (receiver)
678 // ----------------------------------- 631 // -----------------------------------
679 632
680 // TODO(1236192): Most runtime routines don't need the number of 633 // TODO(1236192): Most runtime routines don't need the number of
681 // arguments passed in because it is constant. At some point we 634 // arguments passed in because it is constant. At some point we
682 // should remove this need and make the runtime routine entry code 635 // should remove this need and make the runtime routine entry code
683 // smarter. 636 // smarter.
684 Set(rax, num_arguments); 637 Set(rax, num_arguments);
685 JumpToExternalReference(ext, result_size); 638 JumpToExternalReference(ext, result_size);
686 } 639 }
687 640
688 641
689 MaybeObject* MacroAssembler::TryTailCallExternalReference(
690 const ExternalReference& ext, int num_arguments, int result_size) {
691 // ----------- S t a t e -------------
692 // -- rsp[0] : return address
693 // -- rsp[8] : argument num_arguments - 1
694 // ...
695 // -- rsp[8 * num_arguments] : argument 0 (receiver)
696 // -----------------------------------
697
698 // TODO(1236192): Most runtime routines don't need the number of
699 // arguments passed in because it is constant. At some point we
700 // should remove this need and make the runtime routine entry code
701 // smarter.
702 Set(rax, num_arguments);
703 return TryJumpToExternalReference(ext, result_size);
704 }
705
706
707 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 642 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
708 int num_arguments, 643 int num_arguments,
709 int result_size) { 644 int result_size) {
710 TailCallExternalReference(ExternalReference(fid, isolate()), 645 TailCallExternalReference(ExternalReference(fid, isolate()),
711 num_arguments, 646 num_arguments,
712 result_size); 647 result_size);
713 } 648 }
714 649
715 650
716 MaybeObject* MacroAssembler::TryTailCallRuntime(Runtime::FunctionId fid,
717 int num_arguments,
718 int result_size) {
719 return TryTailCallExternalReference(ExternalReference(fid, isolate()),
720 num_arguments,
721 result_size);
722 }
723
724
725 static int Offset(ExternalReference ref0, ExternalReference ref1) { 651 static int Offset(ExternalReference ref0, ExternalReference ref1) {
726 int64_t offset = (ref0.address() - ref1.address()); 652 int64_t offset = (ref0.address() - ref1.address());
727 // Check that fits into int. 653 // Check that fits into int.
728 ASSERT(static_cast<int>(offset) == offset); 654 ASSERT(static_cast<int>(offset) == offset);
729 return static_cast<int>(offset); 655 return static_cast<int>(offset);
730 } 656 }
731 657
732 658
733 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { 659 void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
734 #ifdef _WIN64 660 #ifdef _WIN64
735 // We need to prepare a slot for result handle on stack and put 661 // We need to prepare a slot for result handle on stack and put
736 // a pointer to it into 1st arg register. 662 // a pointer to it into 1st arg register.
737 EnterApiExitFrame(arg_stack_space + 1); 663 EnterApiExitFrame(arg_stack_space + 1);
738 664
739 // rcx must be used to pass the pointer to the return value slot. 665 // rcx must be used to pass the pointer to the return value slot.
740 lea(rcx, StackSpaceOperand(arg_stack_space)); 666 lea(rcx, StackSpaceOperand(arg_stack_space));
741 #else 667 #else
742 EnterApiExitFrame(arg_stack_space); 668 EnterApiExitFrame(arg_stack_space);
743 #endif 669 #endif
744 } 670 }
745 671
746 672
747 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( 673 void MacroAssembler::CallApiFunctionAndReturn(Address function_address,
748 ApiFunction* function, int stack_space) { 674 int stack_space) {
749 Label empty_result; 675 Label empty_result;
750 Label prologue; 676 Label prologue;
751 Label promote_scheduled_exception; 677 Label promote_scheduled_exception;
752 Label delete_allocated_handles; 678 Label delete_allocated_handles;
753 Label leave_exit_frame; 679 Label leave_exit_frame;
754 Label write_back; 680 Label write_back;
755 681
756 Factory* factory = isolate()->factory(); 682 Factory* factory = isolate()->factory();
757 ExternalReference next_address = 683 ExternalReference next_address =
758 ExternalReference::handle_scope_next_address(); 684 ExternalReference::handle_scope_next_address();
759 const int kNextOffset = 0; 685 const int kNextOffset = 0;
760 const int kLimitOffset = Offset( 686 const int kLimitOffset = Offset(
761 ExternalReference::handle_scope_limit_address(), 687 ExternalReference::handle_scope_limit_address(),
762 next_address); 688 next_address);
763 const int kLevelOffset = Offset( 689 const int kLevelOffset = Offset(
764 ExternalReference::handle_scope_level_address(), 690 ExternalReference::handle_scope_level_address(),
765 next_address); 691 next_address);
766 ExternalReference scheduled_exception_address = 692 ExternalReference scheduled_exception_address =
767 ExternalReference::scheduled_exception_address(isolate()); 693 ExternalReference::scheduled_exception_address(isolate());
768 694
769 // Allocate HandleScope in callee-save registers. 695 // Allocate HandleScope in callee-save registers.
770 Register prev_next_address_reg = r14; 696 Register prev_next_address_reg = r14;
771 Register prev_limit_reg = rbx; 697 Register prev_limit_reg = rbx;
772 Register base_reg = r15; 698 Register base_reg = r15;
773 movq(base_reg, next_address); 699 movq(base_reg, next_address);
774 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); 700 movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
775 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 701 movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
776 addl(Operand(base_reg, kLevelOffset), Immediate(1)); 702 addl(Operand(base_reg, kLevelOffset), Immediate(1));
777 // Call the api function! 703 // Call the api function!
778 movq(rax, 704 movq(rax, reinterpret_cast<int64_t>(function_address),
779 reinterpret_cast<int64_t>(function->address()),
780 RelocInfo::RUNTIME_ENTRY); 705 RelocInfo::RUNTIME_ENTRY);
781 call(rax); 706 call(rax);
782 707
783 #ifdef _WIN64 708 #ifdef _WIN64
784 // rax keeps a pointer to v8::Handle, unpack it. 709 // rax keeps a pointer to v8::Handle, unpack it.
785 movq(rax, Operand(rax, 0)); 710 movq(rax, Operand(rax, 0));
786 #endif 711 #endif
787 // Check if the result handle holds 0. 712 // Check if the result handle holds 0.
788 testq(rax, rax); 713 testq(rax, rax);
789 j(zero, &empty_result); 714 j(zero, &empty_result);
(...skipping 11 matching lines...) Expand all
801 726
802 // Check if the function scheduled an exception. 727 // Check if the function scheduled an exception.
803 movq(rsi, scheduled_exception_address); 728 movq(rsi, scheduled_exception_address);
804 Cmp(Operand(rsi, 0), factory->the_hole_value()); 729 Cmp(Operand(rsi, 0), factory->the_hole_value());
805 j(not_equal, &promote_scheduled_exception); 730 j(not_equal, &promote_scheduled_exception);
806 731
807 LeaveApiExitFrame(); 732 LeaveApiExitFrame();
808 ret(stack_space * kPointerSize); 733 ret(stack_space * kPointerSize);
809 734
810 bind(&promote_scheduled_exception); 735 bind(&promote_scheduled_exception);
811 MaybeObject* result = TryTailCallRuntime(Runtime::kPromoteScheduledException, 736 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
812 0, 1);
813 if (result->IsFailure()) {
814 return result;
815 }
816 737
817 bind(&empty_result); 738 bind(&empty_result);
818 // It was zero; the result is undefined. 739 // It was zero; the result is undefined.
819 Move(rax, factory->undefined_value()); 740 Move(rax, factory->undefined_value());
820 jmp(&prologue); 741 jmp(&prologue);
821 742
822 // HandleScope limit has changed. Delete allocated extensions. 743 // HandleScope limit has changed. Delete allocated extensions.
823 bind(&delete_allocated_handles); 744 bind(&delete_allocated_handles);
824 movq(Operand(base_reg, kLimitOffset), prev_limit_reg); 745 movq(Operand(base_reg, kLimitOffset), prev_limit_reg);
825 movq(prev_limit_reg, rax); 746 movq(prev_limit_reg, rax);
826 #ifdef _WIN64 747 #ifdef _WIN64
827 LoadAddress(rcx, ExternalReference::isolate_address()); 748 LoadAddress(rcx, ExternalReference::isolate_address());
828 #else 749 #else
829 LoadAddress(rdi, ExternalReference::isolate_address()); 750 LoadAddress(rdi, ExternalReference::isolate_address());
830 #endif 751 #endif
831 LoadAddress(rax, 752 LoadAddress(rax,
832 ExternalReference::delete_handle_scope_extensions(isolate())); 753 ExternalReference::delete_handle_scope_extensions(isolate()));
833 call(rax); 754 call(rax);
834 movq(rax, prev_limit_reg); 755 movq(rax, prev_limit_reg);
835 jmp(&leave_exit_frame); 756 jmp(&leave_exit_frame);
836
837 return result;
838 } 757 }
839 758
840 759
841 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 760 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
842 int result_size) { 761 int result_size) {
843 // Set the entry point and jump to the C entry runtime stub. 762 // Set the entry point and jump to the C entry runtime stub.
844 LoadAddress(rbx, ext); 763 LoadAddress(rbx, ext);
845 CEntryStub ces(result_size); 764 CEntryStub ces(result_size);
846 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 765 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
847 } 766 }
848 767
849 768
850 MaybeObject* MacroAssembler::TryJumpToExternalReference(
851 const ExternalReference& ext, int result_size) {
852 // Set the entry point and jump to the C entry runtime stub.
853 LoadAddress(rbx, ext);
854 CEntryStub ces(result_size);
855 return TryTailCallStub(&ces);
856 }
857
858
859 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 769 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
860 InvokeFlag flag, 770 InvokeFlag flag,
861 const CallWrapper& call_wrapper) { 771 const CallWrapper& call_wrapper) {
862 // You can't call a builtin without a valid frame. 772 // You can't call a builtin without a valid frame.
863 ASSERT(flag == JUMP_FUNCTION || has_frame()); 773 ASSERT(flag == JUMP_FUNCTION || has_frame());
864 774
865 // Rely on the assertion to check that the number of provided 775 // Rely on the assertion to check that the number of provided
866 // arguments match the expected number of arguments. Fake a 776 // arguments match the expected number of arguments. Fake a
867 // parameter count to avoid emitting code to do the check. 777 // parameter count to avoid emitting code to do the check.
868 ParameterCount expected(0); 778 ParameterCount expected(0);
(...skipping 2236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3105 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); 3015 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
3106 // Advances rdx to the end of the Code object header, to the start of 3016 // Advances rdx to the end of the Code object header, to the start of
3107 // the executable code. 3017 // the executable code.
3108 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3018 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3109 3019
3110 ParameterCount expected(rbx); 3020 ParameterCount expected(rbx);
3111 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 3021 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
3112 } 3022 }
3113 3023
3114 3024
3115 void MacroAssembler::InvokeFunction(JSFunction* function, 3025 void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
3116 const ParameterCount& actual, 3026 const ParameterCount& actual,
3117 InvokeFlag flag, 3027 InvokeFlag flag,
3118 const CallWrapper& call_wrapper, 3028 const CallWrapper& call_wrapper,
3119 CallKind call_kind) { 3029 CallKind call_kind) {
3120 // You can't call a function without a valid frame. 3030 // You can't call a function without a valid frame.
3121 ASSERT(flag == JUMP_FUNCTION || has_frame()); 3031 ASSERT(flag == JUMP_FUNCTION || has_frame());
3122 3032
3123 // Get the function and setup the context. 3033 // Get the function and setup the context.
3124 Move(rdi, Handle<JSFunction>(function)); 3034 Move(rdi, function);
3125 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 3035 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
3126 3036
3127 // We call indirectly through the code field in the function to 3037 // We call indirectly through the code field in the function to
3128 // allow recompilation to take effect without changing any of the 3038 // allow recompilation to take effect without changing any of the
3129 // call sites. 3039 // call sites.
3130 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3040 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
3131 ParameterCount expected(function->shared()->formal_parameter_count()); 3041 ParameterCount expected(function->shared()->formal_parameter_count());
3132 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 3042 InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind);
3133 } 3043 }
3134 3044
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
4314 4224
4315 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4225 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
4316 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4226 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
4317 4227
4318 bind(&done); 4228 bind(&done);
4319 } 4229 }
4320 4230
4321 } } // namespace v8::internal 4231 } } // namespace v8::internal
4322 4232
4323 #endif // V8_TARGET_ARCH_X64 4233 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698