OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 | 83 |
84 if (HasPointerMap()) { | 84 if (HasPointerMap()) { |
85 stream->Add(" "); | 85 stream->Add(" "); |
86 pointer_map()->PrintTo(stream); | 86 pointer_map()->PrintTo(stream); |
87 } | 87 } |
88 } | 88 } |
89 | 89 |
90 | 90 |
91 template<int R, int I, int T> | 91 template<int R, int I, int T> |
92 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { | 92 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) { |
93 for (int i = 0; i < I; i++) { | 93 stream->Add("= "); |
94 stream->Add(i == 0 ? "= " : " "); | 94 inputs_.PrintOperandsTo(stream); |
95 inputs_.at(i)->PrintTo(stream); | |
96 } | |
97 } | 95 } |
98 | 96 |
99 | 97 |
100 template<int R, int I, int T> | 98 template<int R, int I, int T> |
101 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { | 99 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) { |
102 if (this->HasResult()) { | 100 results_.PrintOperandsTo(stream); |
103 this->result()->PrintTo(stream); | 101 } |
104 stream->Add(" "); | 102 |
| 103 |
| 104 template<typename T, int N> |
| 105 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) { |
| 106 for (int i = 0; i < N; i++) { |
| 107 if (i > 0) stream->Add(" "); |
| 108 elems_[i]->PrintTo(stream); |
105 } | 109 } |
106 } | 110 } |
107 | 111 |
108 | 112 |
109 void LLabel::PrintDataTo(StringStream* stream) { | 113 void LLabel::PrintDataTo(StringStream* stream) { |
110 LGap::PrintDataTo(stream); | 114 LGap::PrintDataTo(stream); |
111 LLabel* rep = replacement(); | 115 LLabel* rep = replacement(); |
112 if (rep != NULL) { | 116 if (rep != NULL) { |
113 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 117 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
114 } | 118 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 } | 169 } |
166 | 170 |
167 | 171 |
168 void LGoto::PrintDataTo(StringStream* stream) { | 172 void LGoto::PrintDataTo(StringStream* stream) { |
169 stream->Add("B%d", block_id()); | 173 stream->Add("B%d", block_id()); |
170 } | 174 } |
171 | 175 |
172 | 176 |
173 void LBranch::PrintDataTo(StringStream* stream) { | 177 void LBranch::PrintDataTo(StringStream* stream) { |
174 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 178 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
175 input()->PrintTo(stream); | 179 InputAt(0)->PrintTo(stream); |
176 } | 180 } |
177 | 181 |
178 | 182 |
179 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { | 183 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { |
180 stream->Add("if "); | 184 stream->Add("if "); |
181 left()->PrintTo(stream); | 185 InputAt(0)->PrintTo(stream); |
182 stream->Add(" %s ", Token::String(op())); | 186 stream->Add(" %s ", Token::String(op())); |
183 right()->PrintTo(stream); | 187 InputAt(1)->PrintTo(stream); |
184 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 188 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
185 } | 189 } |
186 | 190 |
187 | 191 |
188 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { | 192 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { |
189 stream->Add("if "); | 193 stream->Add("if "); |
190 input()->PrintTo(stream); | 194 InputAt(0)->PrintTo(stream); |
191 stream->Add(is_strict() ? " === null" : " == null"); | 195 stream->Add(is_strict() ? " === null" : " == null"); |
192 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 196 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
193 } | 197 } |
194 | 198 |
195 | 199 |
196 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { | 200 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
197 stream->Add("if is_object("); | 201 stream->Add("if is_object("); |
198 input()->PrintTo(stream); | 202 InputAt(0)->PrintTo(stream); |
199 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 203 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
200 } | 204 } |
201 | 205 |
202 | 206 |
203 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { | 207 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { |
204 stream->Add("if is_smi("); | 208 stream->Add("if is_smi("); |
205 input()->PrintTo(stream); | 209 InputAt(0)->PrintTo(stream); |
206 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 210 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
207 } | 211 } |
208 | 212 |
209 | 213 |
210 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { | 214 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { |
211 stream->Add("if has_instance_type("); | 215 stream->Add("if has_instance_type("); |
212 input()->PrintTo(stream); | 216 InputAt(0)->PrintTo(stream); |
213 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 217 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
214 } | 218 } |
215 | 219 |
216 | 220 |
217 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { | 221 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { |
218 stream->Add("if has_cached_array_index("); | 222 stream->Add("if has_cached_array_index("); |
219 input()->PrintTo(stream); | 223 InputAt(0)->PrintTo(stream); |
220 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 224 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
221 } | 225 } |
222 | 226 |
223 | 227 |
224 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { | 228 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
225 stream->Add("if class_of_test("); | 229 stream->Add("if class_of_test("); |
226 input()->PrintTo(stream); | 230 InputAt(0)->PrintTo(stream); |
227 stream->Add(", \"%o\") then B%d else B%d", | 231 stream->Add(", \"%o\") then B%d else B%d", |
228 *hydrogen()->class_name(), | 232 *hydrogen()->class_name(), |
229 true_block_id(), | 233 true_block_id(), |
230 false_block_id()); | 234 false_block_id()); |
231 } | 235 } |
232 | 236 |
233 | 237 |
234 void LTypeofIs::PrintDataTo(StringStream* stream) { | 238 void LTypeofIs::PrintDataTo(StringStream* stream) { |
235 input()->PrintTo(stream); | 239 InputAt(0)->PrintTo(stream); |
236 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | 240 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); |
237 } | 241 } |
238 | 242 |
239 | 243 |
240 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 244 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
241 stream->Add("if typeof "); | 245 stream->Add("if typeof "); |
242 input()->PrintTo(stream); | 246 InputAt(0)->PrintTo(stream); |
243 stream->Add(" == \"%s\" then B%d else B%d", | 247 stream->Add(" == \"%s\" then B%d else B%d", |
244 *hydrogen()->type_literal()->ToCString(), | 248 *hydrogen()->type_literal()->ToCString(), |
245 true_block_id(), false_block_id()); | 249 true_block_id(), false_block_id()); |
246 } | 250 } |
247 | 251 |
248 | 252 |
249 void LCallConstantFunction::PrintDataTo(StringStream* stream) { | 253 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
250 stream->Add("#%d / ", arity()); | 254 stream->Add("#%d / ", arity()); |
251 } | 255 } |
252 | 256 |
253 | 257 |
254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { | 258 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
255 stream->Add("/%s ", hydrogen()->OpName()); | 259 stream->Add("/%s ", hydrogen()->OpName()); |
256 input()->PrintTo(stream); | 260 InputAt(0)->PrintTo(stream); |
257 } | 261 } |
258 | 262 |
259 | 263 |
260 void LCallKeyed::PrintDataTo(StringStream* stream) { | 264 void LCallKeyed::PrintDataTo(StringStream* stream) { |
261 stream->Add("[ecx] #%d / ", arity()); | 265 stream->Add("[ecx] #%d / ", arity()); |
262 } | 266 } |
263 | 267 |
264 | 268 |
265 void LCallNamed::PrintDataTo(StringStream* stream) { | 269 void LCallNamed::PrintDataTo(StringStream* stream) { |
266 SmartPointer<char> name_string = name()->ToCString(); | 270 SmartPointer<char> name_string = name()->ToCString(); |
267 stream->Add("%s #%d / ", *name_string, arity()); | 271 stream->Add("%s #%d / ", *name_string, arity()); |
268 } | 272 } |
269 | 273 |
270 | 274 |
271 void LCallGlobal::PrintDataTo(StringStream* stream) { | 275 void LCallGlobal::PrintDataTo(StringStream* stream) { |
272 SmartPointer<char> name_string = name()->ToCString(); | 276 SmartPointer<char> name_string = name()->ToCString(); |
273 stream->Add("%s #%d / ", *name_string, arity()); | 277 stream->Add("%s #%d / ", *name_string, arity()); |
274 } | 278 } |
275 | 279 |
276 | 280 |
277 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { | 281 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { |
278 stream->Add("#%d / ", arity()); | 282 stream->Add("#%d / ", arity()); |
279 } | 283 } |
280 | 284 |
281 | 285 |
282 void LCallNew::PrintDataTo(StringStream* stream) { | 286 void LCallNew::PrintDataTo(StringStream* stream) { |
283 stream->Add("= "); | 287 stream->Add("= "); |
284 input()->PrintTo(stream); | 288 InputAt(0)->PrintTo(stream); |
285 stream->Add(" #%d / ", arity()); | 289 stream->Add(" #%d / ", arity()); |
286 } | 290 } |
287 | 291 |
288 | 292 |
289 void LClassOfTest::PrintDataTo(StringStream* stream) { | 293 void LClassOfTest::PrintDataTo(StringStream* stream) { |
290 stream->Add("= class_of_test("); | 294 stream->Add("= class_of_test("); |
291 input()->PrintTo(stream); | 295 InputAt(0)->PrintTo(stream); |
292 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 296 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
293 } | 297 } |
294 | 298 |
295 | 299 |
296 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { | 300 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
297 arguments()->PrintTo(stream); | 301 arguments()->PrintTo(stream); |
298 | 302 |
299 stream->Add(" length "); | 303 stream->Add(" length "); |
300 length()->PrintTo(stream); | 304 length()->PrintTo(stream); |
301 | 305 |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (current->has_position()) position_ = current->position(); | 875 if (current->has_position()) position_ = current->position(); |
872 LInstruction* instr = current->CompileToLithium(this); | 876 LInstruction* instr = current->CompileToLithium(this); |
873 | 877 |
874 if (instr != NULL) { | 878 if (instr != NULL) { |
875 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 879 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
876 instr = AssignPointerMap(instr); | 880 instr = AssignPointerMap(instr); |
877 } | 881 } |
878 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 882 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
879 instr = AssignEnvironment(instr); | 883 instr = AssignEnvironment(instr); |
880 } | 884 } |
881 if (current->IsBranch()) { | 885 if (current->IsBranch() && !instr->IsGoto()) { |
882 instr->set_hydrogen_value(HBranch::cast(current)->value()); | 886 // TODO(fschneider): Handle branch instructions uniformly like |
| 887 // other instructions. This requires us to generate the right |
| 888 // branch instruction already at the HIR level. |
| 889 ASSERT(instr->IsControl()); |
| 890 HBranch* branch = HBranch::cast(current); |
| 891 instr->set_hydrogen_value(branch->value()); |
| 892 HBasicBlock* first = branch->FirstSuccessor(); |
| 893 HBasicBlock* second = branch->SecondSuccessor(); |
| 894 ASSERT(first != NULL && second != NULL); |
| 895 instr->SetBranchTargets(first->block_id(), second->block_id()); |
883 } else { | 896 } else { |
884 instr->set_hydrogen_value(current); | 897 instr->set_hydrogen_value(current); |
885 } | 898 } |
886 | 899 |
887 int index = chunk_->AddInstruction(instr, current_block_); | 900 int index = chunk_->AddInstruction(instr, current_block_); |
888 allocator_->SummarizeInstruction(index); | 901 allocator_->SummarizeInstruction(index); |
889 } else { | 902 } else { |
890 // This instruction should be omitted. | 903 // This instruction should be omitted. |
891 allocator_->OmitInstruction(); | 904 allocator_->OmitInstruction(); |
892 } | 905 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), | 946 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
934 instr->include_stack_check()); | 947 instr->include_stack_check()); |
935 return (instr->include_stack_check()) | 948 return (instr->include_stack_check()) |
936 ? AssignPointerMap(result) | 949 ? AssignPointerMap(result) |
937 : result; | 950 : result; |
938 } | 951 } |
939 | 952 |
940 | 953 |
941 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 954 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
942 HValue* v = instr->value(); | 955 HValue* v = instr->value(); |
943 HBasicBlock* first = instr->FirstSuccessor(); | |
944 HBasicBlock* second = instr->SecondSuccessor(); | |
945 ASSERT(first != NULL && second != NULL); | |
946 int first_id = first->block_id(); | |
947 int second_id = second->block_id(); | |
948 | |
949 if (v->EmitAtUses()) { | 956 if (v->EmitAtUses()) { |
950 if (v->IsClassOfTest()) { | 957 if (v->IsClassOfTest()) { |
951 HClassOfTest* compare = HClassOfTest::cast(v); | 958 HClassOfTest* compare = HClassOfTest::cast(v); |
952 ASSERT(compare->value()->representation().IsTagged()); | 959 ASSERT(compare->value()->representation().IsTagged()); |
953 | 960 |
954 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), | 961 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), |
955 TempRegister(), | 962 TempRegister(), |
956 TempRegister(), | 963 TempRegister()); |
957 first_id, | |
958 second_id); | |
959 } else if (v->IsCompare()) { | 964 } else if (v->IsCompare()) { |
960 HCompare* compare = HCompare::cast(v); | 965 HCompare* compare = HCompare::cast(v); |
961 Token::Value op = compare->token(); | 966 Token::Value op = compare->token(); |
962 HValue* left = compare->left(); | 967 HValue* left = compare->left(); |
963 HValue* right = compare->right(); | 968 HValue* right = compare->right(); |
964 Representation r = compare->GetInputRepresentation(); | 969 Representation r = compare->GetInputRepresentation(); |
965 if (r.IsInteger32()) { | 970 if (r.IsInteger32()) { |
966 ASSERT(left->representation().IsInteger32()); | 971 ASSERT(left->representation().IsInteger32()); |
967 ASSERT(right->representation().IsInteger32()); | 972 ASSERT(right->representation().IsInteger32()); |
968 | 973 |
969 return new LCmpIDAndBranch(UseRegisterAtStart(left), | 974 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
970 UseOrConstantAtStart(right), | 975 UseOrConstantAtStart(right)); |
971 first_id, | |
972 second_id); | |
973 } else if (r.IsDouble()) { | 976 } else if (r.IsDouble()) { |
974 ASSERT(left->representation().IsDouble()); | 977 ASSERT(left->representation().IsDouble()); |
975 ASSERT(right->representation().IsDouble()); | 978 ASSERT(right->representation().IsDouble()); |
976 | 979 |
977 return new LCmpIDAndBranch(UseRegisterAtStart(left), | 980 return new LCmpIDAndBranch(UseRegisterAtStart(left), |
978 UseRegisterAtStart(right), | 981 UseRegisterAtStart(right)); |
979 first_id, | |
980 second_id); | |
981 } else { | 982 } else { |
982 ASSERT(left->representation().IsTagged()); | 983 ASSERT(left->representation().IsTagged()); |
983 ASSERT(right->representation().IsTagged()); | 984 ASSERT(right->representation().IsTagged()); |
984 bool reversed = op == Token::GT || op == Token::LTE; | 985 bool reversed = op == Token::GT || op == Token::LTE; |
985 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | 986 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); |
986 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | 987 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); |
987 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, | 988 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
988 right_operand, | 989 right_operand); |
989 first_id, | |
990 second_id); | |
991 return MarkAsCall(result, instr); | 990 return MarkAsCall(result, instr); |
992 } | 991 } |
993 } else if (v->IsIsSmi()) { | 992 } else if (v->IsIsSmi()) { |
994 HIsSmi* compare = HIsSmi::cast(v); | 993 HIsSmi* compare = HIsSmi::cast(v); |
995 ASSERT(compare->value()->representation().IsTagged()); | 994 ASSERT(compare->value()->representation().IsTagged()); |
996 | 995 |
997 return new LIsSmiAndBranch(Use(compare->value()), | 996 return new LIsSmiAndBranch(Use(compare->value())); |
998 first_id, | |
999 second_id); | |
1000 } else if (v->IsHasInstanceType()) { | 997 } else if (v->IsHasInstanceType()) { |
1001 HHasInstanceType* compare = HHasInstanceType::cast(v); | 998 HHasInstanceType* compare = HHasInstanceType::cast(v); |
1002 ASSERT(compare->value()->representation().IsTagged()); | 999 ASSERT(compare->value()->representation().IsTagged()); |
1003 | 1000 |
1004 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), | 1001 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), |
1005 TempRegister(), | 1002 TempRegister()); |
1006 first_id, | |
1007 second_id); | |
1008 } else if (v->IsHasCachedArrayIndex()) { | 1003 } else if (v->IsHasCachedArrayIndex()) { |
1009 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); | 1004 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); |
1010 ASSERT(compare->value()->representation().IsTagged()); | 1005 ASSERT(compare->value()->representation().IsTagged()); |
1011 | 1006 |
1012 return new LHasCachedArrayIndexAndBranch( | 1007 return new LHasCachedArrayIndexAndBranch( |
1013 UseRegisterAtStart(compare->value()), first_id, second_id); | 1008 UseRegisterAtStart(compare->value())); |
1014 } else if (v->IsIsNull()) { | 1009 } else if (v->IsIsNull()) { |
1015 HIsNull* compare = HIsNull::cast(v); | 1010 HIsNull* compare = HIsNull::cast(v); |
1016 ASSERT(compare->value()->representation().IsTagged()); | 1011 ASSERT(compare->value()->representation().IsTagged()); |
1017 | 1012 |
1018 // We only need a temp register for non-strict compare. | 1013 // We only need a temp register for non-strict compare. |
1019 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); | 1014 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); |
1020 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), | 1015 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), |
1021 temp, | 1016 temp); |
1022 first_id, | |
1023 second_id); | |
1024 } else if (v->IsIsObject()) { | 1017 } else if (v->IsIsObject()) { |
1025 HIsObject* compare = HIsObject::cast(v); | 1018 HIsObject* compare = HIsObject::cast(v); |
1026 ASSERT(compare->value()->representation().IsTagged()); | 1019 ASSERT(compare->value()->representation().IsTagged()); |
1027 | 1020 |
1028 LOperand* temp1 = TempRegister(); | 1021 LOperand* temp1 = TempRegister(); |
1029 LOperand* temp2 = TempRegister(); | 1022 LOperand* temp2 = TempRegister(); |
1030 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), | 1023 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), |
1031 temp1, | 1024 temp1, |
1032 temp2, | 1025 temp2); |
1033 first_id, | |
1034 second_id); | |
1035 } else if (v->IsCompareJSObjectEq()) { | 1026 } else if (v->IsCompareJSObjectEq()) { |
1036 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1027 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
1037 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1028 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
1038 UseRegisterAtStart(compare->right()), | 1029 UseRegisterAtStart(compare->right())); |
1039 first_id, | |
1040 second_id); | |
1041 } else if (v->IsInstanceOf()) { | 1030 } else if (v->IsInstanceOf()) { |
1042 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1031 HInstanceOf* instance_of = HInstanceOf::cast(v); |
1043 LInstanceOfAndBranch* result = | 1032 LInstanceOfAndBranch* result = |
1044 new LInstanceOfAndBranch( | 1033 new LInstanceOfAndBranch( |
1045 UseFixed(instance_of->left(), InstanceofStub::left()), | 1034 UseFixed(instance_of->left(), InstanceofStub::left()), |
1046 UseFixed(instance_of->right(), InstanceofStub::right()), | 1035 UseFixed(instance_of->right(), InstanceofStub::right())); |
1047 first_id, | |
1048 second_id); | |
1049 return MarkAsCall(result, instr); | 1036 return MarkAsCall(result, instr); |
1050 } else if (v->IsTypeofIs()) { | 1037 } else if (v->IsTypeofIs()) { |
1051 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1038 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
1052 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), | 1039 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
1053 first_id, | |
1054 second_id); | |
1055 } else { | 1040 } else { |
1056 if (v->IsConstant()) { | 1041 if (v->IsConstant()) { |
1057 if (HConstant::cast(v)->handle()->IsTrue()) { | 1042 if (HConstant::cast(v)->handle()->IsTrue()) { |
1058 return new LGoto(first_id); | 1043 return new LGoto(instr->FirstSuccessor()->block_id()); |
1059 } else if (HConstant::cast(v)->handle()->IsFalse()) { | 1044 } else if (HConstant::cast(v)->handle()->IsFalse()) { |
1060 return new LGoto(second_id); | 1045 return new LGoto(instr->SecondSuccessor()->block_id()); |
1061 } | 1046 } |
1062 } | 1047 } |
1063 Abort("Undefined compare before branch"); | 1048 Abort("Undefined compare before branch"); |
1064 return NULL; | 1049 return NULL; |
1065 } | 1050 } |
1066 } | 1051 } |
1067 return new LBranch(UseRegisterAtStart(v), first_id, second_id); | 1052 return new LBranch(UseRegisterAtStart(v)); |
1068 } | 1053 } |
1069 | 1054 |
1070 | 1055 |
1071 LInstruction* LChunkBuilder::DoCompareMapAndBranch( | 1056 LInstruction* LChunkBuilder::DoCompareMapAndBranch( |
1072 HCompareMapAndBranch* instr) { | 1057 HCompareMapAndBranch* instr) { |
1073 ASSERT(instr->value()->representation().IsTagged()); | 1058 ASSERT(instr->value()->representation().IsTagged()); |
1074 LOperand* value = UseRegisterAtStart(instr->value()); | 1059 LOperand* value = UseRegisterAtStart(instr->value()); |
1075 return new LCmpMapAndBranch(value); | 1060 return new LCmpMapAndBranch(value); |
1076 } | 1061 } |
1077 | 1062 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 UNREACHABLE(); | 1151 UNREACHABLE(); |
1167 return NULL; | 1152 return NULL; |
1168 } | 1153 } |
1169 } | 1154 } |
1170 } | 1155 } |
1171 | 1156 |
1172 | 1157 |
1173 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1158 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
1174 ASSERT(instr->key()->representation().IsTagged()); | 1159 ASSERT(instr->key()->representation().IsTagged()); |
1175 argument_count_ -= instr->argument_count(); | 1160 argument_count_ -= instr->argument_count(); |
1176 UseFixed(instr->key(), ecx); | 1161 LOperand* temp = UseFixed(instr->key(), ecx); |
1177 return MarkAsCall(DefineFixed(new LCallKeyed, eax), instr); | 1162 return MarkAsCall(DefineFixed(new LCallKeyed(temp), eax), instr); |
1178 } | 1163 } |
1179 | 1164 |
1180 | 1165 |
1181 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1166 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
1182 argument_count_ -= instr->argument_count(); | 1167 argument_count_ -= instr->argument_count(); |
1183 return MarkAsCall(DefineFixed(new LCallNamed, eax), instr); | 1168 return MarkAsCall(DefineFixed(new LCallNamed, eax), instr); |
1184 } | 1169 } |
1185 | 1170 |
1186 | 1171 |
1187 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1172 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 return DoBit(Token::BIT_XOR, instr); | 1239 return DoBit(Token::BIT_XOR, instr); |
1255 } | 1240 } |
1256 | 1241 |
1257 | 1242 |
1258 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1243 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1259 if (instr->representation().IsDouble()) { | 1244 if (instr->representation().IsDouble()) { |
1260 return DoArithmeticD(Token::DIV, instr); | 1245 return DoArithmeticD(Token::DIV, instr); |
1261 } else if (instr->representation().IsInteger32()) { | 1246 } else if (instr->representation().IsInteger32()) { |
1262 // The temporary operand is necessary to ensure that right is not allocated | 1247 // The temporary operand is necessary to ensure that right is not allocated |
1263 // into edx. | 1248 // into edx. |
1264 FixedTemp(edx); | 1249 LOperand* temp = FixedTemp(edx); |
1265 LOperand* value = UseFixed(instr->left(), eax); | 1250 LOperand* value = UseFixed(instr->left(), eax); |
1266 LOperand* divisor = UseRegister(instr->right()); | 1251 LOperand* divisor = UseRegister(instr->right()); |
1267 return AssignEnvironment(DefineFixed(new LDivI(value, divisor), eax)); | 1252 LDivI* result = new LDivI(value, divisor, temp); |
| 1253 return AssignEnvironment(DefineFixed(result, eax)); |
1268 } else { | 1254 } else { |
1269 ASSERT(instr->representation().IsTagged()); | 1255 ASSERT(instr->representation().IsTagged()); |
1270 return DoArithmeticT(Token::DIV, instr); | 1256 return DoArithmeticT(Token::DIV, instr); |
1271 } | 1257 } |
1272 } | 1258 } |
1273 | 1259 |
1274 | 1260 |
1275 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1261 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1276 if (instr->representation().IsInteger32()) { | 1262 if (instr->representation().IsInteger32()) { |
1277 ASSERT(instr->left()->representation().IsInteger32()); | 1263 ASSERT(instr->left()->representation().IsInteger32()); |
1278 ASSERT(instr->right()->representation().IsInteger32()); | 1264 ASSERT(instr->right()->representation().IsInteger32()); |
1279 // The temporary operand is necessary to ensure that right is not allocated | 1265 // The temporary operand is necessary to ensure that right is not allocated |
1280 // into edx. | 1266 // into edx. |
1281 FixedTemp(edx); | 1267 LOperand* temp = FixedTemp(edx); |
1282 LOperand* value = UseFixed(instr->left(), eax); | 1268 LOperand* value = UseFixed(instr->left(), eax); |
1283 LOperand* divisor = UseRegister(instr->right()); | 1269 LOperand* divisor = UseRegister(instr->right()); |
1284 LModI* mod = new LModI(value, divisor); | 1270 LModI* mod = new LModI(value, divisor, temp); |
1285 LInstruction* result = DefineFixed(mod, edx); | 1271 LInstruction* result = DefineFixed(mod, edx); |
1286 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1272 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1287 instr->CheckFlag(HValue::kCanBeDivByZero)) | 1273 instr->CheckFlag(HValue::kCanBeDivByZero)) |
1288 ? AssignEnvironment(result) | 1274 ? AssignEnvironment(result) |
1289 : result; | 1275 : result; |
1290 } else if (instr->representation().IsTagged()) { | 1276 } else if (instr->representation().IsTagged()) { |
1291 return DoArithmeticT(Token::MOD, instr); | 1277 return DoArithmeticT(Token::MOD, instr); |
1292 } else { | 1278 } else { |
1293 ASSERT(instr->representation().IsDouble()); | 1279 ASSERT(instr->representation().IsDouble()); |
1294 // We call a C function for double modulo. It can't trigger a GC. | 1280 // We call a C function for double modulo. It can't trigger a GC. |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 1859 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
1874 HEnvironment* outer = current_block_->last_environment()->outer(); | 1860 HEnvironment* outer = current_block_->last_environment()->outer(); |
1875 current_block_->UpdateEnvironment(outer); | 1861 current_block_->UpdateEnvironment(outer); |
1876 return NULL; | 1862 return NULL; |
1877 } | 1863 } |
1878 | 1864 |
1879 | 1865 |
1880 } } // namespace v8::internal | 1866 } } // namespace v8::internal |
1881 | 1867 |
1882 #endif // V8_TARGET_ARCH_IA32 | 1868 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |