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

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

Issue 545007: Introduce number type information in the virtual frame. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: merged with latest rev. 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/jump-target.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 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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 } 1053 }
1045 } 1054 }
1046 } 1055 }
1047 1056
1048 1057
1049 Result VirtualFrame::Pop() { 1058 Result VirtualFrame::Pop() {
1050 FrameElement element = elements_.RemoveLast(); 1059 FrameElement element = elements_.RemoveLast();
1051 int index = element_count(); 1060 int index = element_count();
1052 ASSERT(element.is_valid()); 1061 ASSERT(element.is_valid());
1053 1062
1063 // Get number type information of the result.
1064 NumberInfo::Type info;
1065 if (!element.is_copy()) {
1066 info = element.number_info();
1067 } else {
1068 info = elements_[element.index()].number_info();
1069 }
1070
1054 bool pop_needed = (stack_pointer_ == index); 1071 bool pop_needed = (stack_pointer_ == index);
1055 if (pop_needed) { 1072 if (pop_needed) {
1056 stack_pointer_--; 1073 stack_pointer_--;
1057 if (element.is_memory()) { 1074 if (element.is_memory()) {
1058 Result temp = cgen()->allocator()->Allocate(); 1075 Result temp = cgen()->allocator()->Allocate();
1059 ASSERT(temp.is_valid()); 1076 ASSERT(temp.is_valid());
1060 __ pop(temp.reg()); 1077 __ pop(temp.reg());
1078 temp.set_number_info(info);
1061 return temp; 1079 return temp;
1062 } 1080 }
1063 1081
1064 __ add(Operand(esp), Immediate(kPointerSize)); 1082 __ add(Operand(esp), Immediate(kPointerSize));
1065 } 1083 }
1066 ASSERT(!element.is_memory()); 1084 ASSERT(!element.is_memory());
1067 1085
1068 // The top element is a register, constant, or a copy. Unuse 1086 // The top element is a register, constant, or a copy. Unuse
1069 // registers and follow copies to their backing store. 1087 // registers and follow copies to their backing store.
1070 if (element.is_register()) { 1088 if (element.is_register()) {
1071 Unuse(element.reg()); 1089 Unuse(element.reg());
1072 } else if (element.is_copy()) { 1090 } else if (element.is_copy()) {
1073 ASSERT(element.index() < index); 1091 ASSERT(element.index() < index);
1074 index = element.index(); 1092 index = element.index();
1075 element = elements_[index]; 1093 element = elements_[index];
1076 } 1094 }
1077 ASSERT(!element.is_copy()); 1095 ASSERT(!element.is_copy());
1078 1096
1079 // The element is memory, a register, or a constant. 1097 // The element is memory, a register, or a constant.
1080 if (element.is_memory()) { 1098 if (element.is_memory()) {
1081 // Memory elements could only be the backing store of a copy. 1099 // Memory elements could only be the backing store of a copy.
1082 // Allocate the original to a register. 1100 // Allocate the original to a register.
1083 ASSERT(index <= stack_pointer_); 1101 ASSERT(index <= stack_pointer_);
1084 Result temp = cgen()->allocator()->Allocate(); 1102 Result temp = cgen()->allocator()->Allocate();
1085 ASSERT(temp.is_valid()); 1103 ASSERT(temp.is_valid());
1086 Use(temp.reg(), index); 1104 Use(temp.reg(), index);
1087 FrameElement new_element = 1105 FrameElement new_element =
1088 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); 1106 FrameElement::RegisterElement(temp.reg(),
1107 FrameElement::SYNCED,
1108 element.number_info());
1089 // Preserve the copy flag on the element. 1109 // Preserve the copy flag on the element.
1090 if (element.is_copied()) new_element.set_copied(); 1110 if (element.is_copied()) new_element.set_copied();
1091 elements_[index] = new_element; 1111 elements_[index] = new_element;
1092 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); 1112 __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
1093 return Result(temp.reg()); 1113 return Result(temp.reg(), info);
1094 } else if (element.is_register()) { 1114 } else if (element.is_register()) {
1095 return Result(element.reg()); 1115 return Result(element.reg(), info);
1096 } else { 1116 } else {
1097 ASSERT(element.is_constant()); 1117 ASSERT(element.is_constant());
1098 return Result(element.handle()); 1118 return Result(element.handle());
1099 } 1119 }
1100 } 1120 }
1101 1121
1102 1122
1103 void VirtualFrame::EmitPop(Register reg) { 1123 void VirtualFrame::EmitPop(Register reg) {
1104 ASSERT(stack_pointer_ == element_count() - 1); 1124 ASSERT(stack_pointer_ == element_count() - 1);
1105 stack_pointer_--; 1125 stack_pointer_--;
1106 elements_.RemoveLast(); 1126 elements_.RemoveLast();
1107 __ pop(reg); 1127 __ pop(reg);
1108 } 1128 }
1109 1129
1110 1130
1111 void VirtualFrame::EmitPop(Operand operand) { 1131 void VirtualFrame::EmitPop(Operand operand) {
1112 ASSERT(stack_pointer_ == element_count() - 1); 1132 ASSERT(stack_pointer_ == element_count() - 1);
1113 stack_pointer_--; 1133 stack_pointer_--;
1114 elements_.RemoveLast(); 1134 elements_.RemoveLast();
1115 __ pop(operand); 1135 __ pop(operand);
1116 } 1136 }
1117 1137
1118 1138
1119 void VirtualFrame::EmitPush(Register reg) { 1139 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
1120 ASSERT(stack_pointer_ == element_count() - 1); 1140 ASSERT(stack_pointer_ == element_count() - 1);
1121 elements_.Add(FrameElement::MemoryElement()); 1141 elements_.Add(FrameElement::MemoryElement(info));
1122 stack_pointer_++; 1142 stack_pointer_++;
1123 __ push(reg); 1143 __ push(reg);
1124 } 1144 }
1125 1145
1126 1146
1127 void VirtualFrame::EmitPush(Operand operand) { 1147 void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) {
1128 ASSERT(stack_pointer_ == element_count() - 1); 1148 ASSERT(stack_pointer_ == element_count() - 1);
1129 elements_.Add(FrameElement::MemoryElement()); 1149 elements_.Add(FrameElement::MemoryElement(info));
1130 stack_pointer_++; 1150 stack_pointer_++;
1131 __ push(operand); 1151 __ push(operand);
1132 } 1152 }
1133 1153
1134 1154
1135 void VirtualFrame::EmitPush(Immediate immediate) { 1155 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
1136 ASSERT(stack_pointer_ == element_count() - 1); 1156 ASSERT(stack_pointer_ == element_count() - 1);
1137 elements_.Add(FrameElement::MemoryElement()); 1157 elements_.Add(FrameElement::MemoryElement(info));
1138 stack_pointer_++; 1158 stack_pointer_++;
1139 __ push(immediate); 1159 __ push(immediate);
1140 } 1160 }
1141 1161
1142 1162
1143 #undef __ 1163 #undef __
1144 1164
1145 } } // namespace v8::internal 1165 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | src/jump-target.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698