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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 596036: Port change in CallIC interface to x64 platform. Name of called function is ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months 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/ic-x64.cc ('k') | src/x64/virtual-frame-x64.h » ('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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 __ movq(dst, FieldOperand(src, offset)); 126 __ movq(dst, FieldOperand(src, offset));
127 } else { 127 } else {
128 // Calculate the offset into the properties array. 128 // Calculate the offset into the properties array.
129 int offset = index * kPointerSize + FixedArray::kHeaderSize; 129 int offset = index * kPointerSize + FixedArray::kHeaderSize;
130 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 130 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
131 __ movq(dst, FieldOperand(dst, offset)); 131 __ movq(dst, FieldOperand(dst, offset));
132 } 132 }
133 } 133 }
134 134
135 135
136 template <typename Pushable>
137 static void PushInterceptorArguments(MacroAssembler* masm, 136 static void PushInterceptorArguments(MacroAssembler* masm,
138 Register receiver, 137 Register receiver,
139 Register holder, 138 Register holder,
140 Pushable name, 139 Register name,
141 JSObject* holder_obj) { 140 JSObject* holder_obj) {
142 __ push(receiver); 141 __ push(receiver);
143 __ push(holder); 142 __ push(holder);
144 __ push(name); 143 __ push(name);
145 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 144 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
146 ASSERT(!Heap::InNewSpace(interceptor)); 145 ASSERT(!Heap::InNewSpace(interceptor));
147 __ movq(kScratchRegister, Handle<Object>(interceptor), 146 __ movq(kScratchRegister, Handle<Object>(interceptor),
148 RelocInfo::EMBEDDED_OBJECT); 147 RelocInfo::EMBEDDED_OBJECT);
149 __ push(kScratchRegister); 148 __ push(kScratchRegister);
150 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset)); 149 __ push(FieldOperand(kScratchRegister, InterceptorInfo::kDataOffset));
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // Check if the wrapped value is a string and load the length 340 // Check if the wrapped value is a string and load the length
342 // directly if it is. 341 // directly if it is.
343 __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset)); 342 __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset));
344 GenerateStringCheck(masm, scratch2, scratch1, miss, miss); 343 GenerateStringCheck(masm, scratch2, scratch1, miss, miss);
345 __ movl(rax, FieldOperand(scratch2, String::kLengthOffset)); 344 __ movl(rax, FieldOperand(scratch2, String::kLengthOffset));
346 __ Integer32ToSmi(rax, rax); 345 __ Integer32ToSmi(rax, rax);
347 __ ret(0); 346 __ ret(0);
348 } 347 }
349 348
350 349
351 template <class Pushable>
352 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 350 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
353 Register receiver, 351 Register receiver,
354 Register holder, 352 Register holder,
355 Pushable name, 353 Register name,
356 JSObject* holder_obj) { 354 JSObject* holder_obj) {
357 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 355 PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
358 356
359 ExternalReference ref = 357 ExternalReference ref =
360 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly)); 358 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly));
361 __ movq(rax, Immediate(5)); 359 __ movq(rax, Immediate(5));
362 __ movq(rbx, ref); 360 __ movq(rbx, ref);
363 361
364 CEntryStub stub(1); 362 CEntryStub stub(1);
365 __ CallStub(&stub); 363 __ CallStub(&stub);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 __ TailCallRuntime(ref, 5, 1); 551 __ TailCallRuntime(ref, 5, 1);
554 } 552 }
555 553
556 private: 554 private:
557 Register name_; 555 Register name_;
558 }; 556 };
559 557
560 558
561 class CallInterceptorCompiler BASE_EMBEDDED { 559 class CallInterceptorCompiler BASE_EMBEDDED {
562 public: 560 public:
563 explicit CallInterceptorCompiler(const ParameterCount& arguments) 561 CallInterceptorCompiler(const ParameterCount& arguments, Register name)
564 : arguments_(arguments), argc_(arguments.immediate()) {} 562 : arguments_(arguments), argc_(arguments.immediate()), name_(name) {}
565 563
566 void CompileCacheable(MacroAssembler* masm, 564 void CompileCacheable(MacroAssembler* masm,
567 StubCompiler* stub_compiler, 565 StubCompiler* stub_compiler,
568 Register receiver, 566 Register receiver,
569 Register holder, 567 Register holder,
570 Register scratch1, 568 Register scratch1,
571 Register scratch2, 569 Register scratch2,
572 JSObject* holder_obj, 570 JSObject* holder_obj,
573 LookupResult* lookup, 571 LookupResult* lookup,
574 String* name, 572 String* name,
(...skipping 10 matching lines...) Expand all
585 optimize = true; 583 optimize = true;
586 } 584 }
587 } 585 }
588 586
589 if (!optimize) { 587 if (!optimize) {
590 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label); 588 CompileRegular(masm, receiver, holder, scratch2, holder_obj, miss_label);
591 return; 589 return;
592 } 590 }
593 591
594 __ EnterInternalFrame(); 592 __ EnterInternalFrame();
595 __ push(holder); // save the holder 593 __ push(holder); // Save the holder.
594 __ push(name_); // Save the name.
596 595
597 CompileCallLoadPropertyWithInterceptor( 596 CompileCallLoadPropertyWithInterceptor(masm,
598 masm, 597 receiver,
599 receiver, 598 holder,
600 holder, 599 name_,
601 // Under EnterInternalFrame this refers to name. 600 holder_obj);
602 Operand(rbp, (argc_ + 3) * kPointerSize),
603 holder_obj);
604 601
605 __ pop(receiver); // restore holder 602 __ pop(name_); // Restore the name.
603 __ pop(receiver); // Restore the holder.
606 __ LeaveInternalFrame(); 604 __ LeaveInternalFrame();
607 605
608 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 606 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex);
609 Label invoke; 607 Label invoke;
610 __ j(not_equal, &invoke); 608 __ j(not_equal, &invoke);
611 609
612 stub_compiler->CheckPrototypes(holder_obj, receiver, 610 stub_compiler->CheckPrototypes(holder_obj, receiver,
613 lookup->holder(), scratch1, 611 lookup->holder(), scratch1,
614 scratch2, 612 scratch2,
615 name, 613 name,
(...skipping 18 matching lines...) Expand all
634 __ bind(&invoke); 632 __ bind(&invoke);
635 } 633 }
636 634
637 void CompileRegular(MacroAssembler* masm, 635 void CompileRegular(MacroAssembler* masm,
638 Register receiver, 636 Register receiver,
639 Register holder, 637 Register holder,
640 Register scratch, 638 Register scratch,
641 JSObject* holder_obj, 639 JSObject* holder_obj,
642 Label* miss_label) { 640 Label* miss_label) {
643 __ EnterInternalFrame(); 641 __ EnterInternalFrame();
642 // Save the name_ register across the call.
643 __ push(name_);
644 644
645 PushInterceptorArguments(masm, 645 PushInterceptorArguments(masm,
646 receiver, 646 receiver,
647 holder, 647 holder,
648 Operand(rbp, (argc_ + 3) * kPointerSize), 648 name_,
649 holder_obj); 649 holder_obj);
650 650
651 ExternalReference ref = ExternalReference( 651 ExternalReference ref = ExternalReference(
652 IC_Utility(IC::kLoadPropertyWithInterceptorForCall)); 652 IC_Utility(IC::kLoadPropertyWithInterceptorForCall));
653 __ movq(rax, Immediate(5)); 653 __ movq(rax, Immediate(5));
654 __ movq(rbx, ref); 654 __ movq(rbx, ref);
655 655
656 CEntryStub stub(1); 656 CEntryStub stub(1);
657 __ CallStub(&stub); 657 __ CallStub(&stub);
658 658
659 __ pop(name_);
659 __ LeaveInternalFrame(); 660 __ LeaveInternalFrame();
660 } 661 }
661 662
662 private: 663 private:
663 const ParameterCount& arguments_; 664 const ParameterCount& arguments_;
664 int argc_; 665 int argc_;
666 Register name_;
665 }; 667 };
666 668
667 669
668 #undef __ 670 #undef __
669 671
670 #define __ ACCESS_MASM((masm())) 672 #define __ ACCESS_MASM((masm()))
671 673
672 674
673 Object* CallStubCompiler::CompileCallConstant(Object* object, 675 Object* CallStubCompiler::CompileCallConstant(Object* object,
674 JSObject* holder, 676 JSObject* holder,
675 JSFunction* function, 677 JSFunction* function,
676 String* name, 678 String* name,
677 StubCompiler::CheckType check) { 679 StubCompiler::CheckType check) {
678 // ----------- S t a t e ------------- 680 // ----------- S t a t e -------------
681 // rcx : function name
682 // rsp[0] : return address
683 // rsp[8] : argument argc
684 // rsp[16] : argument argc - 1
685 // ...
686 // rsp[argc * 8] : argument 1
687 // rsp[(argc + 1) * 8] : argument 0 = receiver
679 // ----------------------------------- 688 // -----------------------------------
680 // rsp[0] return address
681 // rsp[8] argument argc
682 // rsp[16] argument argc - 1
683 // ...
684 // rsp[argc * 8] argument 1
685 // rsp[(argc + 1) * 8] argument 0 = receiver
686 // rsp[(argc + 2) * 8] function name
687 689
688 Label miss; 690 Label miss;
689 691
690 // Get the receiver from the stack. 692 // Get the receiver from the stack.
691 const int argc = arguments().immediate(); 693 const int argc = arguments().immediate();
692 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 694 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
693 695
694 // Check that the receiver isn't a smi. 696 // Check that the receiver isn't a smi.
695 if (check != NUMBER_CHECK) { 697 if (check != NUMBER_CHECK) {
696 __ JumpIfSmi(rdx, &miss); 698 __ JumpIfSmi(rdx, &miss);
697 } 699 }
698 700
699 // Make sure that it's okay not to patch the on stack receiver 701 // Make sure that it's okay not to patch the on stack receiver
700 // unless we're doing a receiver map check. 702 // unless we're doing a receiver map check.
701 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 703 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
702 704
703 switch (check) { 705 switch (check) {
704 case RECEIVER_MAP_CHECK: 706 case RECEIVER_MAP_CHECK:
705 // Check that the maps haven't changed. 707 // Check that the maps haven't changed.
706 CheckPrototypes(JSObject::cast(object), rdx, holder, 708 CheckPrototypes(JSObject::cast(object), rdx, holder,
707 rbx, rcx, name, &miss); 709 rbx, rax, name, &miss);
708 710
709 // Patch the receiver on the stack with the global proxy if 711 // Patch the receiver on the stack with the global proxy if
710 // necessary. 712 // necessary.
711 if (object->IsGlobalObject()) { 713 if (object->IsGlobalObject()) {
712 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 714 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
713 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 715 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
714 } 716 }
715 break; 717 break;
716 718
717 case STRING_CHECK: 719 case STRING_CHECK:
718 if (!function->IsBuiltin()) { 720 if (!function->IsBuiltin()) {
719 // Calling non-builtins with a value as receiver requires boxing. 721 // Calling non-builtins with a value as receiver requires boxing.
720 __ jmp(&miss); 722 __ jmp(&miss);
721 } else { 723 } else {
722 // Check that the object is a two-byte string or a symbol. 724 // Check that the object is a two-byte string or a symbol.
723 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rcx); 725 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
724 __ j(above_equal, &miss); 726 __ j(above_equal, &miss);
725 // Check that the maps starting from the prototype haven't changed. 727 // Check that the maps starting from the prototype haven't changed.
726 GenerateLoadGlobalFunctionPrototype(masm(), 728 GenerateLoadGlobalFunctionPrototype(masm(),
727 Context::STRING_FUNCTION_INDEX, 729 Context::STRING_FUNCTION_INDEX,
728 rcx); 730 rax);
729 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 731 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
730 rbx, rdx, name, &miss); 732 rbx, rdx, name, &miss);
731 } 733 }
732 break; 734 break;
733 735
734 case NUMBER_CHECK: { 736 case NUMBER_CHECK: {
735 if (!function->IsBuiltin()) { 737 if (!function->IsBuiltin()) {
736 // Calling non-builtins with a value as receiver requires boxing. 738 // Calling non-builtins with a value as receiver requires boxing.
737 __ jmp(&miss); 739 __ jmp(&miss);
738 } else { 740 } else {
739 Label fast; 741 Label fast;
740 // Check that the object is a smi or a heap number. 742 // Check that the object is a smi or a heap number.
741 __ JumpIfSmi(rdx, &fast); 743 __ JumpIfSmi(rdx, &fast);
742 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); 744 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
743 __ j(not_equal, &miss); 745 __ j(not_equal, &miss);
744 __ bind(&fast); 746 __ bind(&fast);
745 // Check that the maps starting from the prototype haven't changed. 747 // Check that the maps starting from the prototype haven't changed.
746 GenerateLoadGlobalFunctionPrototype(masm(), 748 GenerateLoadGlobalFunctionPrototype(masm(),
747 Context::NUMBER_FUNCTION_INDEX, 749 Context::NUMBER_FUNCTION_INDEX,
748 rcx); 750 rax);
749 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 751 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
750 rbx, rdx, name, &miss); 752 rbx, rdx, name, &miss);
751 } 753 }
752 break; 754 break;
753 } 755 }
754 756
755 case BOOLEAN_CHECK: { 757 case BOOLEAN_CHECK: {
756 if (!function->IsBuiltin()) { 758 if (!function->IsBuiltin()) {
757 // Calling non-builtins with a value as receiver requires boxing. 759 // Calling non-builtins with a value as receiver requires boxing.
758 __ jmp(&miss); 760 __ jmp(&miss);
759 } else { 761 } else {
760 Label fast; 762 Label fast;
761 // Check that the object is a boolean. 763 // Check that the object is a boolean.
762 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); 764 __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
763 __ j(equal, &fast); 765 __ j(equal, &fast);
764 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); 766 __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
765 __ j(not_equal, &miss); 767 __ j(not_equal, &miss);
766 __ bind(&fast); 768 __ bind(&fast);
767 // Check that the maps starting from the prototype haven't changed. 769 // Check that the maps starting from the prototype haven't changed.
768 GenerateLoadGlobalFunctionPrototype(masm(), 770 GenerateLoadGlobalFunctionPrototype(masm(),
769 Context::BOOLEAN_FUNCTION_INDEX, 771 Context::BOOLEAN_FUNCTION_INDEX,
770 rcx); 772 rax);
771 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, 773 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder,
772 rbx, rdx, name, &miss); 774 rbx, rdx, name, &miss);
773 } 775 }
774 break; 776 break;
775 } 777 }
776 778
777 case JSARRAY_HAS_FAST_ELEMENTS_CHECK: 779 case JSARRAY_HAS_FAST_ELEMENTS_CHECK:
778 CheckPrototypes(JSObject::cast(object), rdx, holder, 780 CheckPrototypes(JSObject::cast(object), rdx, holder,
779 rbx, rcx, name, &miss); 781 rbx, rax, name, &miss);
780 // Make sure object->HasFastElements(). 782 // Make sure object->HasFastElements().
781 // Get the elements array of the object. 783 // Get the elements array of the object.
782 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 784 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
783 // Check that the object is in fast mode (not dictionary). 785 // Check that the object is in fast mode (not dictionary).
784 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), 786 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset),
785 Factory::fixed_array_map()); 787 Factory::fixed_array_map());
786 __ j(not_equal, &miss); 788 __ j(not_equal, &miss);
787 break; 789 break;
788 790
789 default: 791 default:
(...skipping 23 matching lines...) Expand all
813 } 815 }
814 return GetCode(CONSTANT_FUNCTION, function_name); 816 return GetCode(CONSTANT_FUNCTION, function_name);
815 } 817 }
816 818
817 819
818 Object* CallStubCompiler::CompileCallField(Object* object, 820 Object* CallStubCompiler::CompileCallField(Object* object,
819 JSObject* holder, 821 JSObject* holder,
820 int index, 822 int index,
821 String* name) { 823 String* name) {
822 // ----------- S t a t e ------------- 824 // ----------- S t a t e -------------
825 // rcx : function name
826 // rsp[0] : return address
827 // rsp[8] : argument argc
828 // rsp[16] : argument argc - 1
829 // ...
830 // rsp[argc * 8] : argument 1
831 // rsp[(argc + 1) * 8] : argument 0 = receiver
823 // ----------------------------------- 832 // -----------------------------------
824 // rsp[0] return address
825 // rsp[8] argument argc
826 // rsp[16] argument argc - 1
827 // ...
828 // rsp[argc * 8] argument 1
829 // rsp[(argc + 1) * 8] argument 0 = receiver
830 // rsp[(argc + 2) * 8] function name
831 Label miss; 833 Label miss;
832 834
833 // Get the receiver from the stack. 835 // Get the receiver from the stack.
834 const int argc = arguments().immediate(); 836 const int argc = arguments().immediate();
835 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 837 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
836 838
837 // Check that the receiver isn't a smi. 839 // Check that the receiver isn't a smi.
838 __ JumpIfSmi(rdx, &miss); 840 __ JumpIfSmi(rdx, &miss);
839 841
840 // Do the right check and compute the holder register. 842 // Do the right check and compute the holder register.
841 Register reg = 843 Register reg =
842 CheckPrototypes(JSObject::cast(object), rdx, holder, 844 CheckPrototypes(JSObject::cast(object), rdx, holder,
843 rbx, rcx, name, &miss); 845 rbx, rax, name, &miss);
844 846
845 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); 847 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index);
846 848
847 // Check that the function really is a function. 849 // Check that the function really is a function.
848 __ JumpIfSmi(rdi, &miss); 850 __ JumpIfSmi(rdi, &miss);
849 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); 851 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx);
850 __ j(not_equal, &miss); 852 __ j(not_equal, &miss);
851 853
852 // Patch the receiver on the stack with the global proxy if 854 // Patch the receiver on the stack with the global proxy if
853 // necessary. 855 // necessary.
(...skipping 12 matching lines...) Expand all
866 868
867 // Return the generated code. 869 // Return the generated code.
868 return GetCode(FIELD, name); 870 return GetCode(FIELD, name);
869 } 871 }
870 872
871 873
872 Object* CallStubCompiler::CompileCallInterceptor(Object* object, 874 Object* CallStubCompiler::CompileCallInterceptor(Object* object,
873 JSObject* holder, 875 JSObject* holder,
874 String* name) { 876 String* name) {
875 // ----------- S t a t e ------------- 877 // ----------- S t a t e -------------
878 // rcx : function name
879 // rsp[0] : return address
880 // rsp[8] : argument argc
881 // rsp[16] : argument argc - 1
882 // ...
883 // rsp[argc * 8] : argument 1
884 // rsp[(argc + 1) * 8] : argument 0 = receiver
876 // ----------------------------------- 885 // -----------------------------------
877 Label miss; 886 Label miss;
878 887
879 // Get the number of arguments. 888 // Get the number of arguments.
880 const int argc = arguments().immediate(); 889 const int argc = arguments().immediate();
881 890
882 LookupResult lookup; 891 LookupResult lookup;
883 LookupPostInterceptor(holder, name, &lookup); 892 LookupPostInterceptor(holder, name, &lookup);
884 893
885 // Get the receiver from the stack. 894 // Get the receiver from the stack.
886 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 895 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
887 896
888 CallInterceptorCompiler compiler(arguments()); 897 CallInterceptorCompiler compiler(arguments(), rcx);
889 CompileLoadInterceptor(&compiler, 898 CompileLoadInterceptor(&compiler,
890 this, 899 this,
891 masm(), 900 masm(),
892 JSObject::cast(object), 901 JSObject::cast(object),
893 holder, 902 holder,
894 name, 903 name,
895 &lookup, 904 &lookup,
896 rdx, 905 rdx,
897 rbx, 906 rbx,
898 rcx, 907 rdi,
899 &miss); 908 &miss);
900 909
901 // Restore receiver. 910 // Restore receiver.
902 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 911 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
903 912
904 // Check that the function really is a function. 913 // Check that the function really is a function.
905 __ JumpIfSmi(rax, &miss); 914 __ JumpIfSmi(rax, &miss);
906 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); 915 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx);
907 __ j(not_equal, &miss); 916 __ j(not_equal, &miss);
908 917
(...skipping 19 matching lines...) Expand all
928 937
929 938
930 939
931 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, 940 Object* CallStubCompiler::CompileCallGlobal(JSObject* object,
932 GlobalObject* holder, 941 GlobalObject* holder,
933 JSGlobalPropertyCell* cell, 942 JSGlobalPropertyCell* cell,
934 JSFunction* function, 943 JSFunction* function,
935 String* name) { 944 String* name) {
936 // ----------- S t a t e ------------- 945 // ----------- S t a t e -------------
937 // ----------------------------------- 946 // -----------------------------------
938 // rsp[0] return address 947 // rcx : function name
939 // rsp[8] argument argc 948 // rsp[0] : return address
940 // rsp[16] argument argc - 1 949 // rsp[8] : argument argc
950 // rsp[16] : argument argc - 1
941 // ... 951 // ...
942 // rsp[argc * 8] argument 1 952 // rsp[argc * 8] : argument 1
943 // rsp[(argc + 1) * 8] argument 0 = receiver 953 // rsp[(argc + 1) * 8] : argument 0 = receiver
944 // rsp[(argc + 2) * 8] function name
945 Label miss; 954 Label miss;
946 955
947 // Get the number of arguments. 956 // Get the number of arguments.
948 const int argc = arguments().immediate(); 957 const int argc = arguments().immediate();
949 958
950 // Get the receiver from the stack. 959 // Get the receiver from the stack.
951 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 960 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
952 961
953 // If the object is the holder then we know that it's a global 962 // If the object is the holder then we know that it's a global
954 // object which can only happen for contextual calls. In this case, 963 // object which can only happen for contextual calls. In this case,
955 // the receiver cannot be a smi. 964 // the receiver cannot be a smi.
956 if (object != holder) { 965 if (object != holder) {
957 __ JumpIfSmi(rdx, &miss); 966 __ JumpIfSmi(rdx, &miss);
958 } 967 }
959 968
960 // Check that the maps haven't changed. 969 // Check that the maps haven't changed.
961 CheckPrototypes(object, rdx, holder, rbx, rcx, name, &miss); 970 CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss);
962 971
963 // Get the value from the cell. 972 // Get the value from the cell.
964 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); 973 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell));
965 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); 974 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset));
966 975
967 // Check that the cell contains the same function. 976 // Check that the cell contains the same function.
968 if (Heap::InNewSpace(function)) { 977 if (Heap::InNewSpace(function)) {
969 // We can't embed a pointer to a function in new space so we have 978 // We can't embed a pointer to a function in new space so we have
970 // to verify that the shared function info is unchanged. This has 979 // to verify that the shared function info is unchanged. This has
971 // the nice side effect that multiple closures based on the same 980 // the nice side effect that multiple closures based on the same
972 // function can all use this call IC. Before we load through the 981 // function can all use this call IC. Before we load through the
973 // function, we have to verify that it still is a function. 982 // function, we have to verify that it still is a function.
974 __ JumpIfSmi(rdi, &miss); 983 __ JumpIfSmi(rdi, &miss);
975 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx); 984 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax);
976 __ j(not_equal, &miss); 985 __ j(not_equal, &miss);
977 986
978 // Check the shared function info. Make sure it hasn't changed. 987 // Check the shared function info. Make sure it hasn't changed.
979 __ Move(rcx, Handle<SharedFunctionInfo>(function->shared())); 988 __ Move(rax, Handle<SharedFunctionInfo>(function->shared()));
980 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rcx); 989 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax);
981 __ j(not_equal, &miss); 990 __ j(not_equal, &miss);
982 } else { 991 } else {
983 __ Cmp(rdi, Handle<JSFunction>(function)); 992 __ Cmp(rdi, Handle<JSFunction>(function));
984 __ j(not_equal, &miss); 993 __ j(not_equal, &miss);
985 } 994 }
986 995
987 // Patch the receiver on the stack with the global proxy. 996 // Patch the receiver on the stack with the global proxy.
988 if (object->IsGlobalObject()) { 997 if (object->IsGlobalObject()) {
989 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 998 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
990 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 999 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 1882 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
1874 1883
1875 // Return the generated code. 1884 // Return the generated code.
1876 return GetCode(); 1885 return GetCode();
1877 } 1886 }
1878 1887
1879 1888
1880 #undef __ 1889 #undef __
1881 1890
1882 } } // namespace v8::internal 1891 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/ic-x64.cc ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698