OLD | NEW |
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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 | 155 |
156 void VirtualFrame::MakeMergable() { | 156 void VirtualFrame::MakeMergable() { |
157 for (int i = 0; i < element_count(); i++) { | 157 for (int i = 0; i < element_count(); i++) { |
158 FrameElement element = elements_[i]; | 158 FrameElement element = elements_[i]; |
159 | 159 |
160 // All number type information is reset to unknown for a mergable frame | 160 // All number type information is reset to unknown for a mergable frame |
161 // because of incoming back edges. | 161 // because of incoming back edges. |
162 if (element.is_constant() || element.is_copy()) { | 162 if (element.is_constant() || element.is_copy()) { |
163 if (element.is_synced()) { | 163 if (element.is_synced()) { |
164 // Just spill. | 164 // Just spill. |
165 elements_[i] = FrameElement::MemoryElement(NumberInfo::Unknown()); | 165 elements_[i] = FrameElement::MemoryElement(TypeInfo::Unknown()); |
166 } else { | 166 } else { |
167 // Allocate to a register. | 167 // Allocate to a register. |
168 FrameElement backing_element; // Invalid if not a copy. | 168 FrameElement backing_element; // Invalid if not a copy. |
169 if (element.is_copy()) { | 169 if (element.is_copy()) { |
170 backing_element = elements_[element.index()]; | 170 backing_element = elements_[element.index()]; |
171 } | 171 } |
172 Result fresh = cgen()->allocator()->Allocate(); | 172 Result fresh = cgen()->allocator()->Allocate(); |
173 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. | 173 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. |
174 elements_[i] = | 174 elements_[i] = |
175 FrameElement::RegisterElement(fresh.reg(), | 175 FrameElement::RegisterElement(fresh.reg(), |
176 FrameElement::NOT_SYNCED, | 176 FrameElement::NOT_SYNCED, |
177 NumberInfo::Unknown()); | 177 TypeInfo::Unknown()); |
178 Use(fresh.reg(), i); | 178 Use(fresh.reg(), i); |
179 | 179 |
180 // Emit a move. | 180 // Emit a move. |
181 if (element.is_constant()) { | 181 if (element.is_constant()) { |
182 if (cgen()->IsUnsafeSmi(element.handle())) { | 182 if (cgen()->IsUnsafeSmi(element.handle())) { |
183 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); | 183 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); |
184 } else { | 184 } else { |
185 __ Set(fresh.reg(), Immediate(element.handle())); | 185 __ Set(fresh.reg(), Immediate(element.handle())); |
186 } | 186 } |
187 } else { | 187 } else { |
(...skipping 12 matching lines...) Expand all Loading... |
200 } | 200 } |
201 } | 201 } |
202 } | 202 } |
203 // No need to set the copied flag --- there are no copies. | 203 // No need to set the copied flag --- there are no copies. |
204 } else { | 204 } else { |
205 // Clear the copy flag of non-constant, non-copy elements. | 205 // Clear the copy flag of non-constant, non-copy elements. |
206 // They cannot be copied because copies are not allowed. | 206 // They cannot be copied because copies are not allowed. |
207 // The copy flag is not relied on before the end of this loop, | 207 // The copy flag is not relied on before the end of this loop, |
208 // including when registers are spilled. | 208 // including when registers are spilled. |
209 elements_[i].clear_copied(); | 209 elements_[i].clear_copied(); |
210 elements_[i].set_number_info(NumberInfo::Unknown()); | 210 elements_[i].set_type_info(TypeInfo::Unknown()); |
211 } | 211 } |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 | 215 |
216 void VirtualFrame::MergeTo(VirtualFrame* expected) { | 216 void VirtualFrame::MergeTo(VirtualFrame* expected) { |
217 Comment cmnt(masm(), "[ Merge frame"); | 217 Comment cmnt(masm(), "[ Merge frame"); |
218 // We should always be merging the code generator's current frame to an | 218 // We should always be merging the code generator's current frame to an |
219 // expected frame. | 219 // expected frame. |
220 ASSERT(cgen()->frame() == this); | 220 ASSERT(cgen()->frame() == this); |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 backing_reg = original.reg(); | 590 backing_reg = original.reg(); |
591 set_register_location(backing_reg, new_backing_index); | 591 set_register_location(backing_reg, new_backing_index); |
592 } | 592 } |
593 // Invalidate the element at index. | 593 // Invalidate the element at index. |
594 elements_[index] = FrameElement::InvalidElement(); | 594 elements_[index] = FrameElement::InvalidElement(); |
595 // Set the new backing element. | 595 // Set the new backing element. |
596 if (elements_[new_backing_index].is_synced()) { | 596 if (elements_[new_backing_index].is_synced()) { |
597 elements_[new_backing_index] = | 597 elements_[new_backing_index] = |
598 FrameElement::RegisterElement(backing_reg, | 598 FrameElement::RegisterElement(backing_reg, |
599 FrameElement::SYNCED, | 599 FrameElement::SYNCED, |
600 original.number_info()); | 600 original.type_info()); |
601 } else { | 601 } else { |
602 elements_[new_backing_index] = | 602 elements_[new_backing_index] = |
603 FrameElement::RegisterElement(backing_reg, | 603 FrameElement::RegisterElement(backing_reg, |
604 FrameElement::NOT_SYNCED, | 604 FrameElement::NOT_SYNCED, |
605 original.number_info()); | 605 original.type_info()); |
606 } | 606 } |
607 // Update the other copies. | 607 // Update the other copies. |
608 for (int i = new_backing_index + 1; i < element_count(); i++) { | 608 for (int i = new_backing_index + 1; i < element_count(); i++) { |
609 if (elements_[i].is_copy() && elements_[i].index() == index) { | 609 if (elements_[i].is_copy() && elements_[i].index() == index) { |
610 elements_[i].set_index(new_backing_index); | 610 elements_[i].set_index(new_backing_index); |
611 elements_[new_backing_index].set_copied(); | 611 elements_[new_backing_index].set_copied(); |
612 } | 612 } |
613 } | 613 } |
614 return new_backing_index; | 614 return new_backing_index; |
615 } | 615 } |
(...skipping 11 matching lines...) Expand all Loading... |
627 | 627 |
628 switch (original.type()) { | 628 switch (original.type()) { |
629 case FrameElement::MEMORY: { | 629 case FrameElement::MEMORY: { |
630 // Emit code to load the original element's data into a register. | 630 // Emit code to load the original element's data into a register. |
631 // Push that register as a FrameElement on top of the frame. | 631 // Push that register as a FrameElement on top of the frame. |
632 Result fresh = cgen()->allocator()->Allocate(); | 632 Result fresh = cgen()->allocator()->Allocate(); |
633 ASSERT(fresh.is_valid()); | 633 ASSERT(fresh.is_valid()); |
634 FrameElement new_element = | 634 FrameElement new_element = |
635 FrameElement::RegisterElement(fresh.reg(), | 635 FrameElement::RegisterElement(fresh.reg(), |
636 FrameElement::NOT_SYNCED, | 636 FrameElement::NOT_SYNCED, |
637 original.number_info()); | 637 original.type_info()); |
638 Use(fresh.reg(), element_count()); | 638 Use(fresh.reg(), element_count()); |
639 elements_.Add(new_element); | 639 elements_.Add(new_element); |
640 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); | 640 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); |
641 break; | 641 break; |
642 } | 642 } |
643 case FrameElement::REGISTER: | 643 case FrameElement::REGISTER: |
644 Use(original.reg(), element_count()); | 644 Use(original.reg(), element_count()); |
645 // Fall through. | 645 // Fall through. |
646 case FrameElement::CONSTANT: | 646 case FrameElement::CONSTANT: |
647 case FrameElement::COPY: | 647 case FrameElement::COPY: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 case FrameElement::REGISTER: { | 789 case FrameElement::REGISTER: { |
790 Label done; | 790 Label done; |
791 // Emit code to load the original element's data into a register. | 791 // Emit code to load the original element's data into a register. |
792 // Push that register as a FrameElement on top of the frame. | 792 // Push that register as a FrameElement on top of the frame. |
793 Result fresh = cgen()->allocator()->Allocate(); | 793 Result fresh = cgen()->allocator()->Allocate(); |
794 ASSERT(fresh.is_valid()); | 794 ASSERT(fresh.is_valid()); |
795 Register fresh_reg = fresh.reg(); | 795 Register fresh_reg = fresh.reg(); |
796 FrameElement new_element = | 796 FrameElement new_element = |
797 FrameElement::RegisterElement(fresh_reg, | 797 FrameElement::RegisterElement(fresh_reg, |
798 FrameElement::NOT_SYNCED, | 798 FrameElement::NOT_SYNCED, |
799 original.number_info()); | 799 original.type_info()); |
800 new_element.set_untagged_int32(true); | 800 new_element.set_untagged_int32(true); |
801 Use(fresh_reg, element_count()); | 801 Use(fresh_reg, element_count()); |
802 fresh.Unuse(); // BreakTarget does not handle a live Result well. | 802 fresh.Unuse(); // BreakTarget does not handle a live Result well. |
803 elements_.Add(new_element); | 803 elements_.Add(new_element); |
804 if (original.is_register()) { | 804 if (original.is_register()) { |
805 __ mov(fresh_reg, original.reg()); | 805 __ mov(fresh_reg, original.reg()); |
806 } else { | 806 } else { |
807 ASSERT(original.is_memory()); | 807 ASSERT(original.is_memory()); |
808 __ mov(fresh_reg, Operand(ebp, fp_relative(index))); | 808 __ mov(fresh_reg, Operand(ebp, fp_relative(index))); |
809 } | 809 } |
810 // Now convert the value to int32, or bail out. | 810 // Now convert the value to int32, or bail out. |
811 if (original.number_info().IsSmi()) { | 811 if (original.type_info().IsSmi()) { |
812 __ SmiUntag(fresh_reg); | 812 __ SmiUntag(fresh_reg); |
813 // Pushing the element is completely done. | 813 // Pushing the element is completely done. |
814 } else { | 814 } else { |
815 __ test(fresh_reg, Immediate(kSmiTagMask)); | 815 __ test(fresh_reg, Immediate(kSmiTagMask)); |
816 Label not_smi; | 816 Label not_smi; |
817 __ j(not_zero, ¬_smi); | 817 __ j(not_zero, ¬_smi); |
818 __ SmiUntag(fresh_reg); | 818 __ SmiUntag(fresh_reg); |
819 __ jmp(&done); | 819 __ jmp(&done); |
820 | 820 |
821 __ bind(¬_smi); | 821 __ bind(¬_smi); |
822 if (!original.number_info().IsNumber()) { | 822 if (!original.type_info().IsNumber()) { |
823 __ cmp(FieldOperand(fresh_reg, HeapObject::kMapOffset), | 823 __ cmp(FieldOperand(fresh_reg, HeapObject::kMapOffset), |
824 Factory::heap_number_map()); | 824 Factory::heap_number_map()); |
825 cgen()->unsafe_bailout_->Branch(not_equal); | 825 cgen()->unsafe_bailout_->Branch(not_equal); |
826 } | 826 } |
827 | 827 |
828 if (!CpuFeatures::IsSupported(SSE2)) { | 828 if (!CpuFeatures::IsSupported(SSE2)) { |
829 UNREACHABLE(); | 829 UNREACHABLE(); |
830 } else { | 830 } else { |
831 CpuFeatures::Scope use_sse2(SSE2); | 831 CpuFeatures::Scope use_sse2(SSE2); |
832 __ movdbl(xmm0, FieldOperand(fresh_reg, HeapNumber::kValueOffset)); | 832 __ movdbl(xmm0, FieldOperand(fresh_reg, HeapNumber::kValueOffset)); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 } | 1139 } |
1140 | 1140 |
1141 | 1141 |
1142 Result VirtualFrame::Pop() { | 1142 Result VirtualFrame::Pop() { |
1143 FrameElement element = elements_.RemoveLast(); | 1143 FrameElement element = elements_.RemoveLast(); |
1144 int index = element_count(); | 1144 int index = element_count(); |
1145 ASSERT(element.is_valid()); | 1145 ASSERT(element.is_valid()); |
1146 ASSERT(element.is_untagged_int32() == cgen()->in_safe_int32_mode()); | 1146 ASSERT(element.is_untagged_int32() == cgen()->in_safe_int32_mode()); |
1147 | 1147 |
1148 // Get number type information of the result. | 1148 // Get number type information of the result. |
1149 NumberInfo info; | 1149 TypeInfo info; |
1150 if (!element.is_copy()) { | 1150 if (!element.is_copy()) { |
1151 info = element.number_info(); | 1151 info = element.type_info(); |
1152 } else { | 1152 } else { |
1153 info = elements_[element.index()].number_info(); | 1153 info = elements_[element.index()].type_info(); |
1154 } | 1154 } |
1155 | 1155 |
1156 bool pop_needed = (stack_pointer_ == index); | 1156 bool pop_needed = (stack_pointer_ == index); |
1157 if (pop_needed) { | 1157 if (pop_needed) { |
1158 stack_pointer_--; | 1158 stack_pointer_--; |
1159 if (element.is_memory()) { | 1159 if (element.is_memory()) { |
1160 Result temp = cgen()->allocator()->Allocate(); | 1160 Result temp = cgen()->allocator()->Allocate(); |
1161 ASSERT(temp.is_valid()); | 1161 ASSERT(temp.is_valid()); |
1162 __ pop(temp.reg()); | 1162 __ pop(temp.reg()); |
1163 temp.set_number_info(info); | 1163 temp.set_type_info(info); |
1164 temp.set_untagged_int32(element.is_untagged_int32()); | 1164 temp.set_untagged_int32(element.is_untagged_int32()); |
1165 return temp; | 1165 return temp; |
1166 } | 1166 } |
1167 | 1167 |
1168 __ add(Operand(esp), Immediate(kPointerSize)); | 1168 __ add(Operand(esp), Immediate(kPointerSize)); |
1169 } | 1169 } |
1170 ASSERT(!element.is_memory()); | 1170 ASSERT(!element.is_memory()); |
1171 | 1171 |
1172 // The top element is a register, constant, or a copy. Unuse | 1172 // The top element is a register, constant, or a copy. Unuse |
1173 // registers and follow copies to their backing store. | 1173 // registers and follow copies to their backing store. |
(...skipping 12 matching lines...) Expand all Loading... |
1186 // Memory elements could only be the backing store of a copy. | 1186 // Memory elements could only be the backing store of a copy. |
1187 // Allocate the original to a register. | 1187 // Allocate the original to a register. |
1188 ASSERT(index <= stack_pointer_); | 1188 ASSERT(index <= stack_pointer_); |
1189 ASSERT(!element.is_untagged_int32()); | 1189 ASSERT(!element.is_untagged_int32()); |
1190 Result temp = cgen()->allocator()->Allocate(); | 1190 Result temp = cgen()->allocator()->Allocate(); |
1191 ASSERT(temp.is_valid()); | 1191 ASSERT(temp.is_valid()); |
1192 Use(temp.reg(), index); | 1192 Use(temp.reg(), index); |
1193 FrameElement new_element = | 1193 FrameElement new_element = |
1194 FrameElement::RegisterElement(temp.reg(), | 1194 FrameElement::RegisterElement(temp.reg(), |
1195 FrameElement::SYNCED, | 1195 FrameElement::SYNCED, |
1196 element.number_info()); | 1196 element.type_info()); |
1197 // Preserve the copy flag on the element. | 1197 // Preserve the copy flag on the element. |
1198 if (element.is_copied()) new_element.set_copied(); | 1198 if (element.is_copied()) new_element.set_copied(); |
1199 elements_[index] = new_element; | 1199 elements_[index] = new_element; |
1200 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); | 1200 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); |
1201 return Result(temp.reg(), info); | 1201 return Result(temp.reg(), info); |
1202 } else if (element.is_register()) { | 1202 } else if (element.is_register()) { |
1203 Result return_value(element.reg(), info); | 1203 Result return_value(element.reg(), info); |
1204 return_value.set_untagged_int32(element.is_untagged_int32()); | 1204 return_value.set_untagged_int32(element.is_untagged_int32()); |
1205 return return_value; | 1205 return return_value; |
1206 } else { | 1206 } else { |
(...skipping 14 matching lines...) Expand all Loading... |
1221 | 1221 |
1222 | 1222 |
1223 void VirtualFrame::EmitPop(Operand operand) { | 1223 void VirtualFrame::EmitPop(Operand operand) { |
1224 ASSERT(stack_pointer_ == element_count() - 1); | 1224 ASSERT(stack_pointer_ == element_count() - 1); |
1225 stack_pointer_--; | 1225 stack_pointer_--; |
1226 elements_.RemoveLast(); | 1226 elements_.RemoveLast(); |
1227 __ pop(operand); | 1227 __ pop(operand); |
1228 } | 1228 } |
1229 | 1229 |
1230 | 1230 |
1231 void VirtualFrame::EmitPush(Register reg, NumberInfo info) { | 1231 void VirtualFrame::EmitPush(Register reg, TypeInfo info) { |
1232 ASSERT(stack_pointer_ == element_count() - 1); | 1232 ASSERT(stack_pointer_ == element_count() - 1); |
1233 elements_.Add(FrameElement::MemoryElement(info)); | 1233 elements_.Add(FrameElement::MemoryElement(info)); |
1234 stack_pointer_++; | 1234 stack_pointer_++; |
1235 __ push(reg); | 1235 __ push(reg); |
1236 } | 1236 } |
1237 | 1237 |
1238 | 1238 |
1239 void VirtualFrame::EmitPush(Operand operand, NumberInfo info) { | 1239 void VirtualFrame::EmitPush(Operand operand, TypeInfo info) { |
1240 ASSERT(stack_pointer_ == element_count() - 1); | 1240 ASSERT(stack_pointer_ == element_count() - 1); |
1241 elements_.Add(FrameElement::MemoryElement(info)); | 1241 elements_.Add(FrameElement::MemoryElement(info)); |
1242 stack_pointer_++; | 1242 stack_pointer_++; |
1243 __ push(operand); | 1243 __ push(operand); |
1244 } | 1244 } |
1245 | 1245 |
1246 | 1246 |
1247 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) { | 1247 void VirtualFrame::EmitPush(Immediate immediate, TypeInfo info) { |
1248 ASSERT(stack_pointer_ == element_count() - 1); | 1248 ASSERT(stack_pointer_ == element_count() - 1); |
1249 elements_.Add(FrameElement::MemoryElement(info)); | 1249 elements_.Add(FrameElement::MemoryElement(info)); |
1250 stack_pointer_++; | 1250 stack_pointer_++; |
1251 __ push(immediate); | 1251 __ push(immediate); |
1252 } | 1252 } |
1253 | 1253 |
1254 | 1254 |
1255 void VirtualFrame::PushUntaggedElement(Handle<Object> value) { | 1255 void VirtualFrame::PushUntaggedElement(Handle<Object> value) { |
1256 elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED)); | 1256 elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED)); |
1257 elements_[element_count() - 1].set_untagged_int32(true); | 1257 elements_[element_count() - 1].set_untagged_int32(true); |
(...skipping 21 matching lines...) Expand all Loading... |
1279 return; | 1279 return; |
1280 } | 1280 } |
1281 } | 1281 } |
1282 UNREACHABLE(); | 1282 UNREACHABLE(); |
1283 } | 1283 } |
1284 | 1284 |
1285 | 1285 |
1286 #undef __ | 1286 #undef __ |
1287 | 1287 |
1288 } } // namespace v8::internal | 1288 } } // namespace v8::internal |
OLD | NEW |