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

Side by Side Diff: src/arm/lithium-arm.cc

Issue 6322008: Version 3.0.10... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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 PrintOutputOperandTo(stream);
71 stream->Add(" ");
72 } 71 }
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 template<int R, int I, int T>
88 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
89 stream->Add("= ");
90 inputs_.PrintOperandsTo(stream);
91 }
92
93
94 template<int R, int I, int T>
95 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
96 results_.PrintOperandsTo(stream);
97 }
98
99
100 template<typename T, int N>
101 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
102 for (int i = 0; i < N; i++) {
103 if (i > 0) stream->Add(" ");
104 elems_[i]->PrintTo(stream);
105 }
106 }
107
108
109 void LLabel::PrintDataTo(StringStream* stream) {
88 LGap::PrintDataTo(stream); 110 LGap::PrintDataTo(stream);
89 LLabel* rep = replacement(); 111 LLabel* rep = replacement();
90 if (rep != NULL) { 112 if (rep != NULL) {
91 stream->Add(" Dead block replaced with B%d", rep->block_id()); 113 stream->Add(" Dead block replaced with B%d", rep->block_id());
92 } 114 }
93 } 115 }
94 116
95 117
96 bool LGap::IsRedundant() const { 118 bool LGap::IsRedundant() const {
97 for (int i = 0; i < 4; i++) { 119 for (int i = 0; i < 4; i++) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 case Token::MUL: return "mul-t"; 158 case Token::MUL: return "mul-t";
137 case Token::MOD: return "mod-t"; 159 case Token::MOD: return "mod-t";
138 case Token::DIV: return "div-t"; 160 case Token::DIV: return "div-t";
139 default: 161 default:
140 UNREACHABLE(); 162 UNREACHABLE();
141 return NULL; 163 return NULL;
142 } 164 }
143 } 165 }
144 166
145 167
146 168 void LGoto::PrintDataTo(StringStream* stream) {
147 void LBinaryOperation::PrintDataTo(StringStream* stream) const {
148 stream->Add("= ");
149 left()->PrintTo(stream);
150 stream->Add(" ");
151 right()->PrintTo(stream);
152 }
153
154
155 void LGoto::PrintDataTo(StringStream* stream) const {
156 stream->Add("B%d", block_id()); 169 stream->Add("B%d", block_id());
157 } 170 }
158 171
159 172
160 void LBranch::PrintDataTo(StringStream* stream) const { 173 void LBranch::PrintDataTo(StringStream* stream) {
161 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); 174 stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
162 input()->PrintTo(stream); 175 InputAt(0)->PrintTo(stream);
163 } 176 }
164 177
165 178
166 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) const { 179 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
167 stream->Add("if "); 180 stream->Add("if ");
168 left()->PrintTo(stream); 181 InputAt(0)->PrintTo(stream);
169 stream->Add(" %s ", Token::String(op())); 182 stream->Add(" %s ", Token::String(op()));
170 right()->PrintTo(stream); 183 InputAt(1)->PrintTo(stream);
171 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 184 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
172 } 185 }
173 186
174 187
175 void LIsNullAndBranch::PrintDataTo(StringStream* stream) const { 188 void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
176 stream->Add("if "); 189 stream->Add("if ");
177 input()->PrintTo(stream); 190 InputAt(0)->PrintTo(stream);
178 stream->Add(is_strict() ? " === null" : " == null"); 191 stream->Add(is_strict() ? " === null" : " == null");
179 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 192 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
180 } 193 }
181 194
182 195
183 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) const { 196 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
184 stream->Add("if is_object("); 197 stream->Add("if is_object(");
185 input()->PrintTo(stream); 198 InputAt(0)->PrintTo(stream);
186 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 199 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
187 } 200 }
188 201
189 202
190 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) const { 203 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
191 stream->Add("if is_smi("); 204 stream->Add("if is_smi(");
192 input()->PrintTo(stream); 205 InputAt(0)->PrintTo(stream);
193 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 206 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
194 } 207 }
195 208
196 209
197 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) const { 210 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
198 stream->Add("if has_instance_type("); 211 stream->Add("if has_instance_type(");
199 input()->PrintTo(stream); 212 InputAt(0)->PrintTo(stream);
200 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 213 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
201 } 214 }
202 215
203 216
204 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) const { 217 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
205 stream->Add("if has_cached_array_index("); 218 stream->Add("if has_cached_array_index(");
206 input()->PrintTo(stream); 219 InputAt(0)->PrintTo(stream);
207 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 220 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
208 } 221 }
209 222
210 223
211 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) const { 224 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
212 stream->Add("if class_of_test("); 225 stream->Add("if class_of_test(");
213 input()->PrintTo(stream); 226 InputAt(0)->PrintTo(stream);
214 stream->Add(", \"%o\") then B%d else B%d", 227 stream->Add(", \"%o\") then B%d else B%d",
215 *hydrogen()->class_name(), 228 *hydrogen()->class_name(),
216 true_block_id(), 229 true_block_id(),
217 false_block_id()); 230 false_block_id());
218 } 231 }
219 232
220 233
221 void LTypeofIs::PrintDataTo(StringStream* stream) const { 234 void LTypeofIs::PrintDataTo(StringStream* stream) {
222 input()->PrintTo(stream); 235 InputAt(0)->PrintTo(stream);
223 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); 236 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
224 } 237 }
225 238
226 239
227 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) const { 240 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
228 stream->Add("if typeof "); 241 stream->Add("if typeof ");
229 input()->PrintTo(stream); 242 InputAt(0)->PrintTo(stream);
230 stream->Add(" == \"%s\" then B%d else B%d", 243 stream->Add(" == \"%s\" then B%d else B%d",
231 *hydrogen()->type_literal()->ToCString(), 244 *hydrogen()->type_literal()->ToCString(),
232 true_block_id(), false_block_id()); 245 true_block_id(), false_block_id());
233 } 246 }
234 247
235 248
236 void LCallConstantFunction::PrintDataTo(StringStream* stream) const { 249 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
237 stream->Add("#%d / ", arity()); 250 stream->Add("#%d / ", arity());
238 } 251 }
239 252
240 253
241 void LUnaryMathOperation::PrintDataTo(StringStream* stream) const { 254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
242 stream->Add("/%s ", hydrogen()->OpName()); 255 stream->Add("/%s ", hydrogen()->OpName());
243 input()->PrintTo(stream); 256 InputAt(0)->PrintTo(stream);
244 } 257 }
245 258
246 259
247 void LLoadContextSlot::PrintDataTo(StringStream* stream) { 260 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
248 stream->Add("(%d, %d)", context_chain_length(), slot_index()); 261 stream->Add("(%d, %d)", context_chain_length(), slot_index());
249 } 262 }
250 263
251 264
252 void LCallKeyed::PrintDataTo(StringStream* stream) const { 265 void LCallKeyed::PrintDataTo(StringStream* stream) {
253 stream->Add("[r2] #%d / ", arity()); 266 stream->Add("[r2] #%d / ", arity());
254 } 267 }
255 268
256 269
257 void LCallNamed::PrintDataTo(StringStream* stream) const { 270 void LCallNamed::PrintDataTo(StringStream* stream) {
258 SmartPointer<char> name_string = name()->ToCString(); 271 SmartPointer<char> name_string = name()->ToCString();
259 stream->Add("%s #%d / ", *name_string, arity()); 272 stream->Add("%s #%d / ", *name_string, arity());
260 } 273 }
261 274
262 275
263 void LCallGlobal::PrintDataTo(StringStream* stream) const { 276 void LCallGlobal::PrintDataTo(StringStream* stream) {
264 SmartPointer<char> name_string = name()->ToCString(); 277 SmartPointer<char> name_string = name()->ToCString();
265 stream->Add("%s #%d / ", *name_string, arity()); 278 stream->Add("%s #%d / ", *name_string, arity());
266 } 279 }
267 280
268 281
269 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { 282 void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
270 stream->Add("#%d / ", arity()); 283 stream->Add("#%d / ", arity());
271 } 284 }
272 285
273 286
274 void LCallNew::PrintDataTo(StringStream* stream) const { 287 void LCallNew::PrintDataTo(StringStream* stream) {
275 LUnaryOperation::PrintDataTo(stream); 288 stream->Add("= ");
289 InputAt(0)->PrintTo(stream);
276 stream->Add(" #%d / ", arity()); 290 stream->Add(" #%d / ", arity());
277 } 291 }
278 292
279 293
280 void LClassOfTest::PrintDataTo(StringStream* stream) const { 294 void LClassOfTest::PrintDataTo(StringStream* stream) {
281 stream->Add("= class_of_test("); 295 stream->Add("= class_of_test(");
282 input()->PrintTo(stream); 296 InputAt(0)->PrintTo(stream);
283 stream->Add(", \"%o\")", *hydrogen()->class_name()); 297 stream->Add(", \"%o\")", *hydrogen()->class_name());
284 } 298 }
285 299
286 300
287 void LUnaryOperation::PrintDataTo(StringStream* stream) const { 301 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
288 stream->Add("= ");
289 input()->PrintTo(stream);
290 }
291
292
293 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const {
294 arguments()->PrintTo(stream); 302 arguments()->PrintTo(stream);
295 303
296 stream->Add(" length "); 304 stream->Add(" length ");
297 length()->PrintTo(stream); 305 length()->PrintTo(stream);
298 306
299 stream->Add(" index "); 307 stream->Add(" index ");
300 index()->PrintTo(stream); 308 index()->PrintTo(stream);
301 } 309 }
302 310
303 311
312 void LStoreNamed::PrintDataTo(StringStream* stream) {
313 object()->PrintTo(stream);
314 stream->Add(".");
315 stream->Add(*String::cast(*name())->ToCString());
316 stream->Add(" <- ");
317 value()->PrintTo(stream);
318 }
319
320
321 void LStoreKeyed::PrintDataTo(StringStream* stream) {
322 object()->PrintTo(stream);
323 stream->Add("[");
324 key()->PrintTo(stream);
325 stream->Add("] <- ");
326 value()->PrintTo(stream);
327 }
328
329
304 LChunk::LChunk(HGraph* graph) 330 LChunk::LChunk(HGraph* graph)
305 : spill_slot_count_(0), 331 : spill_slot_count_(0),
306 graph_(graph), 332 graph_(graph),
307 instructions_(32), 333 instructions_(32),
308 pointer_maps_(8), 334 pointer_maps_(8),
309 inlined_closures_(1) { 335 inlined_closures_(1) {
310 } 336 }
311 337
312 338
313 void LChunk::Verify() const {
314 // TODO(twuerthinger): Implement verification for chunk.
315 }
316
317
318 int LChunk::GetNextSpillIndex(bool is_double) { 339 int LChunk::GetNextSpillIndex(bool is_double) {
319 // Skip a slot if for a double-width slot. 340 // Skip a slot if for a double-width slot.
320 if (is_double) spill_slot_count_++; 341 if (is_double) spill_slot_count_++;
321 return spill_slot_count_++; 342 return spill_slot_count_++;
322 } 343 }
323 344
324 345
325 LOperand* LChunk::GetNextSpillSlot(bool is_double) { 346 LOperand* LChunk::GetNextSpillSlot(bool is_double) {
326 int index = GetNextSpillIndex(is_double); 347 int index = GetNextSpillIndex(is_double);
327 if (is_double) { 348 if (is_double) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 383
363 if (can_eliminate) { 384 if (can_eliminate) {
364 label->set_replacement(GetLabel(goto_instr->block_id())); 385 label->set_replacement(GetLabel(goto_instr->block_id()));
365 } 386 }
366 } 387 }
367 } 388 }
368 } 389 }
369 } 390 }
370 391
371 392
372 void LStoreNamed::PrintDataTo(StringStream* stream) const {
373 object()->PrintTo(stream);
374 stream->Add(".");
375 stream->Add(*String::cast(*name())->ToCString());
376 stream->Add(" <- ");
377 value()->PrintTo(stream);
378 }
379
380
381 void LStoreKeyed::PrintDataTo(StringStream* stream) const {
382 object()->PrintTo(stream);
383 stream->Add("[");
384 key()->PrintTo(stream);
385 stream->Add("] <- ");
386 value()->PrintTo(stream);
387 }
388
389
390 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 393 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
391 LGap* gap = new LGap(block); 394 LGap* gap = new LGap(block);
392 int index = -1; 395 int index = -1;
393 if (instr->IsControl()) { 396 if (instr->IsControl()) {
394 instructions_.Add(gap); 397 instructions_.Add(gap);
395 index = instructions_.length(); 398 index = instructions_.length();
396 instructions_.Add(instr); 399 instructions_.Add(instr);
397 } else { 400 } else {
398 index = instructions_.length(); 401 index = instructions_.length();
399 instructions_.Add(instr); 402 instructions_.Add(instr);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { 589 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
587 if (value->EmitAtUses()) { 590 if (value->EmitAtUses()) {
588 HInstruction* instr = HInstruction::cast(value); 591 HInstruction* instr = HInstruction::cast(value);
589 VisitInstruction(instr); 592 VisitInstruction(instr);
590 } 593 }
591 allocator_->RecordUse(value, operand); 594 allocator_->RecordUse(value, operand);
592 return operand; 595 return operand;
593 } 596 }
594 597
595 598
596 LInstruction* LChunkBuilder::Define(LInstruction* instr) { 599 template<int I, int T>
600 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
601 LUnallocated* result) {
602 allocator_->RecordDefinition(current_instruction_, result);
603 instr->set_result(result);
604 return instr;
605 }
606
607
608 template<int I, int T>
609 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr) {
597 return Define(instr, new LUnallocated(LUnallocated::NONE)); 610 return Define(instr, new LUnallocated(LUnallocated::NONE));
598 } 611 }
599 612
600 613
601 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { 614 template<int I, int T>
615 LInstruction* LChunkBuilder::DefineAsRegister(
616 LTemplateInstruction<1, I, T>* instr) {
602 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 617 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
603 } 618 }
604 619
605 620
606 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { 621 template<int I, int T>
622 LInstruction* LChunkBuilder::DefineAsSpilled(
623 LTemplateInstruction<1, I, T>* instr, int index) {
607 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); 624 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index));
608 } 625 }
609 626
610 627
611 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { 628 template<int I, int T>
629 LInstruction* LChunkBuilder::DefineSameAsFirst(
630 LTemplateInstruction<1, I, T>* instr) {
612 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); 631 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
613 } 632 }
614 633
615 634
616 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { 635 template<int I, int T>
636 LInstruction* LChunkBuilder::DefineFixed(
637 LTemplateInstruction<1, I, T>* instr, Register reg) {
617 return Define(instr, ToUnallocated(reg)); 638 return Define(instr, ToUnallocated(reg));
618 } 639 }
619 640
620 641
621 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, 642 template<int I, int T>
622 DoubleRegister reg) { 643 LInstruction* LChunkBuilder::DefineFixedDouble(
644 LTemplateInstruction<1, I, T>* instr, DoubleRegister reg) {
623 return Define(instr, ToUnallocated(reg)); 645 return Define(instr, ToUnallocated(reg));
624 } 646 }
625 647
626 648
627 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 649 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
628 HEnvironment* hydrogen_env = current_block_->last_environment(); 650 HEnvironment* hydrogen_env = current_block_->last_environment();
629 instr->set_environment(CreateEnvironment(hydrogen_env)); 651 instr->set_environment(CreateEnvironment(hydrogen_env));
630 return instr; 652 return instr;
631 } 653 }
632 654
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 bool needs_environment = 689 bool needs_environment =
668 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 690 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
669 if (needs_environment && !instr->HasEnvironment()) { 691 if (needs_environment && !instr->HasEnvironment()) {
670 instr = AssignEnvironment(instr); 692 instr = AssignEnvironment(instr);
671 } 693 }
672 694
673 return instr; 695 return instr;
674 } 696 }
675 697
676 698
699 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
700 allocator_->MarkAsSaveDoubles();
701 return instr;
702 }
703
704
677 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 705 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
678 ASSERT(!instr->HasPointerMap()); 706 ASSERT(!instr->HasPointerMap());
679 instr->set_pointer_map(new LPointerMap(position_)); 707 instr->set_pointer_map(new LPointerMap(position_));
680 return instr; 708 return instr;
681 } 709 }
682 710
683
684 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) {
685 allocator_->RecordDefinition(current_instruction_, result);
686 instr->set_result(result);
687 return instr;
688 }
689
690 711
691 LUnallocated* LChunkBuilder::TempRegister() { 712 LUnallocated* LChunkBuilder::TempRegister() {
692 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER); 713 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
693 allocator_->RecordTemporary(operand); 714 allocator_->RecordTemporary(operand);
694 return operand; 715 return operand;
695 } 716 }
696 717
697 718
698 LOperand* LChunkBuilder::FixedTemp(Register reg) { 719 LOperand* LChunkBuilder::FixedTemp(Register reg) {
699 LUnallocated* operand = ToUnallocated(reg); 720 LUnallocated* operand = ToUnallocated(reg);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 op == Token::DIV || 809 op == Token::DIV ||
789 op == Token::MOD || 810 op == Token::MOD ||
790 op == Token::MUL || 811 op == Token::MUL ||
791 op == Token::SUB); 812 op == Token::SUB);
792 HValue* left = instr->left(); 813 HValue* left = instr->left();
793 HValue* right = instr->right(); 814 HValue* right = instr->right();
794 ASSERT(left->representation().IsTagged()); 815 ASSERT(left->representation().IsTagged());
795 ASSERT(right->representation().IsTagged()); 816 ASSERT(right->representation().IsTagged());
796 LOperand* left_operand = UseFixed(left, r1); 817 LOperand* left_operand = UseFixed(left, r1);
797 LOperand* right_operand = UseFixed(right, r0); 818 LOperand* right_operand = UseFixed(right, r0);
798 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); 819 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand);
799 return MarkAsCall(DefineFixed(result, r0), instr); 820 return MarkAsCall(DefineFixed(result, r0), instr);
800 } 821 }
801 822
802 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 823 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
803 ASSERT(is_building()); 824 ASSERT(is_building());
804 current_block_ = block; 825 current_block_ = block;
805 next_block_ = next_block; 826 next_block_ = next_block;
806 if (block->IsStartBlock()) { 827 if (block->IsStartBlock()) {
807 block->UpdateEnvironment(graph_->start_environment()); 828 block->UpdateEnvironment(graph_->start_environment());
808 argument_count_ = 0; 829 argument_count_ = 0;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 if (current->has_position()) position_ = current->position(); 890 if (current->has_position()) position_ = current->position();
870 LInstruction* instr = current->CompileToLithium(this); 891 LInstruction* instr = current->CompileToLithium(this);
871 892
872 if (instr != NULL) { 893 if (instr != NULL) {
873 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 894 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
874 instr = AssignPointerMap(instr); 895 instr = AssignPointerMap(instr);
875 } 896 }
876 if (FLAG_stress_environments && !instr->HasEnvironment()) { 897 if (FLAG_stress_environments && !instr->HasEnvironment()) {
877 instr = AssignEnvironment(instr); 898 instr = AssignEnvironment(instr);
878 } 899 }
879 if (current->IsBranch()) { 900 if (current->IsTest() && !instr->IsGoto()) {
880 instr->set_hydrogen_value(HBranch::cast(current)->value()); 901 ASSERT(instr->IsControl());
902 HTest* test = HTest::cast(current);
903 instr->set_hydrogen_value(test->value());
904 HBasicBlock* first = test->FirstSuccessor();
905 HBasicBlock* second = test->SecondSuccessor();
906 ASSERT(first != NULL && second != NULL);
907 instr->SetBranchTargets(first->block_id(), second->block_id());
881 } else { 908 } else {
882 instr->set_hydrogen_value(current); 909 instr->set_hydrogen_value(current);
883 } 910 }
884 911
885 int index = chunk_->AddInstruction(instr, current_block_); 912 int index = chunk_->AddInstruction(instr, current_block_);
886 allocator_->SummarizeInstruction(index); 913 allocator_->SummarizeInstruction(index);
887 } else { 914 } else {
888 // This instruction should be omitted. 915 // This instruction should be omitted.
889 allocator_->OmitInstruction(); 916 allocator_->OmitInstruction();
890 } 917 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 951
925 952
926 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 953 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
927 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), 954 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(),
928 instr->include_stack_check()); 955 instr->include_stack_check());
929 if (instr->include_stack_check()) result = AssignPointerMap(result); 956 if (instr->include_stack_check()) result = AssignPointerMap(result);
930 return result; 957 return result;
931 } 958 }
932 959
933 960
934 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 961 LInstruction* LChunkBuilder::DoTest(HTest* instr) {
935 HValue* v = instr->value(); 962 HValue* v = instr->value();
936 HBasicBlock* first = instr->FirstSuccessor();
937 HBasicBlock* second = instr->SecondSuccessor();
938 ASSERT(first != NULL && second != NULL);
939 int first_id = first->block_id();
940 int second_id = second->block_id();
941
942 if (v->EmitAtUses()) { 963 if (v->EmitAtUses()) {
943 if (v->IsClassOfTest()) { 964 if (v->IsClassOfTest()) {
944 HClassOfTest* compare = HClassOfTest::cast(v); 965 HClassOfTest* compare = HClassOfTest::cast(v);
945 ASSERT(compare->value()->representation().IsTagged()); 966 ASSERT(compare->value()->representation().IsTagged());
946 967
947 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), 968 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
948 TempRegister(), 969 TempRegister());
949 first_id,
950 second_id);
951 } else if (v->IsCompare()) { 970 } else if (v->IsCompare()) {
952 HCompare* compare = HCompare::cast(v); 971 HCompare* compare = HCompare::cast(v);
953 Token::Value op = compare->token(); 972 Token::Value op = compare->token();
954 HValue* left = compare->left(); 973 HValue* left = compare->left();
955 HValue* right = compare->right(); 974 HValue* right = compare->right();
956 Representation r = compare->GetInputRepresentation(); 975 Representation r = compare->GetInputRepresentation();
957 if (r.IsInteger32()) { 976 if (r.IsInteger32()) {
958 ASSERT(left->representation().IsInteger32()); 977 ASSERT(left->representation().IsInteger32());
959 ASSERT(right->representation().IsInteger32()); 978 ASSERT(right->representation().IsInteger32());
960 return new LCmpIDAndBranch(UseRegisterAtStart(left), 979 return new LCmpIDAndBranch(UseRegisterAtStart(left),
961 UseOrConstantAtStart(right), 980 UseOrConstantAtStart(right));
962 first_id,
963 second_id);
964 } else if (r.IsDouble()) { 981 } else if (r.IsDouble()) {
965 ASSERT(left->representation().IsDouble()); 982 ASSERT(left->representation().IsDouble());
966 ASSERT(right->representation().IsDouble()); 983 ASSERT(right->representation().IsDouble());
967 return new LCmpIDAndBranch(UseRegisterAtStart(left), 984 return new LCmpIDAndBranch(UseRegisterAtStart(left),
968 UseRegisterAtStart(right), 985 UseRegisterAtStart(right));
969 first_id,
970 second_id);
971 } else { 986 } else {
972 ASSERT(left->representation().IsTagged()); 987 ASSERT(left->representation().IsTagged());
973 ASSERT(right->representation().IsTagged()); 988 ASSERT(right->representation().IsTagged());
974 bool reversed = op == Token::GT || op == Token::LTE; 989 bool reversed = op == Token::GT || op == Token::LTE;
975 LOperand* left_operand = UseFixed(left, reversed ? r0 : r1); 990 LOperand* left_operand = UseFixed(left, reversed ? r0 : r1);
976 LOperand* right_operand = UseFixed(right, reversed ? r1 : r0); 991 LOperand* right_operand = UseFixed(right, reversed ? r1 : r0);
977 LInstruction* result = new LCmpTAndBranch(left_operand, 992 LInstruction* result = new LCmpTAndBranch(left_operand,
978 right_operand, 993 right_operand);
979 first_id,
980 second_id);
981 return MarkAsCall(result, instr); 994 return MarkAsCall(result, instr);
982 } 995 }
983 } else if (v->IsIsSmi()) { 996 } else if (v->IsIsSmi()) {
984 HIsSmi* compare = HIsSmi::cast(v); 997 HIsSmi* compare = HIsSmi::cast(v);
985 ASSERT(compare->value()->representation().IsTagged()); 998 ASSERT(compare->value()->representation().IsTagged());
986 999
987 return new LIsSmiAndBranch(Use(compare->value()), 1000 return new LIsSmiAndBranch(Use(compare->value()));
988 first_id,
989 second_id);
990 } else if (v->IsHasInstanceType()) { 1001 } else if (v->IsHasInstanceType()) {
991 HHasInstanceType* compare = HHasInstanceType::cast(v); 1002 HHasInstanceType* compare = HHasInstanceType::cast(v);
992 ASSERT(compare->value()->representation().IsTagged()); 1003 ASSERT(compare->value()->representation().IsTagged());
993 1004 return new LHasInstanceTypeAndBranch(
994 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), 1005 UseRegisterAtStart(compare->value()));
995 first_id,
996 second_id);
997 } else if (v->IsHasCachedArrayIndex()) { 1006 } else if (v->IsHasCachedArrayIndex()) {
998 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); 1007 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
999 ASSERT(compare->value()->representation().IsTagged()); 1008 ASSERT(compare->value()->representation().IsTagged());
1000 1009
1001 return new LHasCachedArrayIndexAndBranch( 1010 return new LHasCachedArrayIndexAndBranch(
1002 UseRegisterAtStart(compare->value()), first_id, second_id); 1011 UseRegisterAtStart(compare->value()));
1003 } else if (v->IsIsNull()) { 1012 } else if (v->IsIsNull()) {
1004 HIsNull* compare = HIsNull::cast(v); 1013 HIsNull* compare = HIsNull::cast(v);
1005 ASSERT(compare->value()->representation().IsTagged()); 1014 ASSERT(compare->value()->representation().IsTagged());
1006 1015
1007 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), 1016 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()));
1008 first_id,
1009 second_id);
1010 } else if (v->IsIsObject()) { 1017 } else if (v->IsIsObject()) {
1011 HIsObject* compare = HIsObject::cast(v); 1018 HIsObject* compare = HIsObject::cast(v);
1012 ASSERT(compare->value()->representation().IsTagged()); 1019 ASSERT(compare->value()->representation().IsTagged());
1013 1020
1014 LOperand* temp1 = TempRegister(); 1021 LOperand* temp1 = TempRegister();
1015 LOperand* temp2 = TempRegister(); 1022 LOperand* temp2 = TempRegister();
1016 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), 1023 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
1017 temp1, 1024 temp1,
1018 temp2, 1025 temp2);
1019 first_id,
1020 second_id);
1021 } else if (v->IsCompareJSObjectEq()) { 1026 } else if (v->IsCompareJSObjectEq()) {
1022 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1027 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1023 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1028 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1024 UseRegisterAtStart(compare->right()), 1029 UseRegisterAtStart(compare->right()));
1025 first_id,
1026 second_id);
1027 } else if (v->IsInstanceOf()) { 1030 } else if (v->IsInstanceOf()) {
1028 HInstanceOf* instance_of = HInstanceOf::cast(v); 1031 HInstanceOf* instance_of = HInstanceOf::cast(v);
1029 LInstruction* result = 1032 LInstruction* result =
1030 new LInstanceOfAndBranch(Use(instance_of->left()), 1033 new LInstanceOfAndBranch(Use(instance_of->left()),
1031 Use(instance_of->right()), 1034 Use(instance_of->right()));
1032 first_id,
1033 second_id);
1034 return MarkAsCall(result, instr); 1035 return MarkAsCall(result, instr);
1035 } else if (v->IsTypeofIs()) { 1036 } else if (v->IsTypeofIs()) {
1036 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1037 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1037 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), 1038 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1038 first_id,
1039 second_id);
1040 } else { 1039 } else {
1041 if (v->IsConstant()) { 1040 if (v->IsConstant()) {
1042 if (HConstant::cast(v)->handle()->IsTrue()) { 1041 if (HConstant::cast(v)->handle()->IsTrue()) {
1043 return new LGoto(first_id); 1042 return new LGoto(instr->FirstSuccessor()->block_id());
1044 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1043 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1045 return new LGoto(second_id); 1044 return new LGoto(instr->SecondSuccessor()->block_id());
1046 } 1045 }
1047 } 1046 }
1048 Abort("Undefined compare before branch"); 1047 Abort("Undefined compare before branch");
1049 return NULL; 1048 return NULL;
1050 } 1049 }
1051 } 1050 }
1052 return new LBranch(UseRegisterAtStart(v), first_id, second_id); 1051 return new LBranch(UseRegisterAtStart(v));
1053 } 1052 }
1054 1053
1055 1054
1056 LInstruction* LChunkBuilder::DoCompareMapAndBranch( 1055 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1057 HCompareMapAndBranch* instr) {
1058 ASSERT(instr->value()->representation().IsTagged()); 1056 ASSERT(instr->value()->representation().IsTagged());
1059 LOperand* value = UseRegisterAtStart(instr->value()); 1057 LOperand* value = UseRegisterAtStart(instr->value());
1060 LOperand* temp = TempRegister(); 1058 LOperand* temp = TempRegister();
1061 return new LCmpMapAndBranch(value, temp); 1059 return new LCmpMapAndBranch(value, temp);
1062 } 1060 }
1063 1061
1064 1062
1065 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1063 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1066 return DefineAsRegister(new LArgumentsLength(UseRegister(length->value()))); 1064 return DefineAsRegister(new LArgumentsLength(UseRegister(length->value())));
1067 } 1065 }
1068 1066
1069 1067
1070 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1068 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1071 return DefineAsRegister(new LArgumentsElements); 1069 return DefineAsRegister(new LArgumentsElements);
1072 } 1070 }
1073 1071
1074 1072
1075 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1073 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1076 LInstruction* result = 1074 LInstanceOf* result =
1077 new LInstanceOf(UseFixed(instr->left(), r0), 1075 new LInstanceOf(UseFixed(instr->left(), r0),
1078 UseFixed(instr->right(), r1)); 1076 UseFixed(instr->right(), r1));
1079 return MarkAsCall(DefineFixed(result, r0), instr); 1077 return MarkAsCall(DefineFixed(result, r0), instr);
1080 } 1078 }
1081 1079
1082 1080
1083 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( 1081 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1084 HInstanceOfKnownGlobal* instr) { 1082 HInstanceOfKnownGlobal* instr) {
1085 LInstruction* result = 1083 LInstanceOfKnownGlobal* result =
1086 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0)); 1084 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4));
1087 return MarkAsCall(DefineFixed(result, r0), instr); 1085 MarkAsSaveDoubles(result);
1086 return AssignEnvironment(AssignPointerMap(DefineFixed(result, r0)));
1088 } 1087 }
1089 1088
1090 1089
1091 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1090 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1092 LOperand* function = UseFixed(instr->function(), r1); 1091 LOperand* function = UseFixed(instr->function(), r1);
1093 LOperand* receiver = UseFixed(instr->receiver(), r0); 1092 LOperand* receiver = UseFixed(instr->receiver(), r0);
1094 LOperand* length = UseRegisterAtStart(instr->length()); 1093 LOperand* length = UseRegisterAtStart(instr->length());
1095 LOperand* elements = UseRegisterAtStart(instr->elements()); 1094 LOperand* elements = UseRegisterAtStart(instr->elements());
1096 LInstruction* result = new LApplyArguments(function, 1095 LApplyArguments* result = new LApplyArguments(function,
1097 receiver, 1096 receiver,
1098 length, 1097 length,
1099 elements); 1098 elements);
1100 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1099 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1101 } 1100 }
1102 1101
1103 1102
1104 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1103 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1105 ++argument_count_; 1104 ++argument_count_;
1106 LOperand* argument = Use(instr->argument()); 1105 LOperand* argument = Use(instr->argument());
1107 return new LPushArgument(argument); 1106 return new LPushArgument(argument);
1108 } 1107 }
1109 1108
(...skipping 12 matching lines...) Expand all
1122 HCallConstantFunction* instr) { 1121 HCallConstantFunction* instr) {
1123 argument_count_ -= instr->argument_count(); 1122 argument_count_ -= instr->argument_count();
1124 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); 1123 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr);
1125 } 1124 }
1126 1125
1127 1126
1128 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1127 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1129 BuiltinFunctionId op = instr->op(); 1128 BuiltinFunctionId op = instr->op();
1130 LOperand* input = UseRegisterAtStart(instr->value()); 1129 LOperand* input = UseRegisterAtStart(instr->value());
1131 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL; 1130 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1132 LInstruction* result = new LUnaryMathOperation(input, temp); 1131 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
1133 switch (op) { 1132 switch (op) {
1134 case kMathAbs: 1133 case kMathAbs:
1135 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1134 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1136 case kMathFloor: 1135 case kMathFloor:
1137 return AssignEnvironment(DefineAsRegister(result)); 1136 return AssignEnvironment(DefineAsRegister(result));
1138 case kMathSqrt: 1137 case kMathSqrt:
1139 return DefineSameAsFirst(result); 1138 return DefineSameAsFirst(result);
1140 case kMathRound: 1139 case kMathRound:
1141 Abort("MathRound LUnaryMathOperation not implemented"); 1140 Abort("MathRound LUnaryMathOperation not implemented");
1142 return NULL; 1141 return NULL;
(...skipping 12 matching lines...) Expand all
1155 default: 1154 default:
1156 UNREACHABLE(); 1155 UNREACHABLE();
1157 return NULL; 1156 return NULL;
1158 } 1157 }
1159 } 1158 }
1160 1159
1161 1160
1162 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1161 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1163 ASSERT(instr->key()->representation().IsTagged()); 1162 ASSERT(instr->key()->representation().IsTagged());
1164 argument_count_ -= instr->argument_count(); 1163 argument_count_ -= instr->argument_count();
1165 UseFixed(instr->key(), r2); 1164 LOperand* key = UseFixed(instr->key(), r2);
1166 return MarkAsCall(DefineFixed(new LCallKeyed, r0), instr); 1165 return MarkAsCall(DefineFixed(new LCallKeyed(key), r0), instr);
1167 } 1166 }
1168 1167
1169 1168
1170 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { 1169 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1171 argument_count_ -= instr->argument_count(); 1170 argument_count_ -= instr->argument_count();
1172 return MarkAsCall(DefineFixed(new LCallNamed, r0), instr); 1171 return MarkAsCall(DefineFixed(new LCallNamed, r0), instr);
1173 } 1172 }
1174 1173
1175 1174
1176 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { 1175 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1177 argument_count_ -= instr->argument_count(); 1176 argument_count_ -= instr->argument_count();
1178 return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr); 1177 return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr);
1179 } 1178 }
1180 1179
1181 1180
1182 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { 1181 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1183 argument_count_ -= instr->argument_count(); 1182 argument_count_ -= instr->argument_count();
1184 return MarkAsCall(DefineFixed(new LCallKnownGlobal, r0), instr); 1183 return MarkAsCall(DefineFixed(new LCallKnownGlobal, r0), instr);
1185 } 1184 }
1186 1185
1187 1186
1188 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1187 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1189 LOperand* constructor = UseFixed(instr->constructor(), r1); 1188 LOperand* constructor = UseFixed(instr->constructor(), r1);
1190 argument_count_ -= instr->argument_count(); 1189 argument_count_ -= instr->argument_count();
1191 LInstruction* result = new LCallNew(constructor); 1190 LCallNew* result = new LCallNew(constructor);
1192 return MarkAsCall(DefineFixed(result, r0), instr); 1191 return MarkAsCall(DefineFixed(result, r0), instr);
1193 } 1192 }
1194 1193
1195 1194
1196 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1195 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1197 argument_count_ -= instr->argument_count(); 1196 argument_count_ -= instr->argument_count();
1198 return MarkAsCall(DefineFixed(new LCallFunction, r0), instr); 1197 return MarkAsCall(DefineFixed(new LCallFunction, r0), instr);
1199 } 1198 }
1200 1199
1201 1200
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 ASSERT(instr->right()->representation().IsDouble()); 1370 ASSERT(instr->right()->representation().IsDouble());
1372 LOperand* left = UseRegisterAtStart(instr->left()); 1371 LOperand* left = UseRegisterAtStart(instr->left());
1373 LOperand* right = UseRegisterAtStart(instr->right()); 1372 LOperand* right = UseRegisterAtStart(instr->right());
1374 return DefineAsRegister(new LCmpID(left, right)); 1373 return DefineAsRegister(new LCmpID(left, right));
1375 } else { 1374 } else {
1376 ASSERT(instr->left()->representation().IsTagged()); 1375 ASSERT(instr->left()->representation().IsTagged());
1377 ASSERT(instr->right()->representation().IsTagged()); 1376 ASSERT(instr->right()->representation().IsTagged());
1378 bool reversed = (op == Token::GT || op == Token::LTE); 1377 bool reversed = (op == Token::GT || op == Token::LTE);
1379 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1); 1378 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
1380 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0); 1379 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
1381 LInstruction* result = new LCmpT(left, right); 1380 LCmpT* result = new LCmpT(left, right);
1382 return MarkAsCall(DefineFixed(result, r0), instr); 1381 return MarkAsCall(DefineFixed(result, r0), instr);
1383 } 1382 }
1384 } 1383 }
1385 1384
1386 1385
1387 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1386 LInstruction* LChunkBuilder::DoCompareJSObjectEq(
1388 HCompareJSObjectEq* instr) { 1387 HCompareJSObjectEq* instr) {
1389 LOperand* left = UseRegisterAtStart(instr->left()); 1388 LOperand* left = UseRegisterAtStart(instr->left());
1390 LOperand* right = UseRegisterAtStart(instr->right()); 1389 LOperand* right = UseRegisterAtStart(instr->right());
1391 LInstruction* result = new LCmpJSObjectEq(left, right); 1390 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
1392 return DefineAsRegister(result); 1391 return DefineAsRegister(result);
1393 } 1392 }
1394 1393
1395 1394
1396 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1395 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
1397 ASSERT(instr->value()->representation().IsTagged()); 1396 ASSERT(instr->value()->representation().IsTagged());
1398 LOperand* value = UseRegisterAtStart(instr->value()); 1397 LOperand* value = UseRegisterAtStart(instr->value());
1399 1398
1400 return DefineAsRegister(new LIsNull(value)); 1399 return DefineAsRegister(new LIsNull(value));
1401 } 1400 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 1447
1449 1448
1450 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1449 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1451 LOperand* array = UseRegisterAtStart(instr->value()); 1450 LOperand* array = UseRegisterAtStart(instr->value());
1452 return DefineAsRegister(new LFixedArrayLength(array)); 1451 return DefineAsRegister(new LFixedArrayLength(array));
1453 } 1452 }
1454 1453
1455 1454
1456 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1455 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1457 LOperand* object = UseRegister(instr->value()); 1456 LOperand* object = UseRegister(instr->value());
1458 LInstruction* result = new LValueOf(object, TempRegister()); 1457 LValueOf* result = new LValueOf(object, TempRegister());
1459 return AssignEnvironment(DefineSameAsFirst(result)); 1458 return AssignEnvironment(DefineSameAsFirst(result));
1460 } 1459 }
1461 1460
1462 1461
1463 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1462 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1464 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1463 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1465 UseRegister(instr->length()))); 1464 UseRegister(instr->length())));
1466 } 1465 }
1467 1466
1468 1467
1469 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1468 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1470 LOperand* value = UseFixed(instr->value(), r0); 1469 LOperand* value = UseFixed(instr->value(), r0);
1471 return MarkAsCall(new LThrow(value), instr); 1470 return MarkAsCall(new LThrow(value), instr);
1472 } 1471 }
1473 1472
1474 1473
1475 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1474 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1476 Representation from = instr->from(); 1475 Representation from = instr->from();
1477 Representation to = instr->to(); 1476 Representation to = instr->to();
1478 if (from.IsTagged()) { 1477 if (from.IsTagged()) {
1479 if (to.IsDouble()) { 1478 if (to.IsDouble()) {
1480 LOperand* value = UseRegister(instr->value()); 1479 LOperand* value = UseRegister(instr->value());
1481 LInstruction* res = new LNumberUntagD(value); 1480 LNumberUntagD* res = new LNumberUntagD(value);
1482 return AssignEnvironment(DefineAsRegister(res)); 1481 return AssignEnvironment(DefineAsRegister(res));
1483 } else { 1482 } else {
1484 ASSERT(to.IsInteger32()); 1483 ASSERT(to.IsInteger32());
1485 LOperand* value = UseRegister(instr->value()); 1484 LOperand* value = UseRegister(instr->value());
1486 bool needs_check = !instr->value()->type().IsSmi(); 1485 bool needs_check = !instr->value()->type().IsSmi();
1487 LInstruction* res = NULL; 1486 LInstruction* res = NULL;
1488 if (needs_check) { 1487 if (needs_check) {
1489 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1))); 1488 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1)));
1490 } else { 1489 } else {
1491 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1490 res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
1492 } 1491 }
1493 if (needs_check) { 1492 if (needs_check) {
1494 res = AssignEnvironment(res); 1493 res = AssignEnvironment(res);
1495 } 1494 }
1496 return res; 1495 return res;
1497 } 1496 }
1498 } else if (from.IsDouble()) { 1497 } else if (from.IsDouble()) {
1499 if (to.IsTagged()) { 1498 if (to.IsTagged()) {
1500 LOperand* value = UseRegister(instr->value()); 1499 LOperand* value = UseRegister(instr->value());
1501 LOperand* temp1 = TempRegister(); 1500 LOperand* temp1 = TempRegister();
1502 LOperand* temp2 = TempRegister(); 1501 LOperand* temp2 = TempRegister();
1503 1502
1504 // Make sure that the temp and result_temp registers are 1503 // Make sure that the temp and result_temp registers are
1505 // different. 1504 // different.
1506 LUnallocated* result_temp = TempRegister(); 1505 LUnallocated* result_temp = TempRegister();
1507 LInstruction* result = new LNumberTagD(value, temp1, temp2); 1506 LNumberTagD* result = new LNumberTagD(value, temp1, temp2);
1508 Define(result, result_temp); 1507 Define(result, result_temp);
1509 return AssignPointerMap(result); 1508 return AssignPointerMap(result);
1510 } else { 1509 } else {
1511 ASSERT(to.IsInteger32()); 1510 ASSERT(to.IsInteger32());
1512 LOperand* value = UseRegister(instr->value()); 1511 LOperand* value = UseRegister(instr->value());
1513 LInstruction* res = new LDoubleToI(value); 1512 LDoubleToI* res = new LDoubleToI(value);
1514 return AssignEnvironment(DefineAsRegister(res)); 1513 return AssignEnvironment(DefineAsRegister(res));
1515 } 1514 }
1516 } else if (from.IsInteger32()) { 1515 } else if (from.IsInteger32()) {
1517 if (to.IsTagged()) { 1516 if (to.IsTagged()) {
1518 HValue* val = instr->value(); 1517 HValue* val = instr->value();
1519 LOperand* value = UseRegister(val); 1518 LOperand* value = UseRegister(val);
1520 if (val->HasRange() && val->range()->IsInSmiRange()) { 1519 if (val->HasRange() && val->range()->IsInSmiRange()) {
1521 return DefineSameAsFirst(new LSmiTag(value)); 1520 return DefineSameAsFirst(new LSmiTag(value));
1522 } else { 1521 } else {
1523 LInstruction* result = new LNumberTagI(value); 1522 LNumberTagI* result = new LNumberTagI(value);
1524 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1523 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1525 } 1524 }
1526 } else { 1525 } else {
1527 ASSERT(to.IsDouble()); 1526 ASSERT(to.IsDouble());
1528 LOperand* value = Use(instr->value()); 1527 LOperand* value = Use(instr->value());
1529 return DefineAsRegister(new LInteger32ToDouble(value)); 1528 return DefineAsRegister(new LInteger32ToDouble(value));
1530 } 1529 }
1531 } 1530 }
1532 UNREACHABLE(); 1531 UNREACHABLE();
1533 return NULL; 1532 return NULL;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 } else if (r.IsTagged()) { 1589 } else if (r.IsTagged()) {
1591 return DefineAsRegister(new LConstantT(instr->handle())); 1590 return DefineAsRegister(new LConstantT(instr->handle()));
1592 } else { 1591 } else {
1593 UNREACHABLE(); 1592 UNREACHABLE();
1594 return NULL; 1593 return NULL;
1595 } 1594 }
1596 } 1595 }
1597 1596
1598 1597
1599 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1598 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1600 LInstruction* result = new LLoadGlobal(); 1599 LLoadGlobal* result = new LLoadGlobal();
1601 return instr->check_hole_value() 1600 return instr->check_hole_value()
1602 ? AssignEnvironment(DefineAsRegister(result)) 1601 ? AssignEnvironment(DefineAsRegister(result))
1603 : DefineAsRegister(result); 1602 : DefineAsRegister(result);
1604 } 1603 }
1605 1604
1606 1605
1607 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1606 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1608 return new LStoreGlobal(UseRegisterAtStart(instr->value())); 1607 return new LStoreGlobal(UseRegisterAtStart(instr->value()));
1609 } 1608 }
1610 1609
(...skipping 28 matching lines...) Expand all
1639 return DefineSameAsFirst(new LLoadElements(input)); 1638 return DefineSameAsFirst(new LLoadElements(input));
1640 } 1639 }
1641 1640
1642 1641
1643 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1642 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1644 HLoadKeyedFastElement* instr) { 1643 HLoadKeyedFastElement* instr) {
1645 ASSERT(instr->representation().IsTagged()); 1644 ASSERT(instr->representation().IsTagged());
1646 ASSERT(instr->key()->representation().IsInteger32()); 1645 ASSERT(instr->key()->representation().IsInteger32());
1647 LOperand* obj = UseRegisterAtStart(instr->object()); 1646 LOperand* obj = UseRegisterAtStart(instr->object());
1648 LOperand* key = UseRegisterAtStart(instr->key()); 1647 LOperand* key = UseRegisterAtStart(instr->key());
1649 LInstruction* result = new LLoadKeyedFastElement(obj, key); 1648 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1650 return AssignEnvironment(DefineSameAsFirst(result)); 1649 return AssignEnvironment(DefineSameAsFirst(result));
1651 } 1650 }
1652 1651
1653 1652
1654 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1653 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1655 LOperand* object = UseFixed(instr->object(), r1); 1654 LOperand* object = UseFixed(instr->object(), r1);
1656 LOperand* key = UseFixed(instr->key(), r0); 1655 LOperand* key = UseFixed(instr->key(), r0);
1657 1656
1658 LInstruction* result = 1657 LInstruction* result =
1659 DefineFixed(new LLoadKeyedGeneric(object, key), r0); 1658 DefineFixed(new LLoadKeyedGeneric(object, key), r0);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1710 1709
1711 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1710 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1712 LOperand* obj = UseFixed(instr->object(), r1); 1711 LOperand* obj = UseFixed(instr->object(), r1);
1713 LOperand* val = UseFixed(instr->value(), r0); 1712 LOperand* val = UseFixed(instr->value(), r0);
1714 1713
1715 LInstruction* result = new LStoreNamedGeneric(obj, val); 1714 LInstruction* result = new LStoreNamedGeneric(obj, val);
1716 return MarkAsCall(result, instr); 1715 return MarkAsCall(result, instr);
1717 } 1716 }
1718 1717
1719 1718
1719 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
1720 LOperand* string = UseRegister(instr->string());
1721 LOperand* index = UseRegisterOrConstant(instr->index());
1722 LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
1723 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1724 }
1725
1726
1727 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
1728 LOperand* string = UseRegisterAtStart(instr->value());
1729 return DefineAsRegister(new LStringLength(string));
1730 }
1731
1732
1720 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1733 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1721 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr); 1734 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr);
1722 } 1735 }
1723 1736
1724 1737
1725 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 1738 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1726 return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr); 1739 return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr);
1727 } 1740 }
1728 1741
1729 1742
1730 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 1743 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1731 return MarkAsCall(DefineFixed(new LRegExpLiteral, r0), instr); 1744 return MarkAsCall(DefineFixed(new LRegExpLiteral, r0), instr);
1732 } 1745 }
1733 1746
1734 1747
1735 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 1748 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1736 return MarkAsCall(DefineFixed(new LFunctionLiteral, r0), instr); 1749 return MarkAsCall(DefineFixed(new LFunctionLiteral, r0), instr);
1737 } 1750 }
1738 1751
1739 1752
1740 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 1753 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1741 LOperand* object = UseRegisterAtStart(instr->object()); 1754 LOperand* object = UseRegisterAtStart(instr->object());
1742 LOperand* key = UseRegisterAtStart(instr->key()); 1755 LOperand* key = UseRegisterAtStart(instr->key());
1743 LInstruction* result = new LDeleteProperty(object, key); 1756 LDeleteProperty* result = new LDeleteProperty(object, key);
1744 return MarkAsCall(DefineFixed(result, r0), instr); 1757 return MarkAsCall(DefineFixed(result, r0), instr);
1745 } 1758 }
1746 1759
1747 1760
1748 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1761 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1749 allocator_->MarkAsOsrEntry(); 1762 allocator_->MarkAsOsrEntry();
1750 current_block_->last_environment()->set_ast_id(instr->ast_id()); 1763 current_block_->last_environment()->set_ast_id(instr->ast_id());
1751 return AssignEnvironment(new LOsrEntry); 1764 return AssignEnvironment(new LOsrEntry);
1752 } 1765 }
1753 1766
(...skipping 20 matching lines...) Expand all
1774 // There are no real uses of the arguments object (we bail out in all other 1787 // There are no real uses of the arguments object (we bail out in all other
1775 // cases). 1788 // cases).
1776 return NULL; 1789 return NULL;
1777 } 1790 }
1778 1791
1779 1792
1780 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1793 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
1781 LOperand* arguments = UseRegister(instr->arguments()); 1794 LOperand* arguments = UseRegister(instr->arguments());
1782 LOperand* length = UseTempRegister(instr->length()); 1795 LOperand* length = UseTempRegister(instr->length());
1783 LOperand* index = UseRegister(instr->index()); 1796 LOperand* index = UseRegister(instr->index());
1784 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); 1797 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
1785 return DefineAsRegister(AssignEnvironment(result)); 1798 return AssignEnvironment(DefineAsRegister(result));
1786 } 1799 }
1787 1800
1788 1801
1789 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1802 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1790 LInstruction* result = new LTypeof(UseRegisterAtStart(instr->value())); 1803 LTypeof* result = new LTypeof(UseRegisterAtStart(instr->value()));
1791 return MarkAsCall(DefineFixed(result, r0), instr); 1804 return MarkAsCall(DefineFixed(result, r0), instr);
1792 } 1805 }
1793 1806
1794 1807
1795 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1808 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1796 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1809 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
1797 } 1810 }
1798 1811
1799 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1812 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1800 HEnvironment* env = current_block_->last_environment(); 1813 HEnvironment* env = current_block_->last_environment();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 1861
1849 1862
1850 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1863 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1851 HEnvironment* outer = current_block_->last_environment()->outer(); 1864 HEnvironment* outer = current_block_->last_environment()->outer();
1852 current_block_->UpdateEnvironment(outer); 1865 current_block_->UpdateEnvironment(outer);
1853 return NULL; 1866 return NULL;
1854 } 1867 }
1855 1868
1856 1869
1857 } } // namespace v8::internal 1870 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698