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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 | 57 |
58 | 58 |
59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, | 59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, |
60 LOperand* spill_operand) { | 60 LOperand* spill_operand) { |
61 ASSERT(spill_operand->IsDoubleStackSlot()); | 61 ASSERT(spill_operand->IsDoubleStackSlot()); |
62 ASSERT(double_register_spills_[allocation_index] == NULL); | 62 ASSERT(double_register_spills_[allocation_index] == NULL); |
63 double_register_spills_[allocation_index] = spill_operand; | 63 double_register_spills_[allocation_index] = spill_operand; |
64 } | 64 } |
65 | 65 |
66 | 66 |
67 void LInstruction::PrintTo(StringStream* stream) const { | 67 void LInstruction::PrintTo(StringStream* stream) { |
68 stream->Add("%s ", this->Mnemonic()); | 68 stream->Add("%s ", this->Mnemonic()); |
69 if (HasResult()) { | 69 if (HasResult()) { |
70 result()->PrintTo(stream); | 70 LTemplateInstruction<1>::cast(this)->result()->PrintTo(stream); |
71 stream->Add(" "); | 71 stream->Add(" "); |
72 } | 72 } |
73 PrintDataTo(stream); | 73 PrintDataTo(stream); |
74 | 74 |
75 if (HasEnvironment()) { | 75 if (HasEnvironment()) { |
76 stream->Add(" "); | 76 stream->Add(" "); |
77 environment()->PrintTo(stream); | 77 environment()->PrintTo(stream); |
78 } | 78 } |
79 | 79 |
80 if (HasPointerMap()) { | 80 if (HasPointerMap()) { |
81 stream->Add(" "); | 81 stream->Add(" "); |
82 pointer_map()->PrintTo(stream); | 82 pointer_map()->PrintTo(stream); |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 void LLabel::PrintDataTo(StringStream* stream) const { | 87 void LLabel::PrintDataTo(StringStream* stream) { |
88 LGap::PrintDataTo(stream); | 88 LGap::PrintDataTo(stream); |
89 LLabel* rep = replacement(); | 89 LLabel* rep = replacement(); |
90 if (rep != NULL) { | 90 if (rep != NULL) { |
91 stream->Add(" Dead block replaced with B%d", rep->block_id()); | 91 stream->Add(" Dead block replaced with B%d", rep->block_id()); |
92 } | 92 } |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 bool LParallelMove::IsRedundant() const { | 96 bool LParallelMove::IsRedundant() const { |
97 for (int i = 0; i < move_operands_.length(); ++i) { | 97 for (int i = 0; i < move_operands_.length(); ++i) { |
98 if (!move_operands_[i].IsRedundant()) return false; | 98 if (!move_operands_[i].IsRedundant()) return false; |
99 } | 99 } |
100 return true; | 100 return true; |
101 } | 101 } |
102 | 102 |
103 | 103 |
104 void LParallelMove::PrintDataTo(StringStream* stream) const { | 104 void LParallelMove::PrintDataTo(StringStream* stream) { |
105 for (int i = move_operands_.length() - 1; i >= 0; --i) { | 105 for (int i = move_operands_.length() - 1; i >= 0; --i) { |
106 if (!move_operands_[i].IsEliminated()) { | 106 if (!move_operands_[i].IsEliminated()) { |
107 LOperand* from = move_operands_[i].from(); | 107 LOperand* from = move_operands_[i].from(); |
108 LOperand* to = move_operands_[i].to(); | 108 LOperand* to = move_operands_[i].to(); |
109 if (from->Equals(to)) { | 109 if (from->Equals(to)) { |
110 to->PrintTo(stream); | 110 to->PrintTo(stream); |
111 } else { | 111 } else { |
112 to->PrintTo(stream); | 112 to->PrintTo(stream); |
113 stream->Add(" = "); | 113 stream->Add(" = "); |
114 from->PrintTo(stream); | 114 from->PrintTo(stream); |
115 } | 115 } |
116 stream->Add("; "); | 116 stream->Add("; "); |
117 } | 117 } |
118 } | 118 } |
119 } | 119 } |
120 | 120 |
121 | 121 |
122 bool LGap::IsRedundant() const { | 122 bool LGap::IsRedundant() const { |
123 for (int i = 0; i < 4; i++) { | 123 for (int i = 0; i < 4; i++) { |
124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { | 124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { |
125 return false; | 125 return false; |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 return true; | 129 return true; |
130 } | 130 } |
131 | 131 |
132 | 132 |
133 void LGap::PrintDataTo(StringStream* stream) const { | 133 void LGap::PrintDataTo(StringStream* stream) { |
134 for (int i = 0; i < 4; i++) { | 134 for (int i = 0; i < 4; i++) { |
135 stream->Add("("); | 135 stream->Add("("); |
136 if (parallel_moves_[i] != NULL) { | 136 if (parallel_moves_[i] != NULL) { |
137 parallel_moves_[i]->PrintDataTo(stream); | 137 parallel_moves_[i]->PrintDataTo(stream); |
138 } | 138 } |
139 stream->Add(") "); | 139 stream->Add(") "); |
140 } | 140 } |
141 } | 141 } |
142 | 142 |
143 | 143 |
(...skipping 19 matching lines...) Expand all Loading... |
163 case Token::MOD: return "mod-t"; | 163 case Token::MOD: return "mod-t"; |
164 case Token::DIV: return "div-t"; | 164 case Token::DIV: return "div-t"; |
165 default: | 165 default: |
166 UNREACHABLE(); | 166 UNREACHABLE(); |
167 return NULL; | 167 return NULL; |
168 } | 168 } |
169 } | 169 } |
170 | 170 |
171 | 171 |
172 | 172 |
173 void LBinaryOperation::PrintDataTo(StringStream* stream) const { | 173 void LBinaryOperation::PrintDataTo(StringStream* stream) { |
174 stream->Add("= "); | 174 stream->Add("= "); |
175 left()->PrintTo(stream); | 175 left()->PrintTo(stream); |
176 stream->Add(" "); | 176 stream->Add(" "); |
177 right()->PrintTo(stream); | 177 right()->PrintTo(stream); |
178 } | 178 } |
179 | 179 |
180 | 180 |
181 void LGoto::PrintDataTo(StringStream* stream) const { | 181 void LGoto::PrintDataTo(StringStream* stream) { |
182 stream->Add("B%d", block_id()); | 182 stream->Add("B%d", block_id()); |
183 } | 183 } |
184 | 184 |
185 | 185 |
186 void LBranch::PrintDataTo(StringStream* stream) const { | 186 void LBranch::PrintDataTo(StringStream* stream) { |
187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); | 187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); |
188 input()->PrintTo(stream); | 188 input()->PrintTo(stream); |
189 } | 189 } |
190 | 190 |
191 | 191 |
192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) const { | 192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { |
193 stream->Add("if "); | 193 stream->Add("if "); |
194 left()->PrintTo(stream); | 194 left()->PrintTo(stream); |
195 stream->Add(" %s ", Token::String(op())); | 195 stream->Add(" %s ", Token::String(op())); |
196 right()->PrintTo(stream); | 196 right()->PrintTo(stream); |
197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
198 } | 198 } |
199 | 199 |
200 | 200 |
201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) const { | 201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) { |
202 stream->Add("if "); | 202 stream->Add("if "); |
203 input()->PrintTo(stream); | 203 input()->PrintTo(stream); |
204 stream->Add(is_strict() ? " === null" : " == null"); | 204 stream->Add(is_strict() ? " === null" : " == null"); |
205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); | 205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) const { | 209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { |
210 stream->Add("if is_object("); | 210 stream->Add("if is_object("); |
211 input()->PrintTo(stream); | 211 input()->PrintTo(stream); |
212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
213 } | 213 } |
214 | 214 |
215 | 215 |
216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) const { | 216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { |
217 stream->Add("if is_smi("); | 217 stream->Add("if is_smi("); |
218 input()->PrintTo(stream); | 218 input()->PrintTo(stream); |
219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
220 } | 220 } |
221 | 221 |
222 | 222 |
223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) const { | 223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { |
224 stream->Add("if has_instance_type("); | 224 stream->Add("if has_instance_type("); |
225 input()->PrintTo(stream); | 225 input()->PrintTo(stream); |
226 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 226 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
227 } | 227 } |
228 | 228 |
229 | 229 |
230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) const { | 230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { |
231 stream->Add("if has_cached_array_index("); | 231 stream->Add("if has_cached_array_index("); |
232 input()->PrintTo(stream); | 232 input()->PrintTo(stream); |
233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); | 233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); |
234 } | 234 } |
235 | 235 |
236 | 236 |
237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) const { | 237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { |
238 stream->Add("if class_of_test("); | 238 stream->Add("if class_of_test("); |
239 input()->PrintTo(stream); | 239 input()->PrintTo(stream); |
240 stream->Add(", \"%o\") then B%d else B%d", | 240 stream->Add(", \"%o\") then B%d else B%d", |
241 *hydrogen()->class_name(), | 241 *hydrogen()->class_name(), |
242 true_block_id(), | 242 true_block_id(), |
243 false_block_id()); | 243 false_block_id()); |
244 } | 244 } |
245 | 245 |
246 | 246 |
247 void LTypeofIs::PrintDataTo(StringStream* stream) const { | 247 void LTypeofIs::PrintDataTo(StringStream* stream) { |
248 input()->PrintTo(stream); | 248 input()->PrintTo(stream); |
249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); | 249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); |
250 } | 250 } |
251 | 251 |
252 | 252 |
253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) const { | 253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
254 stream->Add("if typeof "); | 254 stream->Add("if typeof "); |
255 input()->PrintTo(stream); | 255 input()->PrintTo(stream); |
256 stream->Add(" == \"%s\" then B%d else B%d", | 256 stream->Add(" == \"%s\" then B%d else B%d", |
257 *hydrogen()->type_literal()->ToCString(), | 257 *hydrogen()->type_literal()->ToCString(), |
258 true_block_id(), false_block_id()); | 258 true_block_id(), false_block_id()); |
259 } | 259 } |
260 | 260 |
261 | 261 |
262 void LCallConstantFunction::PrintDataTo(StringStream* stream) const { | 262 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
263 stream->Add("#%d / ", arity()); | 263 stream->Add("#%d / ", arity()); |
264 } | 264 } |
265 | 265 |
266 | 266 |
267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) const { | 267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) { |
268 stream->Add("/%s ", hydrogen()->OpName()); | 268 stream->Add("/%s ", hydrogen()->OpName()); |
269 input()->PrintTo(stream); | 269 input()->PrintTo(stream); |
270 } | 270 } |
271 | 271 |
272 | 272 |
273 void LCallKeyed::PrintDataTo(StringStream* stream) const { | 273 void LCallKeyed::PrintDataTo(StringStream* stream) { |
274 stream->Add("[ecx] #%d / ", arity()); | 274 stream->Add("[ecx] #%d / ", arity()); |
275 } | 275 } |
276 | 276 |
277 | 277 |
278 void LCallNamed::PrintDataTo(StringStream* stream) const { | 278 void LCallNamed::PrintDataTo(StringStream* stream) { |
279 SmartPointer<char> name_string = name()->ToCString(); | 279 SmartPointer<char> name_string = name()->ToCString(); |
280 stream->Add("%s #%d / ", *name_string, arity()); | 280 stream->Add("%s #%d / ", *name_string, arity()); |
281 } | 281 } |
282 | 282 |
283 | 283 |
284 void LCallGlobal::PrintDataTo(StringStream* stream) const { | 284 void LCallGlobal::PrintDataTo(StringStream* stream) { |
285 SmartPointer<char> name_string = name()->ToCString(); | 285 SmartPointer<char> name_string = name()->ToCString(); |
286 stream->Add("%s #%d / ", *name_string, arity()); | 286 stream->Add("%s #%d / ", *name_string, arity()); |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { | 290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) { |
291 stream->Add("#%d / ", arity()); | 291 stream->Add("#%d / ", arity()); |
292 } | 292 } |
293 | 293 |
294 | 294 |
295 void LCallNew::PrintDataTo(StringStream* stream) const { | 295 void LCallNew::PrintDataTo(StringStream* stream) { |
296 LUnaryOperation::PrintDataTo(stream); | 296 LUnaryOperation<1>::PrintDataTo(stream); |
297 stream->Add(" #%d / ", arity()); | 297 stream->Add(" #%d / ", arity()); |
298 } | 298 } |
299 | 299 |
300 | 300 |
301 void LClassOfTest::PrintDataTo(StringStream* stream) const { | 301 void LClassOfTest::PrintDataTo(StringStream* stream) { |
302 stream->Add("= class_of_test("); | 302 stream->Add("= class_of_test("); |
303 input()->PrintTo(stream); | 303 input()->PrintTo(stream); |
304 stream->Add(", \"%o\")", *hydrogen()->class_name()); | 304 stream->Add(", \"%o\")", *hydrogen()->class_name()); |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 void LUnaryOperation::PrintDataTo(StringStream* stream) const { | 308 template <int R> |
| 309 void LUnaryOperation<R>::PrintDataTo(StringStream* stream) { |
309 stream->Add("= "); | 310 stream->Add("= "); |
310 input()->PrintTo(stream); | 311 input()->PrintTo(stream); |
311 } | 312 } |
312 | 313 |
313 | 314 |
314 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const { | 315 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) { |
315 arguments()->PrintTo(stream); | 316 arguments()->PrintTo(stream); |
316 | 317 |
317 stream->Add(" length "); | 318 stream->Add(" length "); |
318 length()->PrintTo(stream); | 319 length()->PrintTo(stream); |
319 | 320 |
320 stream->Add(" index "); | 321 stream->Add(" index "); |
321 index()->PrintTo(stream); | 322 index()->PrintTo(stream); |
322 } | 323 } |
323 | 324 |
324 | 325 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 | 375 |
375 if (can_eliminate) { | 376 if (can_eliminate) { |
376 label->set_replacement(GetLabel(goto_instr->block_id())); | 377 label->set_replacement(GetLabel(goto_instr->block_id())); |
377 } | 378 } |
378 } | 379 } |
379 } | 380 } |
380 } | 381 } |
381 } | 382 } |
382 | 383 |
383 | 384 |
384 void LStoreNamed::PrintDataTo(StringStream* stream) const { | 385 void LStoreNamed::PrintDataTo(StringStream* stream) { |
385 object()->PrintTo(stream); | 386 object()->PrintTo(stream); |
386 stream->Add("."); | 387 stream->Add("."); |
387 stream->Add(*String::cast(*name())->ToCString()); | 388 stream->Add(*String::cast(*name())->ToCString()); |
388 stream->Add(" <- "); | 389 stream->Add(" <- "); |
389 value()->PrintTo(stream); | 390 value()->PrintTo(stream); |
390 } | 391 } |
391 | 392 |
392 | 393 |
393 void LStoreKeyed::PrintDataTo(StringStream* stream) const { | 394 void LStoreKeyed::PrintDataTo(StringStream* stream) { |
394 object()->PrintTo(stream); | 395 object()->PrintTo(stream); |
395 stream->Add("["); | 396 stream->Add("["); |
396 key()->PrintTo(stream); | 397 key()->PrintTo(stream); |
397 stream->Add("] <- "); | 398 stream->Add("] <- "); |
398 value()->PrintTo(stream); | 399 value()->PrintTo(stream); |
399 } | 400 } |
400 | 401 |
401 | 402 |
402 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 403 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
403 LGap* gap = new LGap(block); | 404 LGap* gap = new LGap(block); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { | 592 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { |
592 if (value->EmitAtUses()) { | 593 if (value->EmitAtUses()) { |
593 HInstruction* instr = HInstruction::cast(value); | 594 HInstruction* instr = HInstruction::cast(value); |
594 VisitInstruction(instr); | 595 VisitInstruction(instr); |
595 } | 596 } |
596 allocator_->RecordUse(value, operand); | 597 allocator_->RecordUse(value, operand); |
597 return operand; | 598 return operand; |
598 } | 599 } |
599 | 600 |
600 | 601 |
601 LInstruction* LChunkBuilder::Define(LInstruction* instr) { | 602 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr) { |
602 return Define(instr, new LUnallocated(LUnallocated::NONE)); | 603 return Define(instr, new LUnallocated(LUnallocated::NONE)); |
603 } | 604 } |
604 | 605 |
605 | 606 |
606 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { | 607 LInstruction* LChunkBuilder::DefineAsRegister(LTemplateInstruction<1>* instr) { |
607 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); | 608 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); |
608 } | 609 } |
609 | 610 |
610 | 611 |
611 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { | 612 LInstruction* LChunkBuilder::DefineAsSpilled(LTemplateInstruction<1>* instr, |
| 613 int index) { |
612 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); | 614 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); |
613 } | 615 } |
614 | 616 |
615 | 617 |
616 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { | 618 LInstruction* LChunkBuilder::DefineSameAsFirst(LTemplateInstruction<1>* instr) { |
617 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); | 619 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); |
618 } | 620 } |
619 | 621 |
620 | 622 |
621 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { | 623 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1>* instr, |
| 624 Register reg) { |
622 return Define(instr, ToUnallocated(reg)); | 625 return Define(instr, ToUnallocated(reg)); |
623 } | 626 } |
624 | 627 |
625 | 628 |
626 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, | 629 LInstruction* LChunkBuilder::DefineFixedDouble(LTemplateInstruction<1>* instr, |
627 XMMRegister reg) { | 630 XMMRegister reg) { |
628 return Define(instr, ToUnallocated(reg)); | 631 return Define(instr, ToUnallocated(reg)); |
629 } | 632 } |
630 | 633 |
631 | 634 |
632 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 635 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
633 HEnvironment* hydrogen_env = current_block_->last_environment(); | 636 HEnvironment* hydrogen_env = current_block_->last_environment(); |
634 instr->set_environment(CreateEnvironment(hydrogen_env)); | 637 instr->set_environment(CreateEnvironment(hydrogen_env)); |
635 return instr; | 638 return instr; |
636 } | 639 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 688 } |
686 | 689 |
687 | 690 |
688 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { | 691 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { |
689 ASSERT(!instr->HasPointerMap()); | 692 ASSERT(!instr->HasPointerMap()); |
690 instr->set_pointer_map(new LPointerMap(position_)); | 693 instr->set_pointer_map(new LPointerMap(position_)); |
691 return instr; | 694 return instr; |
692 } | 695 } |
693 | 696 |
694 | 697 |
695 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) { | 698 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1>* instr, |
| 699 LUnallocated* result) { |
696 allocator_->RecordDefinition(current_instruction_, result); | 700 allocator_->RecordDefinition(current_instruction_, result); |
697 instr->set_result(result); | 701 instr->set_result(result); |
698 return instr; | 702 return instr; |
699 } | 703 } |
700 | 704 |
701 | 705 |
702 LOperand* LChunkBuilder::Temp() { | 706 LOperand* LChunkBuilder::Temp() { |
703 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); | 707 LUnallocated* operand = new LUnallocated(LUnallocated::NONE); |
704 allocator_->RecordTemporary(operand); | 708 allocator_->RecordTemporary(operand); |
705 return operand; | 709 return operand; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 bool can_truncate = true; | 778 bool can_truncate = true; |
775 for (int i = 0; i < instr->uses()->length(); i++) { | 779 for (int i = 0; i < instr->uses()->length(); i++) { |
776 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { | 780 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { |
777 can_truncate = false; | 781 can_truncate = false; |
778 break; | 782 break; |
779 } | 783 } |
780 } | 784 } |
781 can_deopt = !can_truncate; | 785 can_deopt = !can_truncate; |
782 } | 786 } |
783 | 787 |
784 LInstruction* result = | 788 LShiftI* result = new LShiftI(op, left, right, can_deopt); |
785 DefineSameAsFirst(new LShiftI(op, left, right, can_deopt)); | 789 return can_deopt |
786 if (can_deopt) AssignEnvironment(result); | 790 ? AssignEnvironment(DefineSameAsFirst(result)) |
787 return result; | 791 : DefineSameAsFirst(result); |
788 } | 792 } |
789 | 793 |
790 | 794 |
791 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 795 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
792 HArithmeticBinaryOperation* instr) { | 796 HArithmeticBinaryOperation* instr) { |
793 ASSERT(instr->representation().IsDouble()); | 797 ASSERT(instr->representation().IsDouble()); |
794 ASSERT(instr->left()->representation().IsDouble()); | 798 ASSERT(instr->left()->representation().IsDouble()); |
795 ASSERT(instr->right()->representation().IsDouble()); | 799 ASSERT(instr->right()->representation().IsDouble()); |
796 LOperand* left = UseRegisterAtStart(instr->left()); | 800 LOperand* left = UseRegisterAtStart(instr->left()); |
797 LOperand* right = UseRegisterAtStart(instr->right()); | 801 LOperand* right = UseRegisterAtStart(instr->right()); |
798 LArithmeticD* result = new LArithmeticD(op, left, right); | 802 LArithmeticD* result = new LArithmeticD(op, left, right); |
799 return DefineSameAsFirst(result); | 803 return DefineSameAsFirst(result); |
800 } | 804 } |
801 | 805 |
802 | 806 |
803 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 807 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
804 HArithmeticBinaryOperation* instr) { | 808 HArithmeticBinaryOperation* instr) { |
805 ASSERT(op == Token::ADD || | 809 ASSERT(op == Token::ADD || |
806 op == Token::DIV || | 810 op == Token::DIV || |
807 op == Token::MOD || | 811 op == Token::MOD || |
808 op == Token::MUL || | 812 op == Token::MUL || |
809 op == Token::SUB); | 813 op == Token::SUB); |
810 HValue* left = instr->left(); | 814 HValue* left = instr->left(); |
811 HValue* right = instr->right(); | 815 HValue* right = instr->right(); |
812 ASSERT(left->representation().IsTagged()); | 816 ASSERT(left->representation().IsTagged()); |
813 ASSERT(right->representation().IsTagged()); | 817 ASSERT(right->representation().IsTagged()); |
814 LOperand* left_operand = UseFixed(left, edx); | 818 LOperand* left_operand = UseFixed(left, edx); |
815 LOperand* right_operand = UseFixed(right, eax); | 819 LOperand* right_operand = UseFixed(right, eax); |
816 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); | 820 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); |
817 return MarkAsCall(DefineFixed(result, eax), instr); | 821 return MarkAsCall(DefineFixed(result, eax), instr); |
818 } | 822 } |
819 | 823 |
820 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 824 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
821 ASSERT(is_building()); | 825 ASSERT(is_building()); |
822 current_block_ = block; | 826 current_block_ = block; |
823 next_block_ = next_block; | 827 next_block_ = next_block; |
824 if (block->IsStartBlock()) { | 828 if (block->IsStartBlock()) { |
825 block->UpdateEnvironment(graph_->start_environment()); | 829 block->UpdateEnvironment(graph_->start_environment()); |
826 argument_count_ = 0; | 830 argument_count_ = 0; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 spilled_double_registers_[value->index()], | 944 spilled_double_registers_[value->index()], |
941 false); | 945 false); |
942 } | 946 } |
943 } | 947 } |
944 | 948 |
945 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i)); | 949 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i)); |
946 } | 950 } |
947 } | 951 } |
948 | 952 |
949 | 953 |
950 void LEnvironment::PrintTo(StringStream* stream) const { | 954 void LEnvironment::PrintTo(StringStream* stream) { |
951 stream->Add("[id=%d|", ast_id()); | 955 stream->Add("[id=%d|", ast_id()); |
952 stream->Add("[parameters=%d|", parameter_count()); | 956 stream->Add("[parameters=%d|", parameter_count()); |
953 stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); | 957 stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); |
954 for (int i = 0; i < values_.length(); ++i) { | 958 for (int i = 0; i < values_.length(); ++i) { |
955 if (i != 0) stream->Add(";"); | 959 if (i != 0) stream->Add(";"); |
956 if (values_[i] == NULL) { | 960 if (values_[i] == NULL) { |
957 stream->Add("[hole]"); | 961 stream->Add("[hole]"); |
958 } else { | 962 } else { |
959 values_[i]->PrintTo(stream); | 963 values_[i]->PrintTo(stream); |
960 } | 964 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 } | 996 } |
993 } | 997 } |
994 result->AddValue(op, value->representation()); | 998 result->AddValue(op, value->representation()); |
995 } | 999 } |
996 | 1000 |
997 return result; | 1001 return result; |
998 } | 1002 } |
999 | 1003 |
1000 | 1004 |
1001 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1005 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
1002 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), | 1006 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
1003 instr->include_stack_check()); | 1007 instr->include_stack_check()); |
1004 if (instr->include_stack_check()) result = AssignPointerMap(result); | 1008 return (instr->include_stack_check()) |
1005 return result; | 1009 ? AssignPointerMap(result) |
| 1010 : result; |
1006 } | 1011 } |
1007 | 1012 |
1008 | 1013 |
1009 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1014 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
1010 HValue* v = instr->value(); | 1015 HValue* v = instr->value(); |
1011 HBasicBlock* first = instr->FirstSuccessor(); | 1016 HBasicBlock* first = instr->FirstSuccessor(); |
1012 HBasicBlock* second = instr->SecondSuccessor(); | 1017 HBasicBlock* second = instr->SecondSuccessor(); |
1013 ASSERT(first != NULL && second != NULL); | 1018 ASSERT(first != NULL && second != NULL); |
1014 int first_id = first->block_id(); | 1019 int first_id = first->block_id(); |
1015 int second_id = second->block_id(); | 1020 int second_id = second->block_id(); |
(...skipping 28 matching lines...) Expand all Loading... |
1044 UseRegisterAtStart(right), | 1049 UseRegisterAtStart(right), |
1045 first_id, | 1050 first_id, |
1046 second_id, | 1051 second_id, |
1047 true); | 1052 true); |
1048 } else { | 1053 } else { |
1049 ASSERT(left->representation().IsTagged()); | 1054 ASSERT(left->representation().IsTagged()); |
1050 ASSERT(right->representation().IsTagged()); | 1055 ASSERT(right->representation().IsTagged()); |
1051 bool reversed = op == Token::GT || op == Token::LTE; | 1056 bool reversed = op == Token::GT || op == Token::LTE; |
1052 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); | 1057 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); |
1053 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); | 1058 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); |
1054 LInstruction* result = new LCmpTAndBranch(left_operand, | 1059 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, |
1055 right_operand, | 1060 right_operand, |
1056 first_id, | 1061 first_id, |
1057 second_id); | 1062 second_id); |
1058 return MarkAsCall(result, instr); | 1063 return MarkAsCall(result, instr); |
1059 } | 1064 } |
1060 } else if (v->IsIsSmi()) { | 1065 } else if (v->IsIsSmi()) { |
1061 HIsSmi* compare = HIsSmi::cast(v); | 1066 HIsSmi* compare = HIsSmi::cast(v); |
1062 ASSERT(compare->value()->representation().IsTagged()); | 1067 ASSERT(compare->value()->representation().IsTagged()); |
1063 | 1068 |
1064 return new LIsSmiAndBranch(Use(compare->value()), | 1069 return new LIsSmiAndBranch(Use(compare->value()), |
1065 first_id, | 1070 first_id, |
1066 second_id); | 1071 second_id); |
1067 } else if (v->IsHasInstanceType()) { | 1072 } else if (v->IsHasInstanceType()) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 first_id, | 1106 first_id, |
1102 second_id); | 1107 second_id); |
1103 } else if (v->IsCompareJSObjectEq()) { | 1108 } else if (v->IsCompareJSObjectEq()) { |
1104 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1109 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
1105 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1110 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
1106 UseRegisterAtStart(compare->right()), | 1111 UseRegisterAtStart(compare->right()), |
1107 first_id, | 1112 first_id, |
1108 second_id); | 1113 second_id); |
1109 } else if (v->IsInstanceOf()) { | 1114 } else if (v->IsInstanceOf()) { |
1110 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1115 HInstanceOf* instance_of = HInstanceOf::cast(v); |
1111 LInstruction* result = | 1116 LInstanceOfAndBranch* result = |
1112 new LInstanceOfAndBranch( | 1117 new LInstanceOfAndBranch( |
1113 UseFixed(instance_of->left(), InstanceofStub::left()), | 1118 UseFixed(instance_of->left(), InstanceofStub::left()), |
1114 UseFixed(instance_of->right(), InstanceofStub::right()), | 1119 UseFixed(instance_of->right(), InstanceofStub::right()), |
1115 first_id, | 1120 first_id, |
1116 second_id); | 1121 second_id); |
1117 return MarkAsCall(result, instr); | 1122 return MarkAsCall(result, instr); |
1118 } else if (v->IsTypeofIs()) { | 1123 } else if (v->IsTypeofIs()) { |
1119 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1124 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
1120 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), | 1125 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), |
1121 first_id, | 1126 first_id, |
(...skipping 26 matching lines...) Expand all Loading... |
1148 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1153 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
1149 } | 1154 } |
1150 | 1155 |
1151 | 1156 |
1152 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1157 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
1153 return DefineAsRegister(new LArgumentsElements); | 1158 return DefineAsRegister(new LArgumentsElements); |
1154 } | 1159 } |
1155 | 1160 |
1156 | 1161 |
1157 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1162 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
1158 LInstruction* result = | 1163 LInstanceOf* result = |
1159 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), | 1164 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), |
1160 UseFixed(instr->right(), InstanceofStub::right())); | 1165 UseFixed(instr->right(), InstanceofStub::right())); |
1161 return MarkAsCall(DefineFixed(result, eax), instr); | 1166 return MarkAsCall(DefineFixed(result, eax), instr); |
1162 } | 1167 } |
1163 | 1168 |
1164 | 1169 |
1165 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1170 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
1166 HInstanceOfKnownGlobal* instr) { | 1171 HInstanceOfKnownGlobal* instr) { |
1167 LInstruction* result = | 1172 LInstanceOfKnownGlobal* result = |
1168 new LInstanceOfKnownGlobal( | 1173 new LInstanceOfKnownGlobal( |
1169 UseFixed(instr->value(), InstanceofStub::left()), | 1174 UseFixed(instr->value(), InstanceofStub::left()), |
1170 FixedTemp(edi)); | 1175 FixedTemp(edi)); |
1171 MarkAsSaveDoubles(result); | 1176 MarkAsSaveDoubles(result); |
1172 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); | 1177 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); |
1173 } | 1178 } |
1174 | 1179 |
1175 | 1180 |
1176 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1181 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
1177 LOperand* function = UseFixed(instr->function(), edi); | 1182 LOperand* function = UseFixed(instr->function(), edi); |
1178 LOperand* receiver = UseFixed(instr->receiver(), eax); | 1183 LOperand* receiver = UseFixed(instr->receiver(), eax); |
1179 LOperand* length = UseRegisterAtStart(instr->length()); | 1184 LOperand* length = UseRegisterAtStart(instr->length()); |
1180 LOperand* elements = UseRegisterAtStart(instr->elements()); | 1185 LOperand* elements = UseRegisterAtStart(instr->elements()); |
1181 LInstruction* result = new LApplyArguments(function, | 1186 LApplyArguments* result = new LApplyArguments(function, |
1182 receiver, | 1187 receiver, |
1183 length, | 1188 length, |
1184 elements); | 1189 elements); |
1185 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1190 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
1186 } | 1191 } |
1187 | 1192 |
1188 | 1193 |
1189 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1194 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
1190 ++argument_count_; | 1195 ++argument_count_; |
1191 LOperand* argument = UseOrConstant(instr->argument()); | 1196 LOperand* argument = UseOrConstant(instr->argument()); |
1192 return new LPushArgument(argument); | 1197 return new LPushArgument(argument); |
1193 } | 1198 } |
1194 | 1199 |
(...skipping 12 matching lines...) Expand all Loading... |
1207 HCallConstantFunction* instr) { | 1212 HCallConstantFunction* instr) { |
1208 argument_count_ -= instr->argument_count(); | 1213 argument_count_ -= instr->argument_count(); |
1209 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); | 1214 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); |
1210 } | 1215 } |
1211 | 1216 |
1212 | 1217 |
1213 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1218 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
1214 BuiltinFunctionId op = instr->op(); | 1219 BuiltinFunctionId op = instr->op(); |
1215 if (op == kMathLog || op == kMathSin || op == kMathCos) { | 1220 if (op == kMathLog || op == kMathSin || op == kMathCos) { |
1216 LOperand* input = UseFixedDouble(instr->value(), xmm1); | 1221 LOperand* input = UseFixedDouble(instr->value(), xmm1); |
1217 LInstruction* result = new LUnaryMathOperation(input); | 1222 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
1218 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1223 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
1219 } else { | 1224 } else { |
1220 LOperand* input = UseRegisterAtStart(instr->value()); | 1225 LOperand* input = UseRegisterAtStart(instr->value()); |
1221 LInstruction* result = new LUnaryMathOperation(input); | 1226 LUnaryMathOperation* result = new LUnaryMathOperation(input); |
1222 switch (op) { | 1227 switch (op) { |
1223 case kMathAbs: | 1228 case kMathAbs: |
1224 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1229 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
1225 case kMathFloor: | 1230 case kMathFloor: |
1226 return AssignEnvironment(DefineAsRegister(result)); | 1231 return AssignEnvironment(DefineAsRegister(result)); |
1227 case kMathRound: | 1232 case kMathRound: |
1228 return AssignEnvironment(DefineAsRegister(result)); | 1233 return AssignEnvironment(DefineAsRegister(result)); |
1229 case kMathSqrt: | 1234 case kMathSqrt: |
1230 return DefineSameAsFirst(result); | 1235 return DefineSameAsFirst(result); |
1231 case kMathPowHalf: | 1236 case kMathPowHalf: |
(...skipping 28 matching lines...) Expand all Loading... |
1260 | 1265 |
1261 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1266 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
1262 argument_count_ -= instr->argument_count(); | 1267 argument_count_ -= instr->argument_count(); |
1263 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); | 1268 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); |
1264 } | 1269 } |
1265 | 1270 |
1266 | 1271 |
1267 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1272 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
1268 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1273 LOperand* constructor = UseFixed(instr->constructor(), edi); |
1269 argument_count_ -= instr->argument_count(); | 1274 argument_count_ -= instr->argument_count(); |
1270 LInstruction* result = new LCallNew(constructor); | 1275 LCallNew* result = new LCallNew(constructor); |
1271 return MarkAsCall(DefineFixed(result, eax), instr); | 1276 return MarkAsCall(DefineFixed(result, eax), instr); |
1272 } | 1277 } |
1273 | 1278 |
1274 | 1279 |
1275 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1280 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
1276 argument_count_ -= instr->argument_count(); | 1281 argument_count_ -= instr->argument_count(); |
1277 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); | 1282 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); |
1278 } | 1283 } |
1279 | 1284 |
1280 | 1285 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 | 1345 |
1341 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1346 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1342 if (instr->representation().IsInteger32()) { | 1347 if (instr->representation().IsInteger32()) { |
1343 ASSERT(instr->left()->representation().IsInteger32()); | 1348 ASSERT(instr->left()->representation().IsInteger32()); |
1344 ASSERT(instr->right()->representation().IsInteger32()); | 1349 ASSERT(instr->right()->representation().IsInteger32()); |
1345 // The temporary operand is necessary to ensure that right is not allocated | 1350 // The temporary operand is necessary to ensure that right is not allocated |
1346 // into edx. | 1351 // into edx. |
1347 FixedTemp(edx); | 1352 FixedTemp(edx); |
1348 LOperand* value = UseFixed(instr->left(), eax); | 1353 LOperand* value = UseFixed(instr->left(), eax); |
1349 LOperand* divisor = UseRegister(instr->right()); | 1354 LOperand* divisor = UseRegister(instr->right()); |
1350 LInstruction* result = DefineFixed(new LModI(value, divisor), edx); | 1355 LModI* mod = new LModI(value, divisor); |
1351 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1356 LInstruction* result = DefineFixed(mod, edx); |
1352 instr->CheckFlag(HValue::kCanBeDivByZero)) { | 1357 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1353 result = AssignEnvironment(result); | 1358 instr->CheckFlag(HValue::kCanBeDivByZero)) |
1354 } | 1359 ? AssignEnvironment(result) |
1355 return result; | 1360 : result; |
1356 } else if (instr->representation().IsTagged()) { | 1361 } else if (instr->representation().IsTagged()) { |
1357 return DoArithmeticT(Token::MOD, instr); | 1362 return DoArithmeticT(Token::MOD, instr); |
1358 } else { | 1363 } else { |
1359 ASSERT(instr->representation().IsDouble()); | 1364 ASSERT(instr->representation().IsDouble()); |
1360 // We call a C function for double modulo. It can't trigger a GC. | 1365 // We call a C function for double modulo. It can't trigger a GC. |
1361 // We need to use fixed result register for the call. | 1366 // We need to use fixed result register for the call. |
1362 // TODO(fschneider): Allow any register as input registers. | 1367 // TODO(fschneider): Allow any register as input registers. |
1363 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1368 LOperand* left = UseFixedDouble(instr->left(), xmm1); |
1364 LOperand* right = UseFixedDouble(instr->right(), xmm2); | 1369 LOperand* right = UseFixedDouble(instr->right(), xmm2); |
1365 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); | 1370 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 return DefineAsRegister(new LCmpID(op, left, right, false)); | 1461 return DefineAsRegister(new LCmpID(op, left, right, false)); |
1457 } else if (instr->left()->representation().IsDouble()) { | 1462 } else if (instr->left()->representation().IsDouble()) { |
1458 ASSERT(instr->right()->representation().IsDouble()); | 1463 ASSERT(instr->right()->representation().IsDouble()); |
1459 LOperand* left = UseRegisterAtStart(instr->left()); | 1464 LOperand* left = UseRegisterAtStart(instr->left()); |
1460 LOperand* right = UseRegisterAtStart(instr->right()); | 1465 LOperand* right = UseRegisterAtStart(instr->right()); |
1461 return DefineAsRegister(new LCmpID(op, left, right, true)); | 1466 return DefineAsRegister(new LCmpID(op, left, right, true)); |
1462 } else { | 1467 } else { |
1463 bool reversed = (op == Token::GT || op == Token::LTE); | 1468 bool reversed = (op == Token::GT || op == Token::LTE); |
1464 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); | 1469 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); |
1465 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); | 1470 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); |
1466 LInstruction* result = new LCmpT(left, right); | 1471 LCmpT* result = new LCmpT(left, right); |
1467 return MarkAsCall(DefineFixed(result, eax), instr); | 1472 return MarkAsCall(DefineFixed(result, eax), instr); |
1468 } | 1473 } |
1469 } | 1474 } |
1470 | 1475 |
1471 | 1476 |
1472 LInstruction* LChunkBuilder::DoCompareJSObjectEq( | 1477 LInstruction* LChunkBuilder::DoCompareJSObjectEq( |
1473 HCompareJSObjectEq* instr) { | 1478 HCompareJSObjectEq* instr) { |
1474 LOperand* left = UseRegisterAtStart(instr->left()); | 1479 LOperand* left = UseRegisterAtStart(instr->left()); |
1475 LOperand* right = UseRegisterAtStart(instr->right()); | 1480 LOperand* right = UseRegisterAtStart(instr->right()); |
1476 LInstruction* result = new LCmpJSObjectEq(left, right); | 1481 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right); |
1477 return DefineAsRegister(result); | 1482 return DefineAsRegister(result); |
1478 } | 1483 } |
1479 | 1484 |
1480 | 1485 |
1481 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { | 1486 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { |
1482 ASSERT(instr->value()->representation().IsTagged()); | 1487 ASSERT(instr->value()->representation().IsTagged()); |
1483 LOperand* value = UseRegisterAtStart(instr->value()); | 1488 LOperand* value = UseRegisterAtStart(instr->value()); |
1484 | 1489 |
1485 return DefineAsRegister(new LIsNull(value, | 1490 return DefineAsRegister(new LIsNull(value, |
1486 instr->is_strict())); | 1491 instr->is_strict())); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 | 1540 |
1536 | 1541 |
1537 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1542 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
1538 LOperand* array = UseRegisterAtStart(instr->value()); | 1543 LOperand* array = UseRegisterAtStart(instr->value()); |
1539 return DefineAsRegister(new LFixedArrayLength(array)); | 1544 return DefineAsRegister(new LFixedArrayLength(array)); |
1540 } | 1545 } |
1541 | 1546 |
1542 | 1547 |
1543 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1548 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
1544 LOperand* object = UseRegister(instr->value()); | 1549 LOperand* object = UseRegister(instr->value()); |
1545 LInstruction* result = new LValueOf(object, TempRegister()); | 1550 LValueOf* result = new LValueOf(object, TempRegister()); |
1546 return AssignEnvironment(DefineSameAsFirst(result)); | 1551 return AssignEnvironment(DefineSameAsFirst(result)); |
1547 } | 1552 } |
1548 | 1553 |
1549 | 1554 |
1550 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1555 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
1551 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1556 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
1552 Use(instr->length()))); | 1557 Use(instr->length()))); |
1553 } | 1558 } |
1554 | 1559 |
1555 | 1560 |
1556 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | 1561 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { |
1557 LOperand* value = UseFixed(instr->value(), eax); | 1562 LOperand* value = UseFixed(instr->value(), eax); |
1558 return MarkAsCall(new LThrow(value), instr); | 1563 return MarkAsCall(new LThrow(value), instr); |
1559 } | 1564 } |
1560 | 1565 |
1561 | 1566 |
1562 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1567 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
1563 Representation from = instr->from(); | 1568 Representation from = instr->from(); |
1564 Representation to = instr->to(); | 1569 Representation to = instr->to(); |
1565 if (from.IsTagged()) { | 1570 if (from.IsTagged()) { |
1566 if (to.IsDouble()) { | 1571 if (to.IsDouble()) { |
1567 LOperand* value = UseRegister(instr->value()); | 1572 LOperand* value = UseRegister(instr->value()); |
1568 LInstruction* res = new LNumberUntagD(value); | 1573 LNumberUntagD* res = new LNumberUntagD(value); |
1569 return AssignEnvironment(DefineAsRegister(res)); | 1574 return AssignEnvironment(DefineAsRegister(res)); |
1570 } else { | 1575 } else { |
1571 ASSERT(to.IsInteger32()); | 1576 ASSERT(to.IsInteger32()); |
1572 LOperand* value = UseRegister(instr->value()); | 1577 LOperand* value = UseRegister(instr->value()); |
1573 bool needs_check = !instr->value()->type().IsSmi(); | 1578 bool needs_check = !instr->value()->type().IsSmi(); |
1574 if (needs_check) { | 1579 if (needs_check) { |
1575 LOperand* xmm_temp = | 1580 LOperand* xmm_temp = |
1576 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) | 1581 (instr->CanTruncateToInt32() && CpuFeatures::IsSupported(SSE3)) |
1577 ? NULL | 1582 ? NULL |
1578 : FixedTemp(xmm1); | 1583 : FixedTemp(xmm1); |
1579 LInstruction* res = new LTaggedToI(value, xmm_temp); | 1584 LTaggedToI* res = new LTaggedToI(value, xmm_temp); |
1580 return AssignEnvironment(DefineSameAsFirst(res)); | 1585 return AssignEnvironment(DefineSameAsFirst(res)); |
1581 } else { | 1586 } else { |
1582 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); | 1587 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); |
1583 } | 1588 } |
1584 } | 1589 } |
1585 } else if (from.IsDouble()) { | 1590 } else if (from.IsDouble()) { |
1586 if (to.IsTagged()) { | 1591 if (to.IsTagged()) { |
1587 LOperand* value = UseRegister(instr->value()); | 1592 LOperand* value = UseRegister(instr->value()); |
1588 LOperand* temp = TempRegister(); | 1593 LOperand* temp = TempRegister(); |
1589 | 1594 |
1590 // Make sure that temp and result_temp are different registers. | 1595 // Make sure that temp and result_temp are different registers. |
1591 LUnallocated* result_temp = TempRegister(); | 1596 LUnallocated* result_temp = TempRegister(); |
1592 LInstruction* result = new LNumberTagD(value, temp); | 1597 LNumberTagD* result = new LNumberTagD(value, temp); |
1593 return AssignPointerMap(Define(result, result_temp)); | 1598 return AssignPointerMap(Define(result, result_temp)); |
1594 } else { | 1599 } else { |
1595 ASSERT(to.IsInteger32()); | 1600 ASSERT(to.IsInteger32()); |
1596 LOperand* value = UseRegister(instr->value()); | 1601 LOperand* value = UseRegister(instr->value()); |
1597 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); | 1602 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); |
1598 } | 1603 } |
1599 } else if (from.IsInteger32()) { | 1604 } else if (from.IsInteger32()) { |
1600 if (to.IsTagged()) { | 1605 if (to.IsTagged()) { |
1601 HValue* val = instr->value(); | 1606 HValue* val = instr->value(); |
1602 LOperand* value = UseRegister(val); | 1607 LOperand* value = UseRegister(val); |
1603 if (val->HasRange() && val->range()->IsInSmiRange()) { | 1608 if (val->HasRange() && val->range()->IsInSmiRange()) { |
1604 return DefineSameAsFirst(new LSmiTag(value)); | 1609 return DefineSameAsFirst(new LSmiTag(value)); |
1605 } else { | 1610 } else { |
1606 LInstruction* result = new LNumberTagI(value); | 1611 LNumberTagI* result = new LNumberTagI(value); |
1607 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1612 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
1608 } | 1613 } |
1609 } else { | 1614 } else { |
1610 ASSERT(to.IsDouble()); | 1615 ASSERT(to.IsDouble()); |
1611 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); | 1616 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); |
1612 } | 1617 } |
1613 } | 1618 } |
1614 UNREACHABLE(); | 1619 UNREACHABLE(); |
1615 return NULL; | 1620 return NULL; |
1616 } | 1621 } |
1617 | 1622 |
1618 | 1623 |
1619 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { | 1624 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { |
1620 LOperand* value = UseRegisterAtStart(instr->value()); | 1625 LOperand* value = UseRegisterAtStart(instr->value()); |
1621 return AssignEnvironment(new LCheckSmi(value, zero)); | 1626 return AssignEnvironment(new LCheckSmi(value, zero)); |
1622 } | 1627 } |
1623 | 1628 |
1624 | 1629 |
1625 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1630 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
1626 LOperand* value = UseRegisterAtStart(instr->value()); | 1631 LOperand* value = UseRegisterAtStart(instr->value()); |
1627 LOperand* temp = TempRegister(); | 1632 LOperand* temp = TempRegister(); |
1628 LInstruction* result = new LCheckInstanceType(value, temp); | 1633 LCheckInstanceType* result = new LCheckInstanceType(value, temp); |
1629 return AssignEnvironment(result); | 1634 return AssignEnvironment(result); |
1630 } | 1635 } |
1631 | 1636 |
1632 | 1637 |
1633 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1638 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
1634 LOperand* temp = TempRegister(); | 1639 LOperand* temp = TempRegister(); |
1635 LInstruction* result = | 1640 LCheckPrototypeMaps* result = |
1636 new LCheckPrototypeMaps(temp, | 1641 new LCheckPrototypeMaps(temp, |
1637 instr->holder(), | 1642 instr->holder(), |
1638 instr->receiver_map()); | 1643 instr->receiver_map()); |
1639 return AssignEnvironment(result); | 1644 return AssignEnvironment(result); |
1640 } | 1645 } |
1641 | 1646 |
1642 | 1647 |
1643 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1648 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
1644 LOperand* value = UseRegisterAtStart(instr->value()); | 1649 LOperand* value = UseRegisterAtStart(instr->value()); |
1645 return AssignEnvironment(new LCheckSmi(value, not_zero)); | 1650 return AssignEnvironment(new LCheckSmi(value, not_zero)); |
1646 } | 1651 } |
1647 | 1652 |
1648 | 1653 |
1649 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 1654 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
1650 LOperand* value = UseRegisterAtStart(instr->value()); | 1655 LOperand* value = UseRegisterAtStart(instr->value()); |
1651 return AssignEnvironment(new LCheckFunction(value)); | 1656 return AssignEnvironment(new LCheckFunction(value)); |
1652 } | 1657 } |
1653 | 1658 |
1654 | 1659 |
1655 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { | 1660 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { |
1656 LOperand* value = UseRegisterAtStart(instr->value()); | 1661 LOperand* value = UseRegisterAtStart(instr->value()); |
1657 LInstruction* result = new LCheckMap(value); | 1662 LCheckMap* result = new LCheckMap(value); |
1658 return AssignEnvironment(result); | 1663 return AssignEnvironment(result); |
1659 } | 1664 } |
1660 | 1665 |
1661 | 1666 |
1662 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1667 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
1663 return new LReturn(UseFixed(instr->value(), eax)); | 1668 return new LReturn(UseFixed(instr->value(), eax)); |
1664 } | 1669 } |
1665 | 1670 |
1666 | 1671 |
1667 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1672 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
1668 Representation r = instr->representation(); | 1673 Representation r = instr->representation(); |
1669 if (r.IsInteger32()) { | 1674 if (r.IsInteger32()) { |
1670 int32_t value = instr->Integer32Value(); | 1675 int32_t value = instr->Integer32Value(); |
1671 return DefineAsRegister(new LConstantI(value)); | 1676 return DefineAsRegister(new LConstantI(value)); |
1672 } else if (r.IsDouble()) { | 1677 } else if (r.IsDouble()) { |
1673 double value = instr->DoubleValue(); | 1678 double value = instr->DoubleValue(); |
1674 return DefineAsRegister(new LConstantD(value)); | 1679 return DefineAsRegister(new LConstantD(value)); |
1675 } else if (r.IsTagged()) { | 1680 } else if (r.IsTagged()) { |
1676 return DefineAsRegister(new LConstantT(instr->handle())); | 1681 return DefineAsRegister(new LConstantT(instr->handle())); |
1677 } else { | 1682 } else { |
1678 Abort("unsupported constant of type double"); | 1683 Abort("unsupported constant of type double"); |
1679 return NULL; | 1684 return NULL; |
1680 } | 1685 } |
1681 } | 1686 } |
1682 | 1687 |
1683 | 1688 |
1684 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { | 1689 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { |
1685 LInstruction* result = new LLoadGlobal; | 1690 LLoadGlobal* result = new LLoadGlobal; |
1686 return instr->check_hole_value() | 1691 return instr->check_hole_value() |
1687 ? AssignEnvironment(DefineAsRegister(result)) | 1692 ? AssignEnvironment(DefineAsRegister(result)) |
1688 : DefineAsRegister(result); | 1693 : DefineAsRegister(result); |
1689 } | 1694 } |
1690 | 1695 |
1691 | 1696 |
1692 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { | 1697 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { |
1693 return new LStoreGlobal(UseRegisterAtStart(instr->value())); | 1698 return new LStoreGlobal(UseRegisterAtStart(instr->value())); |
1694 } | 1699 } |
1695 | 1700 |
1696 | 1701 |
1697 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1702 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
1698 return DefineAsRegister( | 1703 return DefineAsRegister( |
1699 new LLoadNamedField(UseRegisterAtStart(instr->object()))); | 1704 new LLoadNamedField(UseRegisterAtStart(instr->object()))); |
1700 } | 1705 } |
1701 | 1706 |
1702 | 1707 |
1703 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1708 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
1704 LOperand* object = UseFixed(instr->object(), eax); | 1709 LOperand* object = UseFixed(instr->object(), eax); |
1705 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); | 1710 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); |
1706 return MarkAsCall(result, instr); | 1711 return MarkAsCall(DefineFixed(result, eax), instr); |
1707 } | 1712 } |
1708 | 1713 |
1709 | 1714 |
1710 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1715 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
1711 HLoadFunctionPrototype* instr) { | 1716 HLoadFunctionPrototype* instr) { |
1712 return AssignEnvironment(DefineAsRegister( | 1717 return AssignEnvironment(DefineAsRegister( |
1713 new LLoadFunctionPrototype(UseRegister(instr->function()), | 1718 new LLoadFunctionPrototype(UseRegister(instr->function()), |
1714 TempRegister()))); | 1719 TempRegister()))); |
1715 } | 1720 } |
1716 | 1721 |
1717 | 1722 |
1718 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1723 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
1719 LOperand* input = UseRegisterAtStart(instr->value()); | 1724 LOperand* input = UseRegisterAtStart(instr->value()); |
1720 return DefineSameAsFirst(new LLoadElements(input)); | 1725 return DefineSameAsFirst(new LLoadElements(input)); |
1721 } | 1726 } |
1722 | 1727 |
1723 | 1728 |
1724 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1729 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
1725 HLoadKeyedFastElement* instr) { | 1730 HLoadKeyedFastElement* instr) { |
1726 Representation r = instr->representation(); | 1731 Representation r = instr->representation(); |
1727 LOperand* obj = UseRegisterAtStart(instr->object()); | 1732 LOperand* obj = UseRegisterAtStart(instr->object()); |
1728 ASSERT(instr->key()->representation().IsInteger32()); | 1733 ASSERT(instr->key()->representation().IsInteger32()); |
1729 LOperand* key = UseRegisterAtStart(instr->key()); | 1734 LOperand* key = UseRegisterAtStart(instr->key()); |
1730 LOperand* load_result = NULL; | 1735 LOperand* load_result = NULL; |
1731 // Double needs an extra temp, because the result is converted from heap | 1736 // Double needs an extra temp, because the result is converted from heap |
1732 // number to a double register. | 1737 // number to a double register. |
1733 if (r.IsDouble()) load_result = TempRegister(); | 1738 if (r.IsDouble()) load_result = TempRegister(); |
1734 LInstruction* result = new LLoadKeyedFastElement(obj, | 1739 LLoadKeyedFastElement* load = new LLoadKeyedFastElement(obj, |
1735 key, | 1740 key, |
1736 load_result); | 1741 load_result); |
1737 if (r.IsDouble()) { | 1742 LInstruction* result = r.IsDouble() |
1738 result = DefineAsRegister(result); | 1743 ? DefineAsRegister(load) |
1739 } else { | 1744 : DefineSameAsFirst(load); |
1740 result = DefineSameAsFirst(result); | |
1741 } | |
1742 return AssignEnvironment(result); | 1745 return AssignEnvironment(result); |
1743 } | 1746 } |
1744 | 1747 |
1745 | 1748 |
1746 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1749 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
1747 LOperand* object = UseFixed(instr->object(), edx); | 1750 LOperand* object = UseFixed(instr->object(), edx); |
1748 LOperand* key = UseFixed(instr->key(), eax); | 1751 LOperand* key = UseFixed(instr->key(), eax); |
1749 | 1752 |
1750 LInstruction* result = | 1753 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); |
1751 DefineFixed(new LLoadKeyedGeneric(object, key), eax); | 1754 return MarkAsCall(DefineFixed(result, eax), instr); |
1752 return MarkAsCall(result, instr); | |
1753 } | 1755 } |
1754 | 1756 |
1755 | 1757 |
1756 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1758 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
1757 HStoreKeyedFastElement* instr) { | 1759 HStoreKeyedFastElement* instr) { |
1758 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1760 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
1759 ASSERT(instr->value()->representation().IsTagged()); | 1761 ASSERT(instr->value()->representation().IsTagged()); |
1760 ASSERT(instr->object()->representation().IsTagged()); | 1762 ASSERT(instr->object()->representation().IsTagged()); |
1761 ASSERT(instr->key()->representation().IsInteger32()); | 1763 ASSERT(instr->key()->representation().IsInteger32()); |
1762 | 1764 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1809 temp, | 1811 temp, |
1810 needs_write_barrier, | 1812 needs_write_barrier, |
1811 instr->transition()); | 1813 instr->transition()); |
1812 } | 1814 } |
1813 | 1815 |
1814 | 1816 |
1815 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1817 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
1816 LOperand* obj = UseFixed(instr->object(), edx); | 1818 LOperand* obj = UseFixed(instr->object(), edx); |
1817 LOperand* val = UseFixed(instr->value(), eax); | 1819 LOperand* val = UseFixed(instr->value(), eax); |
1818 | 1820 |
1819 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); | 1821 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, instr->name(), val); |
1820 return MarkAsCall(result, instr); | 1822 return MarkAsCall(result, instr); |
1821 } | 1823 } |
1822 | 1824 |
1823 | 1825 |
1824 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1826 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
1825 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1827 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
1826 } | 1828 } |
1827 | 1829 |
1828 | 1830 |
1829 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1831 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
1830 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1832 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); |
1831 } | 1833 } |
1832 | 1834 |
1833 | 1835 |
1834 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1836 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
1835 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 1837 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); |
1836 } | 1838 } |
1837 | 1839 |
1838 | 1840 |
1839 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1841 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
1840 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 1842 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); |
1841 } | 1843 } |
1842 | 1844 |
1843 | 1845 |
1844 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1846 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
1845 LInstruction* result = new LDeleteProperty(Use(instr->object()), | 1847 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()), |
1846 UseOrConstant(instr->key())); | 1848 UseOrConstant(instr->key())); |
1847 return MarkAsCall(DefineFixed(result, eax), instr); | 1849 return MarkAsCall(DefineFixed(result, eax), instr); |
1848 } | 1850 } |
1849 | 1851 |
1850 | 1852 |
1851 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1853 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
1852 allocator_->MarkAsOsrEntry(); | 1854 allocator_->MarkAsOsrEntry(); |
1853 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1855 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
1854 return AssignEnvironment(new LOsrEntry); | 1856 return AssignEnvironment(new LOsrEntry); |
1855 } | 1857 } |
1856 | 1858 |
(...skipping 20 matching lines...) Expand all Loading... |
1877 // There are no real uses of the arguments object (we bail out in all other | 1879 // There are no real uses of the arguments object (we bail out in all other |
1878 // cases). | 1880 // cases). |
1879 return NULL; | 1881 return NULL; |
1880 } | 1882 } |
1881 | 1883 |
1882 | 1884 |
1883 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 1885 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
1884 LOperand* arguments = UseRegister(instr->arguments()); | 1886 LOperand* arguments = UseRegister(instr->arguments()); |
1885 LOperand* length = UseTempRegister(instr->length()); | 1887 LOperand* length = UseTempRegister(instr->length()); |
1886 LOperand* index = Use(instr->index()); | 1888 LOperand* index = Use(instr->index()); |
1887 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); | 1889 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
1888 return DefineAsRegister(AssignEnvironment(result)); | 1890 return AssignEnvironment(DefineAsRegister(result)); |
1889 } | 1891 } |
1890 | 1892 |
1891 | 1893 |
1892 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { | 1894 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { |
1893 LInstruction* result = new LTypeof(UseAtStart(instr->value())); | 1895 LTypeof* result = new LTypeof(UseAtStart(instr->value())); |
1894 return MarkAsCall(DefineFixed(result, eax), instr); | 1896 return MarkAsCall(DefineFixed(result, eax), instr); |
1895 } | 1897 } |
1896 | 1898 |
1897 | 1899 |
1898 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { | 1900 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { |
1899 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); | 1901 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); |
1900 } | 1902 } |
1901 | 1903 |
1902 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 1904 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
1903 HEnvironment* env = current_block_->last_environment(); | 1905 HEnvironment* env = current_block_->last_environment(); |
1904 ASSERT(env != NULL); | 1906 ASSERT(env != NULL); |
1905 | 1907 |
1906 env->set_ast_id(instr->ast_id()); | 1908 env->set_ast_id(instr->ast_id()); |
1907 | 1909 |
1908 env->Drop(instr->pop_count()); | 1910 env->Drop(instr->pop_count()); |
1909 for (int i = 0; i < instr->values()->length(); ++i) { | 1911 for (int i = 0; i < instr->values()->length(); ++i) { |
1910 HValue* value = instr->values()->at(i); | 1912 HValue* value = instr->values()->at(i); |
1911 if (instr->HasAssignedIndexAt(i)) { | 1913 if (instr->HasAssignedIndexAt(i)) { |
1912 env->Bind(instr->GetAssignedIndexAt(i), value); | 1914 env->Bind(instr->GetAssignedIndexAt(i), value); |
1913 } else { | 1915 } else { |
1914 env->Push(value); | 1916 env->Push(value); |
1915 } | 1917 } |
1916 } | 1918 } |
1917 ASSERT(env->length() == instr->environment_length()); | 1919 ASSERT(env->length() == instr->environment_length()); |
1918 | 1920 |
1919 // If there is an instruction pending deoptimization environment create a | 1921 // If there is an instruction pending deoptimization environment create a |
1920 // lazy bailout instruction to capture the environment. | 1922 // lazy bailout instruction to capture the environment. |
1921 if (pending_deoptimization_ast_id_ == instr->ast_id()) { | 1923 if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
1922 LInstruction* result = new LLazyBailout; | 1924 LLazyBailout* lazy_bailout = new LLazyBailout; |
1923 result = AssignEnvironment(result); | 1925 LInstruction* result = AssignEnvironment(lazy_bailout); |
1924 instructions_pending_deoptimization_environment_-> | 1926 instructions_pending_deoptimization_environment_-> |
1925 set_deoptimization_environment(result->environment()); | 1927 set_deoptimization_environment(result->environment()); |
1926 ClearInstructionPendingDeoptimizationEnvironment(); | 1928 ClearInstructionPendingDeoptimizationEnvironment(); |
1927 return result; | 1929 return result; |
1928 } | 1930 } |
1929 | 1931 |
1930 return NULL; | 1932 return NULL; |
1931 } | 1933 } |
1932 | 1934 |
1933 | 1935 |
(...skipping 23 matching lines...) Expand all Loading... |
1957 | 1959 |
1958 | 1960 |
1959 void LPointerMap::RecordPointer(LOperand* op) { | 1961 void LPointerMap::RecordPointer(LOperand* op) { |
1960 // Do not record arguments as pointers. | 1962 // Do not record arguments as pointers. |
1961 if (op->IsStackSlot() && op->index() < 0) return; | 1963 if (op->IsStackSlot() && op->index() < 0) return; |
1962 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); | 1964 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); |
1963 pointer_operands_.Add(op); | 1965 pointer_operands_.Add(op); |
1964 } | 1966 } |
1965 | 1967 |
1966 | 1968 |
1967 void LPointerMap::PrintTo(StringStream* stream) const { | 1969 void LPointerMap::PrintTo(StringStream* stream) { |
1968 stream->Add("{"); | 1970 stream->Add("{"); |
1969 for (int i = 0; i < pointer_operands_.length(); ++i) { | 1971 for (int i = 0; i < pointer_operands_.length(); ++i) { |
1970 if (i != 0) stream->Add(";"); | 1972 if (i != 0) stream->Add(";"); |
1971 pointer_operands_[i]->PrintTo(stream); | 1973 pointer_operands_[i]->PrintTo(stream); |
1972 } | 1974 } |
1973 stream->Add("} @%d", position()); | 1975 stream->Add("} @%d", position()); |
1974 } | 1976 } |
1975 | 1977 |
1976 } } // namespace v8::internal | 1978 } } // namespace v8::internal |
OLD | NEW |