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

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

Issue 975001: Use untagged int32 values in evaluation of side-effect free expressions. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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/register-allocator.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 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 elements_[top_index] = new_top; 768 elements_[top_index] = new_top;
769 } else { 769 } else {
770 // The stored-to slot holds the same value as the top but 770 // The stored-to slot holds the same value as the top but
771 // unsynced. (We do not have copies of constants yet.) 771 // unsynced. (We do not have copies of constants yet.)
772 ASSERT(top.is_constant()); 772 ASSERT(top.is_constant());
773 elements_[index].clear_sync(); 773 elements_[index].clear_sync();
774 } 774 }
775 } 775 }
776 776
777 777
778 void VirtualFrame::UntaggedPushFrameSlotAt(int index) {
779 ASSERT(index >= 0);
780 ASSERT(index <= element_count());
781 FrameElement original = elements_[index];
782 if (original.is_copy()) {
783 original = elements_[original.index()];
784 index = original.index();
785 }
786
787 switch (original.type()) {
788 case FrameElement::MEMORY:
789 case FrameElement::REGISTER: {
790 Label done;
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.
793 Result fresh = cgen()->allocator()->Allocate();
794 ASSERT(fresh.is_valid());
795 Register fresh_reg = fresh.reg();
796 FrameElement new_element =
797 FrameElement::RegisterElement(fresh_reg,
798 FrameElement::NOT_SYNCED,
799 original.number_info());
800 new_element.set_untagged_int32(true);
801 Use(fresh_reg, element_count());
802 fresh.Unuse(); // BreakTarget does not handle a live Result well.
803 elements_.Add(new_element);
804 if (original.is_register()) {
805 __ mov(fresh_reg, original.reg());
806 } else {
807 ASSERT(original.is_memory());
808 __ mov(fresh_reg, Operand(ebp, fp_relative(index)));
809 }
810 // Now convert the value to int32, or bail out.
811 if (original.number_info().IsSmi()) {
812 __ SmiUntag(fresh_reg);
813 // Pushing the element is completely done.
814 } else {
815 __ test(fresh_reg, Immediate(kSmiTagMask));
816 Label not_smi;
817 __ j(not_zero, &not_smi);
818 __ SmiUntag(fresh_reg);
819 __ jmp(&done);
820
821 __ bind(&not_smi);
822 if (!original.number_info().IsNumber()) {
823 __ cmp(FieldOperand(fresh_reg, HeapObject::kMapOffset),
824 Factory::heap_number_map());
825 cgen()->unsafe_bailout_->Branch(not_equal);
826 }
827
828 if (!CpuFeatures::IsSupported(SSE2)) {
829 UNREACHABLE();
830 } else {
831 CpuFeatures::Scope use_sse2(SSE2);
832 __ movdbl(xmm0, FieldOperand(fresh_reg, HeapNumber::kValueOffset));
833 __ cvttsd2si(fresh_reg, Operand(xmm0));
834 __ cvtsi2sd(xmm1, Operand(fresh_reg));
835 __ ucomisd(xmm0, xmm1);
836 cgen()->unsafe_bailout_->Branch(not_equal);
837 cgen()->unsafe_bailout_->Branch(parity_even); // NaN.
838 // Test for negative zero.
839 __ test(fresh_reg, Operand(fresh_reg));
840 __ j(not_zero, &done);
841 __ movmskpd(fresh_reg, xmm0);
842 __ and_(fresh_reg, 0x1);
843 cgen()->unsafe_bailout_->Branch(not_equal);
844 }
845 __ bind(&done);
846 }
847 break;
848 }
849 case FrameElement::CONSTANT:
850 elements_.Add(CopyElementAt(index));
851 elements_[element_count() - 1].set_untagged_int32(true);
852 break;
853 case FrameElement::COPY:
854 case FrameElement::INVALID:
855 UNREACHABLE();
856 break;
857 }
858 }
859
860
778 void VirtualFrame::PushTryHandler(HandlerType type) { 861 void VirtualFrame::PushTryHandler(HandlerType type) {
779 ASSERT(cgen()->HasValidEntryRegisters()); 862 ASSERT(cgen()->HasValidEntryRegisters());
780 // Grow the expression stack by handler size less one (the return 863 // Grow the expression stack by handler size less one (the return
781 // address is already pushed by a call instruction). 864 // address is already pushed by a call instruction).
782 Adjust(kHandlerSize - 1); 865 Adjust(kHandlerSize - 1);
783 __ PushTryHandler(IN_JAVASCRIPT, type); 866 __ PushTryHandler(IN_JAVASCRIPT, type);
784 } 867 }
785 868
786 869
787 Result VirtualFrame::RawCallStub(CodeStub* stub) { 870 Result VirtualFrame::RawCallStub(CodeStub* stub) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 Unuse(dropped.reg()); 1136 Unuse(dropped.reg());
1054 } 1137 }
1055 } 1138 }
1056 } 1139 }
1057 1140
1058 1141
1059 Result VirtualFrame::Pop() { 1142 Result VirtualFrame::Pop() {
1060 FrameElement element = elements_.RemoveLast(); 1143 FrameElement element = elements_.RemoveLast();
1061 int index = element_count(); 1144 int index = element_count();
1062 ASSERT(element.is_valid()); 1145 ASSERT(element.is_valid());
1146 ASSERT(element.is_untagged_int32() == cgen()->in_safe_int32_mode());
1063 1147
1064 // Get number type information of the result. 1148 // Get number type information of the result.
1065 NumberInfo info; 1149 NumberInfo info;
1066 if (!element.is_copy()) { 1150 if (!element.is_copy()) {
1067 info = element.number_info(); 1151 info = element.number_info();
1068 } else { 1152 } else {
1069 info = elements_[element.index()].number_info(); 1153 info = elements_[element.index()].number_info();
1070 } 1154 }
1071 1155
1072 bool pop_needed = (stack_pointer_ == index); 1156 bool pop_needed = (stack_pointer_ == index);
1073 if (pop_needed) { 1157 if (pop_needed) {
1074 stack_pointer_--; 1158 stack_pointer_--;
1075 if (element.is_memory()) { 1159 if (element.is_memory()) {
1076 Result temp = cgen()->allocator()->Allocate(); 1160 Result temp = cgen()->allocator()->Allocate();
1077 ASSERT(temp.is_valid()); 1161 ASSERT(temp.is_valid());
1078 __ pop(temp.reg()); 1162 __ pop(temp.reg());
1079 temp.set_number_info(info); 1163 temp.set_number_info(info);
1164 temp.set_untagged_int32(element.is_untagged_int32());
1080 return temp; 1165 return temp;
1081 } 1166 }
1082 1167
1083 __ add(Operand(esp), Immediate(kPointerSize)); 1168 __ add(Operand(esp), Immediate(kPointerSize));
1084 } 1169 }
1085 ASSERT(!element.is_memory()); 1170 ASSERT(!element.is_memory());
1086 1171
1087 // The top element is a register, constant, or a copy. Unuse 1172 // The top element is a register, constant, or a copy. Unuse
1088 // registers and follow copies to their backing store. 1173 // registers and follow copies to their backing store.
1089 if (element.is_register()) { 1174 if (element.is_register()) {
1090 Unuse(element.reg()); 1175 Unuse(element.reg());
1091 } else if (element.is_copy()) { 1176 } else if (element.is_copy()) {
1177 ASSERT(!element.is_untagged_int32());
1092 ASSERT(element.index() < index); 1178 ASSERT(element.index() < index);
1093 index = element.index(); 1179 index = element.index();
1094 element = elements_[index]; 1180 element = elements_[index];
1095 } 1181 }
1096 ASSERT(!element.is_copy()); 1182 ASSERT(!element.is_copy());
1097 1183
1098 // The element is memory, a register, or a constant. 1184 // The element is memory, a register, or a constant.
1099 if (element.is_memory()) { 1185 if (element.is_memory()) {
1100 // Memory elements could only be the backing store of a copy. 1186 // Memory elements could only be the backing store of a copy.
1101 // Allocate the original to a register. 1187 // Allocate the original to a register.
1102 ASSERT(index <= stack_pointer_); 1188 ASSERT(index <= stack_pointer_);
1189 ASSERT(!element.is_untagged_int32());
1103 Result temp = cgen()->allocator()->Allocate(); 1190 Result temp = cgen()->allocator()->Allocate();
1104 ASSERT(temp.is_valid()); 1191 ASSERT(temp.is_valid());
1105 Use(temp.reg(), index); 1192 Use(temp.reg(), index);
1106 FrameElement new_element = 1193 FrameElement new_element =
1107 FrameElement::RegisterElement(temp.reg(), 1194 FrameElement::RegisterElement(temp.reg(),
1108 FrameElement::SYNCED, 1195 FrameElement::SYNCED,
1109 element.number_info()); 1196 element.number_info());
1110 // Preserve the copy flag on the element. 1197 // Preserve the copy flag on the element.
1111 if (element.is_copied()) new_element.set_copied(); 1198 if (element.is_copied()) new_element.set_copied();
1112 elements_[index] = new_element; 1199 elements_[index] = new_element;
1113 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); 1200 __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
1114 return Result(temp.reg(), info); 1201 return Result(temp.reg(), info);
1115 } else if (element.is_register()) { 1202 } else if (element.is_register()) {
1116 return Result(element.reg(), info); 1203 Result return_value(element.reg(), info);
1204 return_value.set_untagged_int32(element.is_untagged_int32());
1205 return return_value;
1117 } else { 1206 } else {
1118 ASSERT(element.is_constant()); 1207 ASSERT(element.is_constant());
1119 return Result(element.handle()); 1208 Result return_value(element.handle());
1209 return_value.set_untagged_int32(element.is_untagged_int32());
1210 return return_value;
1120 } 1211 }
1121 } 1212 }
1122 1213
1123 1214
1124 void VirtualFrame::EmitPop(Register reg) { 1215 void VirtualFrame::EmitPop(Register reg) {
1125 ASSERT(stack_pointer_ == element_count() - 1); 1216 ASSERT(stack_pointer_ == element_count() - 1);
1126 stack_pointer_--; 1217 stack_pointer_--;
1127 elements_.RemoveLast(); 1218 elements_.RemoveLast();
1128 __ pop(reg); 1219 __ pop(reg);
1129 } 1220 }
(...skipping 24 matching lines...) Expand all
1154 1245
1155 1246
1156 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) { 1247 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo info) {
1157 ASSERT(stack_pointer_ == element_count() - 1); 1248 ASSERT(stack_pointer_ == element_count() - 1);
1158 elements_.Add(FrameElement::MemoryElement(info)); 1249 elements_.Add(FrameElement::MemoryElement(info));
1159 stack_pointer_++; 1250 stack_pointer_++;
1160 __ push(immediate); 1251 __ push(immediate);
1161 } 1252 }
1162 1253
1163 1254
1255 void VirtualFrame::PushUntaggedElement(Handle<Object> value) {
1256 elements_.Add(FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED));
1257 elements_[element_count() - 1].set_untagged_int32(true);
1258 }
1259
1260
1164 void VirtualFrame::Push(Expression* expr) { 1261 void VirtualFrame::Push(Expression* expr) {
1165 ASSERT(expr->IsTrivial()); 1262 ASSERT(expr->IsTrivial());
1166 1263
1167 Literal* lit = expr->AsLiteral(); 1264 Literal* lit = expr->AsLiteral();
1168 if (lit != NULL) { 1265 if (lit != NULL) {
1169 Push(lit->handle()); 1266 Push(lit->handle());
1170 return; 1267 return;
1171 } 1268 }
1172 1269
1173 VariableProxy* proxy = expr->AsVariableProxy(); 1270 VariableProxy* proxy = expr->AsVariableProxy();
1174 if (proxy != NULL) { 1271 if (proxy != NULL) {
1175 Slot* slot = proxy->var()->slot(); 1272 Slot* slot = proxy->var()->slot();
1176 if (slot->type() == Slot::LOCAL) { 1273 if (slot->type() == Slot::LOCAL) {
1177 PushLocalAt(slot->index()); 1274 PushLocalAt(slot->index());
1178 return; 1275 return;
1179 } 1276 }
1180 if (slot->type() == Slot::PARAMETER) { 1277 if (slot->type() == Slot::PARAMETER) {
1181 PushParameterAt(slot->index()); 1278 PushParameterAt(slot->index());
1182 return; 1279 return;
1183 } 1280 }
1184 } 1281 }
1185 UNREACHABLE(); 1282 UNREACHABLE();
1186 } 1283 }
1187 1284
1188 1285
1189 #undef __ 1286 #undef __
1190 1287
1191 } } // namespace v8::internal 1288 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | src/register-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698