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

Side by Side Diff: src/ia32/virtual-frame-ia32.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
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/ia32/virtual-frame-ia32.h ('k') | src/ic.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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 27 matching lines...) Expand all
38 38
39 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
40 // VirtualFrame implementation. 40 // VirtualFrame implementation.
41 41
42 // On entry to a function, the virtual frame already contains the receiver, 42 // On entry to a function, the virtual frame already contains the receiver,
43 // the parameters, and a return address. All frame elements are in memory. 43 // the parameters, and a return address. All frame elements are in memory.
44 VirtualFrame::VirtualFrame() 44 VirtualFrame::VirtualFrame()
45 : elements_(parameter_count() + local_count() + kPreallocatedElements), 45 : elements_(parameter_count() + local_count() + kPreallocatedElements),
46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. 46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
47 for (int i = 0; i <= stack_pointer_; i++) { 47 for (int i = 0; i <= stack_pointer_; i++) {
48 elements_.Add(FrameElement::MemoryElement()); 48 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
49 } 49 }
50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { 50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
51 register_locations_[i] = kIllegalIndex; 51 register_locations_[i] = kIllegalIndex;
52 } 52 }
53 } 53 }
54 54
55 55
56 void VirtualFrame::SyncElementBelowStackPointer(int index) { 56 void VirtualFrame::SyncElementBelowStackPointer(int index) {
57 // Emit code to write elements below the stack pointer to their 57 // Emit code to write elements below the stack pointer to their
58 // (already allocated) stack address. 58 // (already allocated) stack address.
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 166 }
167 } 167 }
168 } 168 }
169 } 169 }
170 170
171 171
172 void VirtualFrame::MakeMergable() { 172 void VirtualFrame::MakeMergable() {
173 for (int i = 0; i < element_count(); i++) { 173 for (int i = 0; i < element_count(); i++) {
174 FrameElement element = elements_[i]; 174 FrameElement element = elements_[i];
175 175
176 // All number type information is reset to unknown for a mergable frame
177 // because of incoming back edges.
176 if (element.is_constant() || element.is_copy()) { 178 if (element.is_constant() || element.is_copy()) {
177 if (element.is_synced()) { 179 if (element.is_synced()) {
178 // Just spill. 180 // Just spill.
179 elements_[i] = FrameElement::MemoryElement(); 181 elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
180 } else { 182 } else {
181 // Allocate to a register. 183 // Allocate to a register.
182 FrameElement backing_element; // Invalid if not a copy. 184 FrameElement backing_element; // Invalid if not a copy.
183 if (element.is_copy()) { 185 if (element.is_copy()) {
184 backing_element = elements_[element.index()]; 186 backing_element = elements_[element.index()];
185 } 187 }
186 Result fresh = cgen()->allocator()->Allocate(); 188 Result fresh = cgen()->allocator()->Allocate();
187 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. 189 ASSERT(fresh.is_valid()); // A register was spilled if all were in use.
188 elements_[i] = 190 elements_[i] =
189 FrameElement::RegisterElement(fresh.reg(), 191 FrameElement::RegisterElement(fresh.reg(),
190 FrameElement::NOT_SYNCED); 192 FrameElement::NOT_SYNCED,
193 NumberInfo::kUnknown);
191 Use(fresh.reg(), i); 194 Use(fresh.reg(), i);
192 195
193 // Emit a move. 196 // Emit a move.
194 if (element.is_constant()) { 197 if (element.is_constant()) {
195 if (cgen()->IsUnsafeSmi(element.handle())) { 198 if (cgen()->IsUnsafeSmi(element.handle())) {
196 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); 199 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle());
197 } else { 200 } else {
198 __ Set(fresh.reg(), Immediate(element.handle())); 201 __ Set(fresh.reg(), Immediate(element.handle()));
199 } 202 }
200 } else { 203 } else {
(...skipping 12 matching lines...) Expand all
213 } 216 }
214 } 217 }
215 } 218 }
216 // No need to set the copied flag --- there are no copies. 219 // No need to set the copied flag --- there are no copies.
217 } else { 220 } else {
218 // Clear the copy flag of non-constant, non-copy elements. 221 // Clear the copy flag of non-constant, non-copy elements.
219 // They cannot be copied because copies are not allowed. 222 // They cannot be copied because copies are not allowed.
220 // The copy flag is not relied on before the end of this loop, 223 // The copy flag is not relied on before the end of this loop,
221 // including when registers are spilled. 224 // including when registers are spilled.
222 elements_[i].clear_copied(); 225 elements_[i].clear_copied();
226 elements_[i].set_number_info(NumberInfo::kUnknown);
223 } 227 }
224 } 228 }
225 } 229 }
226 230
227 231
228 void VirtualFrame::MergeTo(VirtualFrame* expected) { 232 void VirtualFrame::MergeTo(VirtualFrame* expected) {
229 Comment cmnt(masm(), "[ Merge frame"); 233 Comment cmnt(masm(), "[ Merge frame");
230 // We should always be merging the code generator's current frame to an 234 // We should always be merging the code generator's current frame to an
231 // expected frame. 235 // expected frame.
232 ASSERT(cgen()->frame() == this); 236 ASSERT(cgen()->frame() == this);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } else { 604 } else {
601 // The original was in a register. 605 // The original was in a register.
602 backing_reg = original.reg(); 606 backing_reg = original.reg();
603 set_register_location(backing_reg, new_backing_index); 607 set_register_location(backing_reg, new_backing_index);
604 } 608 }
605 // Invalidate the element at index. 609 // Invalidate the element at index.
606 elements_[index] = FrameElement::InvalidElement(); 610 elements_[index] = FrameElement::InvalidElement();
607 // Set the new backing element. 611 // Set the new backing element.
608 if (elements_[new_backing_index].is_synced()) { 612 if (elements_[new_backing_index].is_synced()) {
609 elements_[new_backing_index] = 613 elements_[new_backing_index] =
610 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); 614 FrameElement::RegisterElement(backing_reg,
615 FrameElement::SYNCED,
616 original.number_info());
611 } else { 617 } else {
612 elements_[new_backing_index] = 618 elements_[new_backing_index] =
613 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); 619 FrameElement::RegisterElement(backing_reg,
620 FrameElement::NOT_SYNCED,
621 original.number_info());
614 } 622 }
615 // Update the other copies. 623 // Update the other copies.
616 for (int i = new_backing_index + 1; i < element_count(); i++) { 624 for (int i = new_backing_index + 1; i < element_count(); i++) {
617 if (elements_[i].is_copy() && elements_[i].index() == index) { 625 if (elements_[i].is_copy() && elements_[i].index() == index) {
618 elements_[i].set_index(new_backing_index); 626 elements_[i].set_index(new_backing_index);
619 elements_[new_backing_index].set_copied(); 627 elements_[new_backing_index].set_copied();
620 } 628 }
621 } 629 }
622 return new_backing_index; 630 return new_backing_index;
623 } 631 }
(...skipping 10 matching lines...) Expand all
634 } 642 }
635 643
636 switch (original.type()) { 644 switch (original.type()) {
637 case FrameElement::MEMORY: { 645 case FrameElement::MEMORY: {
638 // Emit code to load the original element's data into a register. 646 // Emit code to load the original element's data into a register.
639 // Push that register as a FrameElement on top of the frame. 647 // Push that register as a FrameElement on top of the frame.
640 Result fresh = cgen()->allocator()->Allocate(); 648 Result fresh = cgen()->allocator()->Allocate();
641 ASSERT(fresh.is_valid()); 649 ASSERT(fresh.is_valid());
642 FrameElement new_element = 650 FrameElement new_element =
643 FrameElement::RegisterElement(fresh.reg(), 651 FrameElement::RegisterElement(fresh.reg(),
644 FrameElement::NOT_SYNCED); 652 FrameElement::NOT_SYNCED,
653 original.number_info());
645 Use(fresh.reg(), element_count()); 654 Use(fresh.reg(), element_count());
646 elements_.Add(new_element); 655 elements_.Add(new_element);
647 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); 656 __ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
648 break; 657 break;
649 } 658 }
650 case FrameElement::REGISTER: 659 case FrameElement::REGISTER:
651 Use(original.reg(), element_count()); 660 Use(original.reg(), element_count());
652 // Fall through. 661 // Fall through.
653 case FrameElement::CONSTANT: 662 case FrameElement::CONSTANT:
654 case FrameElement::COPY: 663 case FrameElement::COPY:
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { 855 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
847 PrepareForCall(arg_count, arg_count); 856 PrepareForCall(arg_count, arg_count);
848 ASSERT(cgen()->HasValidEntryRegisters()); 857 ASSERT(cgen()->HasValidEntryRegisters());
849 __ CallRuntime(id, arg_count); 858 __ CallRuntime(id, arg_count);
850 Result result = cgen()->allocator()->Allocate(eax); 859 Result result = cgen()->allocator()->Allocate(eax);
851 ASSERT(result.is_valid()); 860 ASSERT(result.is_valid());
852 return result; 861 return result;
853 } 862 }
854 863
855 864
865 #ifdef ENABLE_DEBUGGER_SUPPORT
866 void VirtualFrame::DebugBreak() {
867 PrepareForCall(0, 0);
868 ASSERT(cgen()->HasValidEntryRegisters());
869 __ DebugBreak();
870 Result result = cgen()->allocator()->Allocate(eax);
871 ASSERT(result.is_valid());
872 }
873 #endif
874
875
856 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, 876 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
857 InvokeFlag flag, 877 InvokeFlag flag,
858 int arg_count) { 878 int arg_count) {
859 PrepareForCall(arg_count, arg_count); 879 PrepareForCall(arg_count, arg_count);
860 ASSERT(cgen()->HasValidEntryRegisters()); 880 ASSERT(cgen()->HasValidEntryRegisters());
861 __ InvokeBuiltin(id, flag); 881 __ InvokeBuiltin(id, flag);
862 Result result = cgen()->allocator()->Allocate(eax); 882 Result result = cgen()->allocator()->Allocate(eax);
863 ASSERT(result.is_valid()); 883 ASSERT(result.is_valid());
864 return result; 884 return result;
865 } 885 }
866 886
867 887
868 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, 888 Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
869 RelocInfo::Mode rmode) { 889 RelocInfo::Mode rmode) {
870 ASSERT(cgen()->HasValidEntryRegisters()); 890 ASSERT(cgen()->HasValidEntryRegisters());
871 __ call(code, rmode); 891 __ call(code, rmode);
872 Result result = cgen()->allocator()->Allocate(eax); 892 Result result = cgen()->allocator()->Allocate(eax);
873 ASSERT(result.is_valid()); 893 ASSERT(result.is_valid());
874 return result; 894 return result;
875 } 895 }
876 896
877 897
878 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { 898 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
879 // Name and receiver are on the top of the frame. The IC expects 899 // Name and receiver are on the top of the frame. The IC expects
880 // name in ecx and receiver on the stack. It does not drop the 900 // name in ecx and receiver in eax.
881 // receiver.
882 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 901 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
883 Result name = Pop(); 902 Result name = Pop();
884 PrepareForCall(1, 0); // One stack arg, not callee-dropped. 903 Result receiver = Pop();
885 name.ToRegister(ecx); 904 PrepareForCall(0, 0); // No stack arguments.
905 // Move results to the right registers:
906 if (name.is_register() && name.reg().is(eax)) {
907 if (receiver.is_register() && receiver.reg().is(ecx)) {
908 // Wrong registers.
909 __ xchg(eax, ecx);
910 } else {
911 // Register ecx is free for name, which frees eax for receiver.
912 name.ToRegister(ecx);
913 receiver.ToRegister(eax);
914 }
915 } else {
916 // Register eax is free for receiver, which frees ecx for name.
917 receiver.ToRegister(eax);
918 name.ToRegister(ecx);
919 }
886 name.Unuse(); 920 name.Unuse();
921 receiver.Unuse();
887 return RawCallCodeObject(ic, mode); 922 return RawCallCodeObject(ic, mode);
888 } 923 }
889 924
890 925
891 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { 926 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
892 // Key and receiver are on top of the frame. The IC expects them on 927 // Key and receiver are on top of the frame. Put them in eax and edx.
893 // the stack. It does not drop them. 928 Result key = Pop();
929 Result receiver = Pop();
930 PrepareForCall(0, 0);
931
932 if (!key.is_register() || !key.reg().is(edx)) {
933 // Register edx is available for receiver.
934 receiver.ToRegister(edx);
935 key.ToRegister(eax);
936 } else if (!receiver.is_register() || !receiver.reg().is(eax)) {
937 // Register eax is available for key.
938 key.ToRegister(eax);
939 receiver.ToRegister(edx);
940 } else {
941 __ xchg(edx, eax);
942 }
943 key.Unuse();
944 receiver.Unuse();
945
894 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 946 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
895 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
896 return RawCallCodeObject(ic, mode); 947 return RawCallCodeObject(ic, mode);
897 } 948 }
898 949
899 950
900 Result VirtualFrame::CallStoreIC() { 951 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
901 // Name, value, and receiver are on top of the frame. The IC 952 // Value and (if not contextual) receiver are on top of the frame.
902 // expects name in ecx, value in eax, and receiver in edx. 953 // The IC expects name in ecx, value in eax, and receiver in edx.
903 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 954 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
904 Result name = Pop();
905 Result value = Pop(); 955 Result value = Pop();
906 Result receiver = Pop(); 956 if (is_contextual) {
907 PrepareForCall(0, 0); 957 PrepareForCall(0, 0);
958 value.ToRegister(eax);
959 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
960 __ mov(ecx, name);
961 } else {
962 Result receiver = Pop();
963 PrepareForCall(0, 0);
908 964
909 // Optimized for case in which name is a constant value. 965 if (value.is_register() && value.reg().is(edx)) {
910 if (name.is_register() && (name.reg().is(edx) || name.reg().is(eax))) { 966 if (receiver.is_register() && receiver.reg().is(eax)) {
911 if (!is_used(ecx)) { 967 // Wrong registers.
912 name.ToRegister(ecx); 968 __ xchg(eax, edx);
913 } else if (!is_used(ebx)) { 969 } else {
914 name.ToRegister(ebx); 970 // Register eax is free for value, which frees edx for receiver.
971 value.ToRegister(eax);
972 receiver.ToRegister(edx);
973 }
915 } else { 974 } else {
916 ASSERT(!is_used(edi)); // Only three results are live, so edi is free. 975 // Register edx is free for receiver, which guarantees eax is free for
917 name.ToRegister(edi); 976 // value.
977 receiver.ToRegister(edx);
978 value.ToRegister(eax);
918 } 979 }
919 } 980 }
920 // Now name is not in edx or eax, so we can fix them, then move name to ecx. 981 __ mov(ecx, name);
921 if (value.is_register() && value.reg().is(edx)) {
922 if (receiver.is_register() && receiver.reg().is(eax)) {
923 // Wrong registers.
924 __ xchg(eax, edx);
925 } else {
926 // Register eax is free for value, which frees edx for receiver.
927 value.ToRegister(eax);
928 receiver.ToRegister(edx);
929 }
930 } else {
931 // Register edx is free for receiver, which guarantees eax is free for
932 // value.
933 receiver.ToRegister(edx);
934 value.ToRegister(eax);
935 }
936 // Receiver and value are in the right place, so ecx is free for name.
937 name.ToRegister(ecx);
938 name.Unuse();
939 value.Unuse(); 982 value.Unuse();
940 receiver.Unuse();
941 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 983 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
942 } 984 }
943 985
944 986
945 Result VirtualFrame::CallKeyedStoreIC() { 987 Result VirtualFrame::CallKeyedStoreIC() {
946 // Value, key, and receiver are on the top of the frame. The IC 988 // Value, key, and receiver are on the top of the frame. The IC
947 // expects value in eax and key and receiver on the stack. It does 989 // expects value in eax and key and receiver on the stack. It does
948 // not drop the key and receiver. 990 // not drop the key and receiver.
949 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 991 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
950 // TODO(1222589): Make the IC grab the values from the stack.
951 Result value = Pop(); 992 Result value = Pop();
952 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. 993 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
953 value.ToRegister(eax); 994 value.ToRegister(eax);
954 value.Unuse(); 995 value.Unuse();
955 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 996 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
956 } 997 }
957 998
958 999
959 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, 1000 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
960 int arg_count, 1001 int arg_count,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 } 1059 }
1019 } 1060 }
1020 } 1061 }
1021 1062
1022 1063
1023 Result VirtualFrame::Pop() { 1064 Result VirtualFrame::Pop() {
1024 FrameElement element = elements_.RemoveLast(); 1065 FrameElement element = elements_.RemoveLast();
1025 int index = element_count(); 1066 int index = element_count();
1026 ASSERT(element.is_valid()); 1067 ASSERT(element.is_valid());
1027 1068
1069 // Get number type information of the result.
1070 NumberInfo::Type info;
1071 if (!element.is_copy()) {
1072 info = element.number_info();
1073 } else {
1074 info = elements_[element.index()].number_info();
1075 }
1076
1028 bool pop_needed = (stack_pointer_ == index); 1077 bool pop_needed = (stack_pointer_ == index);
1029 if (pop_needed) { 1078 if (pop_needed) {
1030 stack_pointer_--; 1079 stack_pointer_--;
1031 if (element.is_memory()) { 1080 if (element.is_memory()) {
1032 Result temp = cgen()->allocator()->Allocate(); 1081 Result temp = cgen()->allocator()->Allocate();
1033 ASSERT(temp.is_valid()); 1082 ASSERT(temp.is_valid());
1034 __ pop(temp.reg()); 1083 __ pop(temp.reg());
1084 temp.set_number_info(info);
1035 return temp; 1085 return temp;
1036 } 1086 }
1037 1087
1038 __ add(Operand(esp), Immediate(kPointerSize)); 1088 __ add(Operand(esp), Immediate(kPointerSize));
1039 } 1089 }
1040 ASSERT(!element.is_memory()); 1090 ASSERT(!element.is_memory());
1041 1091
1042 // The top element is a register, constant, or a copy. Unuse 1092 // The top element is a register, constant, or a copy. Unuse
1043 // registers and follow copies to their backing store. 1093 // registers and follow copies to their backing store.
1044 if (element.is_register()) { 1094 if (element.is_register()) {
1045 Unuse(element.reg()); 1095 Unuse(element.reg());
1046 } else if (element.is_copy()) { 1096 } else if (element.is_copy()) {
1047 ASSERT(element.index() < index); 1097 ASSERT(element.index() < index);
1048 index = element.index(); 1098 index = element.index();
1049 element = elements_[index]; 1099 element = elements_[index];
1050 } 1100 }
1051 ASSERT(!element.is_copy()); 1101 ASSERT(!element.is_copy());
1052 1102
1053 // The element is memory, a register, or a constant. 1103 // The element is memory, a register, or a constant.
1054 if (element.is_memory()) { 1104 if (element.is_memory()) {
1055 // Memory elements could only be the backing store of a copy. 1105 // Memory elements could only be the backing store of a copy.
1056 // Allocate the original to a register. 1106 // Allocate the original to a register.
1057 ASSERT(index <= stack_pointer_); 1107 ASSERT(index <= stack_pointer_);
1058 Result temp = cgen()->allocator()->Allocate(); 1108 Result temp = cgen()->allocator()->Allocate();
1059 ASSERT(temp.is_valid()); 1109 ASSERT(temp.is_valid());
1060 Use(temp.reg(), index); 1110 Use(temp.reg(), index);
1061 FrameElement new_element = 1111 FrameElement new_element =
1062 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); 1112 FrameElement::RegisterElement(temp.reg(),
1113 FrameElement::SYNCED,
1114 element.number_info());
1063 // Preserve the copy flag on the element. 1115 // Preserve the copy flag on the element.
1064 if (element.is_copied()) new_element.set_copied(); 1116 if (element.is_copied()) new_element.set_copied();
1065 elements_[index] = new_element; 1117 elements_[index] = new_element;
1066 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); 1118 __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
1067 return Result(temp.reg()); 1119 return Result(temp.reg(), info);
1068 } else if (element.is_register()) { 1120 } else if (element.is_register()) {
1069 return Result(element.reg()); 1121 return Result(element.reg(), info);
1070 } else { 1122 } else {
1071 ASSERT(element.is_constant()); 1123 ASSERT(element.is_constant());
1072 return Result(element.handle()); 1124 return Result(element.handle());
1073 } 1125 }
1074 } 1126 }
1075 1127
1076 1128
1077 void VirtualFrame::EmitPop(Register reg) { 1129 void VirtualFrame::EmitPop(Register reg) {
1078 ASSERT(stack_pointer_ == element_count() - 1); 1130 ASSERT(stack_pointer_ == element_count() - 1);
1079 stack_pointer_--; 1131 stack_pointer_--;
1080 elements_.RemoveLast(); 1132 elements_.RemoveLast();
1081 __ pop(reg); 1133 __ pop(reg);
1082 } 1134 }
1083 1135
1084 1136
1085 void VirtualFrame::EmitPop(Operand operand) { 1137 void VirtualFrame::EmitPop(Operand operand) {
1086 ASSERT(stack_pointer_ == element_count() - 1); 1138 ASSERT(stack_pointer_ == element_count() - 1);
1087 stack_pointer_--; 1139 stack_pointer_--;
1088 elements_.RemoveLast(); 1140 elements_.RemoveLast();
1089 __ pop(operand); 1141 __ pop(operand);
1090 } 1142 }
1091 1143
1092 1144
1093 void VirtualFrame::EmitPush(Register reg) { 1145 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
1094 ASSERT(stack_pointer_ == element_count() - 1); 1146 ASSERT(stack_pointer_ == element_count() - 1);
1095 elements_.Add(FrameElement::MemoryElement()); 1147 elements_.Add(FrameElement::MemoryElement(info));
1096 stack_pointer_++; 1148 stack_pointer_++;
1097 __ push(reg); 1149 __ push(reg);
1098 } 1150 }
1099 1151
1100 1152
1101 void VirtualFrame::EmitPush(Operand operand) { 1153 void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) {
1102 ASSERT(stack_pointer_ == element_count() - 1); 1154 ASSERT(stack_pointer_ == element_count() - 1);
1103 elements_.Add(FrameElement::MemoryElement()); 1155 elements_.Add(FrameElement::MemoryElement(info));
1104 stack_pointer_++; 1156 stack_pointer_++;
1105 __ push(operand); 1157 __ push(operand);
1106 } 1158 }
1107 1159
1108 1160
1109 void VirtualFrame::EmitPush(Immediate immediate) { 1161 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
1110 ASSERT(stack_pointer_ == element_count() - 1); 1162 ASSERT(stack_pointer_ == element_count() - 1);
1111 elements_.Add(FrameElement::MemoryElement()); 1163 elements_.Add(FrameElement::MemoryElement(info));
1112 stack_pointer_++; 1164 stack_pointer_++;
1113 __ push(immediate); 1165 __ push(immediate);
1114 } 1166 }
1115 1167
1116 1168
1169 void VirtualFrame::Push(Expression* expr) {
1170 ASSERT(expr->IsTrivial());
1171
1172 Literal* lit = expr->AsLiteral();
1173 if (lit != NULL) {
1174 Push(lit->handle());
1175 return;
1176 }
1177
1178 VariableProxy* proxy = expr->AsVariableProxy();
1179 if (proxy != NULL && proxy->is_this()) {
1180 PushParameterAt(-1);
1181 return;
1182 }
1183
1184 UNREACHABLE();
1185 }
1186
1187
1117 #undef __ 1188 #undef __
1118 1189
1119 } } // namespace v8::internal 1190 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698