OLD | NEW |
---|---|
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, | 771 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
772 RelocInfo::Mode rmode) { | 772 RelocInfo::Mode rmode) { |
773 ASSERT(cgen_->HasValidEntryRegisters()); | 773 ASSERT(cgen_->HasValidEntryRegisters()); |
774 __ call(code, rmode); | 774 __ call(code, rmode); |
775 Result result = cgen_->allocator()->Allocate(eax); | 775 Result result = cgen_->allocator()->Allocate(eax); |
776 ASSERT(result.is_valid()); | 776 ASSERT(result.is_valid()); |
777 return result; | 777 return result; |
778 } | 778 } |
779 | 779 |
780 | 780 |
781 Result VirtualFrame::CallCodeObject(Handle<Code> code, | 781 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { |
782 RelocInfo::Mode rmode, | 782 // Name and receiver are on the top of the frame. The IC expects |
783 Result* arg, | 783 // name in ecx and reciever on the stack. It does not drop the |
Kasper Lund
2009/03/25 13:25:34
reciever -> receiver (i before e except after c)
| |
784 int dropped_args) { | 784 // receiver. |
785 int spilled_args = 0; | 785 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
786 switch (code->kind()) { | 786 Result name = Pop(); |
787 case Code::LOAD_IC: | 787 PrepareForCall(1, 0); // One stack arg, not callee-dropped. |
788 ASSERT(arg->reg().is(ecx)); | 788 name.ToRegister(ecx); |
789 ASSERT(dropped_args == 0); | 789 name.Unuse(); |
790 spilled_args = 1; | 790 return RawCallCodeObject(ic, mode); |
791 break; | 791 } |
792 case Code::KEYED_STORE_IC: | 792 |
793 ASSERT(arg->reg().is(eax)); | 793 |
794 ASSERT(dropped_args == 0); | 794 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { |
795 spilled_args = 2; | 795 // Key and receiver are on top of the frame. The IC expects them on |
796 break; | 796 // the stack. It does not drop them. |
797 default: | 797 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
798 // No other types of code objects are called with values | 798 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. |
799 // in exactly one register. | 799 return RawCallCodeObject(ic, mode); |
800 UNREACHABLE(); | 800 } |
801 break; | 801 |
802 | |
803 Result VirtualFrame::CallStoreIC() { | |
804 // Name, value, and receiver are on top of the frame. The IC | |
805 // expects name in ecx, value in eax, and receiver on the stack. It | |
806 // does not drop the receiver. | |
807 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | |
808 Result name = Pop(); | |
809 Result value = Pop(); | |
810 PrepareForCall(1, 0); // One stack arg, not callee-dropped. | |
811 | |
812 if (value.is_register() && value.reg().is(ecx)) { | |
813 if (name.is_register() && name.reg().is(eax)) { | |
814 // Wrong registers. | |
815 __ xchg(eax, ecx); | |
816 } else { | |
817 // Register eax is free for value, which frees ecx for name. | |
818 value.ToRegister(eax); | |
819 name.ToRegister(ecx); | |
820 } | |
821 } else { | |
822 // Register ecx is free for name, which guarantees eax is free for | |
823 // value. | |
824 name.ToRegister(ecx); | |
825 value.ToRegister(eax); | |
802 } | 826 } |
803 PrepareForCall(spilled_args, dropped_args); | 827 |
804 arg->Unuse(); | 828 name.Unuse(); |
805 return RawCallCodeObject(code, rmode); | 829 value.Unuse(); |
830 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); | |
831 } | |
832 | |
833 | |
834 Result VirtualFrame::CallKeyedStoreIC() { | |
835 // Value, key, and receiver are on the top of the frame. The IC | |
836 // expects value in eax and key and receiver on the stack. It does | |
837 // not drop the key and receiver. | |
838 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | |
839 // TODO(1222589): Make the IC grab the values from the stack. | |
840 Result value = Pop(); | |
841 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. | |
842 value.ToRegister(eax); | |
843 value.Unuse(); | |
844 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); | |
806 } | 845 } |
807 | 846 |
808 | 847 |
809 Result VirtualFrame::CallCodeObject(Handle<Code> code, | 848 Result VirtualFrame::CallCodeObject(Handle<Code> code, |
810 RelocInfo::Mode rmode, | 849 RelocInfo::Mode rmode, |
811 Result* arg0, | 850 Result* arg0, |
812 Result* arg1, | 851 Result* arg1, |
813 int dropped_args) { | 852 int dropped_args) { |
814 int spilled_args = 1; | 853 int spilled_args = 1; |
815 switch (code->kind()) { | 854 switch (code->kind()) { |
816 case Code::STORE_IC: | |
817 ASSERT(arg0->reg().is(eax)); | |
818 ASSERT(arg1->reg().is(ecx)); | |
819 ASSERT(dropped_args == 0); | |
820 spilled_args = 1; | |
821 break; | |
822 case Code::BUILTIN: | 855 case Code::BUILTIN: |
823 ASSERT(*code == Builtins::builtin(Builtins::JSConstructCall)); | 856 ASSERT(*code == Builtins::builtin(Builtins::JSConstructCall)); |
824 ASSERT(arg0->reg().is(eax)); | 857 ASSERT(arg0->reg().is(eax)); |
825 ASSERT(arg1->reg().is(edi)); | 858 ASSERT(arg1->reg().is(edi)); |
826 spilled_args = dropped_args + 1; | 859 spilled_args = dropped_args + 1; |
827 break; | 860 break; |
828 default: | 861 default: |
829 // No other types of code objects are called with values | 862 // No other types of code objects are called with values |
830 // in exactly two registers. | 863 // in exactly two registers. |
831 UNREACHABLE(); | 864 UNREACHABLE(); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 ASSERT(stack_pointer_ == elements_.length() - 1); | 980 ASSERT(stack_pointer_ == elements_.length() - 1); |
948 elements_.Add(FrameElement::MemoryElement()); | 981 elements_.Add(FrameElement::MemoryElement()); |
949 stack_pointer_++; | 982 stack_pointer_++; |
950 __ push(immediate); | 983 __ push(immediate); |
951 } | 984 } |
952 | 985 |
953 | 986 |
954 #undef __ | 987 #undef __ |
955 | 988 |
956 } } // namespace v8::internal | 989 } } // namespace v8::internal |
OLD | NEW |