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

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

Issue 6201006: X64 Crankshaft: Ported lots of boilerplate code. (Closed)
Patch Set: Addressed review comments. Updated to match newest ia32 version. 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
« no previous file with comments | « src/x64/lithium-x64.h ('k') | no next file » | 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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "x64/lithium-x64.h" 28 #include "x64/lithium-x64.h"
29 #include "x64/lithium-codegen-x64.h" 29 #include "x64/lithium-codegen-x64.h"
30 30
31 namespace v8 { 31 namespace v8 {
32 namespace internal { 32 namespace internal {
33 33
34 #define DEFINE_COMPILE(type) \
35 void L##type::CompileToNative(LCodeGen* generator) { \
36 generator->Do##type(this); \
37 }
38 LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
39 #undef DEFINE_COMPILE
40
34 LOsrEntry::LOsrEntry() { 41 LOsrEntry::LOsrEntry() {
35 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { 42 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
36 register_spills_[i] = NULL; 43 register_spills_[i] = NULL;
37 } 44 }
38 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { 45 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
39 double_register_spills_[i] = NULL; 46 double_register_spills_[i] = NULL;
40 } 47 }
41 } 48 }
42 49
43 50
44 void LOsrEntry::MarkSpilledRegister(int allocation_index, 51 void LOsrEntry::MarkSpilledRegister(int allocation_index,
45 LOperand* spill_operand) { 52 LOperand* spill_operand) {
46 ASSERT(spill_operand->IsStackSlot()); 53 ASSERT(spill_operand->IsStackSlot());
47 ASSERT(register_spills_[allocation_index] == NULL); 54 ASSERT(register_spills_[allocation_index] == NULL);
48 register_spills_[allocation_index] = spill_operand; 55 register_spills_[allocation_index] = spill_operand;
49 } 56 }
50 57
51 58
52 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
53 LOperand* spill_operand) { 60 LOperand* spill_operand) {
54 ASSERT(spill_operand->IsDoubleStackSlot()); 61 ASSERT(spill_operand->IsDoubleStackSlot());
55 ASSERT(double_register_spills_[allocation_index] == NULL); 62 ASSERT(double_register_spills_[allocation_index] == NULL);
56 double_register_spills_[allocation_index] = spill_operand; 63 double_register_spills_[allocation_index] = spill_operand;
57 } 64 }
58 65
59 66
60 void LOsrEntry::CompileToNative(LCodeGen* generator) {
61 UNIMPLEMENTED();
62 // Implement in lithium-codegen-x64.cc.
63 }
64
65
66 void LInstruction::PrintTo(StringStream* stream) { 67 void LInstruction::PrintTo(StringStream* stream) {
67 stream->Add("%s ", this->Mnemonic()); 68 stream->Add("%s ", this->Mnemonic());
68 if (HasResult()) { 69 if (HasResult()) {
69 LTemplateInstruction<1>::cast(this)->result()->PrintTo(stream); 70 PrintOutputOperandTo(stream);
70 stream->Add(" ");
71 } 71 }
72
72 PrintDataTo(stream); 73 PrintDataTo(stream);
73 74
74 if (HasEnvironment()) { 75 if (HasEnvironment()) {
75 stream->Add(" "); 76 stream->Add(" ");
76 // environment()->PrintTo(stream); 77 environment()->PrintTo(stream);
77 } 78 }
78 79
79 if (HasPointerMap()) { 80 if (HasPointerMap()) {
80 stream->Add(" "); 81 stream->Add(" ");
81 // pointer_map()->PrintTo(stream); 82 pointer_map()->PrintTo(stream);
82 } 83 }
83 } 84 }
84 85
86
87 template<int R, int I, int T>
88 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
89 for (int i = 0; i < I; i++) {
90 stream->Add(i == 0 ? "= " : " ");
91 inputs_.at(i)->PrintTo(stream);
92 }
93 }
94
95
96 template<int R, int I, int T>
97 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
98 if (this->HasResult()) {
99 this->result()->PrintTo(stream);
100 stream->Add(" ");
101 }
102 }
103
85 104
86 void LLabel::PrintDataTo(StringStream* stream) { 105 void LLabel::PrintDataTo(StringStream* stream) {
87 LGap::PrintDataTo(stream); 106 LGap::PrintDataTo(stream);
88 LLabel* rep = replacement(); 107 LLabel* rep = replacement();
89 if (rep != NULL) { 108 if (rep != NULL) {
90 stream->Add(" Dead block replaced with B%d", rep->block_id()); 109 stream->Add(" Dead block replaced with B%d", rep->block_id());
91 } 110 }
92 } 111 }
93 112
94 113
(...skipping 12 matching lines...) Expand all
107 for (int i = 0; i < 4; i++) { 126 for (int i = 0; i < 4; i++) {
108 stream->Add("("); 127 stream->Add("(");
109 if (parallel_moves_[i] != NULL) { 128 if (parallel_moves_[i] != NULL) {
110 parallel_moves_[i]->PrintDataTo(stream); 129 parallel_moves_[i]->PrintDataTo(stream);
111 } 130 }
112 stream->Add(") "); 131 stream->Add(") ");
113 } 132 }
114 } 133 }
115 134
116 135
136 const char* LArithmeticD::Mnemonic() const {
137 switch (op()) {
138 case Token::ADD: return "add-d";
139 case Token::SUB: return "sub-d";
140 case Token::MUL: return "mul-d";
141 case Token::DIV: return "div-d";
142 case Token::MOD: return "mod-d";
143 default:
144 UNREACHABLE();
145 return NULL;
146 }
147 }
148
149
150 const char* LArithmeticT::Mnemonic() const {
151 switch (op()) {
152 case Token::ADD: return "add-t";
153 case Token::SUB: return "sub-t";
154 case Token::MUL: return "mul-t";
155 case Token::MOD: return "mod-t";
156 case Token::DIV: return "div-t";
157 default:
158 UNREACHABLE();
159 return NULL;
160 }
161 }
162
163
117 void LGoto::PrintDataTo(StringStream* stream) { 164 void LGoto::PrintDataTo(StringStream* stream) {
118 stream->Add("B%d", block_id()); 165 stream->Add("B%d", block_id());
119 } 166 }
120 167
121 168
169 void LBranch::PrintDataTo(StringStream* stream) {
170 stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
171 input()->PrintTo(stream);
172 }
173
174
175 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
176 stream->Add("if ");
177 left()->PrintTo(stream);
178 stream->Add(" %s ", Token::String(op()));
179 right()->PrintTo(stream);
180 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
181 }
182
183
184 void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
185 stream->Add("if ");
186 input()->PrintTo(stream);
187 stream->Add(is_strict() ? " === null" : " == null");
188 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
189 }
190
191
192 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
193 stream->Add("if is_object(");
194 input()->PrintTo(stream);
195 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
196 }
197
198
199 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
200 stream->Add("if is_smi(");
201 input()->PrintTo(stream);
202 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
203 }
204
205
206 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
207 stream->Add("if has_instance_type(");
208 input()->PrintTo(stream);
209 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
210 }
211
212
213 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
214 stream->Add("if has_cached_array_index(");
215 input()->PrintTo(stream);
216 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
217 }
218
219
220 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
221 stream->Add("if class_of_test(");
222 input()->PrintTo(stream);
223 stream->Add(", \"%o\") then B%d else B%d",
224 *hydrogen()->class_name(),
225 true_block_id(),
226 false_block_id());
227 }
228
229
230 void LTypeofIs::PrintDataTo(StringStream* stream) {
231 input()->PrintTo(stream);
232 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
233 }
234
235
236 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
237 stream->Add("if typeof ");
238 input()->PrintTo(stream);
239 stream->Add(" == \"%s\" then B%d else B%d",
240 *hydrogen()->type_literal()->ToCString(),
241 true_block_id(), false_block_id());
242 }
243
244
245 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
246 stream->Add("#%d / ", arity());
247 }
248
249
250 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
251 stream->Add("/%s ", hydrogen()->OpName());
252 input()->PrintTo(stream);
253 }
254
255
256 void LCallKeyed::PrintDataTo(StringStream* stream) {
257 stream->Add("[ecx] #%d / ", arity());
258 }
259
260
261 void LCallNamed::PrintDataTo(StringStream* stream) {
262 SmartPointer<char> name_string = name()->ToCString();
263 stream->Add("%s #%d / ", *name_string, arity());
264 }
265
266
267 void LCallGlobal::PrintDataTo(StringStream* stream) {
268 SmartPointer<char> name_string = name()->ToCString();
269 stream->Add("%s #%d / ", *name_string, arity());
270 }
271
272
273 void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
274 stream->Add("#%d / ", arity());
275 }
276
277
278 void LCallNew::PrintDataTo(StringStream* stream) {
279 stream->Add("= ");
280 input()->PrintTo(stream);
281 stream->Add(" #%d / ", arity());
282 }
283
284
285 void LClassOfTest::PrintDataTo(StringStream* stream) {
286 stream->Add("= class_of_test(");
287 input()->PrintTo(stream);
288 stream->Add(", \"%o\")", *hydrogen()->class_name());
289 }
290
291
292 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
293 arguments()->PrintTo(stream);
294
295 stream->Add(" length ");
296 length()->PrintTo(stream);
297
298 stream->Add(" index ");
299 index()->PrintTo(stream);
300 }
301
302
303 int LChunk::GetNextSpillIndex(bool is_double) {
304 // Need to consider what index means: Is it 32 bit or 64 bit index?
305 UNIMPLEMENTED();
306 return 0;
307 }
308
309
310 LOperand* LChunk::GetNextSpillSlot(bool is_double) {
311 UNIMPLEMENTED();
312 return NULL;
313 }
314
315
316 void LChunk::MarkEmptyBlocks() {
317 HPhase phase("Mark empty blocks", this);
318 for (int i = 0; i < graph()->blocks()->length(); ++i) {
319 HBasicBlock* block = graph()->blocks()->at(i);
320 int first = block->first_instruction_index();
321 int last = block->last_instruction_index();
322 LInstruction* first_instr = instructions()->at(first);
323 LInstruction* last_instr = instructions()->at(last);
324
325 LLabel* label = LLabel::cast(first_instr);
326 if (last_instr->IsGoto()) {
327 LGoto* goto_instr = LGoto::cast(last_instr);
328 if (!goto_instr->include_stack_check() &&
329 label->IsRedundant() &&
330 !label->is_loop_header()) {
331 bool can_eliminate = true;
332 for (int i = first + 1; i < last && can_eliminate; ++i) {
333 LInstruction* cur = instructions()->at(i);
334 if (cur->IsGap()) {
335 LGap* gap = LGap::cast(cur);
336 if (!gap->IsRedundant()) {
337 can_eliminate = false;
338 }
339 } else {
340 can_eliminate = false;
341 }
342 }
343
344 if (can_eliminate) {
345 label->set_replacement(GetLabel(goto_instr->block_id()));
346 }
347 }
348 }
349 }
350 }
351
352
353 void LStoreNamed::PrintDataTo(StringStream* stream) {
354 object()->PrintTo(stream);
355 stream->Add(".");
356 stream->Add(*String::cast(*name())->ToCString());
357 stream->Add(" <- ");
358 value()->PrintTo(stream);
359 }
360
361
362 void LStoreKeyed::PrintDataTo(StringStream* stream) {
363 object()->PrintTo(stream);
364 stream->Add("[");
365 key()->PrintTo(stream);
366 stream->Add("] <- ");
367 value()->PrintTo(stream);
368 }
369
370
371 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
372 LGap* gap = new LGap(block);
373 int index = -1;
374 if (instr->IsControl()) {
375 instructions_.Add(gap);
376 index = instructions_.length();
377 instructions_.Add(instr);
378 } else {
379 index = instructions_.length();
380 instructions_.Add(instr);
381 instructions_.Add(gap);
382 }
383 if (instr->HasPointerMap()) {
384 pointer_maps_.Add(instr->pointer_map());
385 instr->pointer_map()->set_lithium_position(index);
386 }
387 return index;
388 }
389
390
391 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
392 return LConstantOperand::Create(constant->id());
393 }
394
395
396 int LChunk::GetParameterStackSlot(int index) const {
397 // The receiver is at index 0, the first parameter at index 1, so we
398 // shift all parameter indexes down by the number of parameters, and
399 // make sure they end up negative so they are distinguishable from
400 // spill slots.
401 int result = index - graph()->info()->scope()->num_parameters() - 1;
402 ASSERT(result < 0);
403 return result;
404 }
405
406 // A parameter relative to ebp in the arguments stub.
407 int LChunk::ParameterAt(int index) {
408 ASSERT(-1 <= index); // -1 is the receiver.
409 return (1 + graph()->info()->scope()->num_parameters() - index) *
410 kPointerSize;
411 }
412
413
414 LGap* LChunk::GetGapAt(int index) const {
415 return LGap::cast(instructions_[index]);
416 }
417
418
419 bool LChunk::IsGapAt(int index) const {
420 return instructions_[index]->IsGap();
421 }
422
423
424 int LChunk::NearestGapPos(int index) const {
425 while (!IsGapAt(index)) index--;
426 return index;
427 }
428
429
430 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
431 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
432 }
433
434
435 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
436 return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
437 }
438
439
440 Representation LChunk::LookupLiteralRepresentation(
441 LConstantOperand* operand) const {
442 return graph_->LookupValue(operand->index())->representation();
443 }
444
445
122 LChunk* LChunkBuilder::Build() { 446 LChunk* LChunkBuilder::Build() {
123 ASSERT(is_unused()); 447 ASSERT(is_unused());
124 chunk_ = new LChunk(graph()); 448 chunk_ = new LChunk(graph());
125 HPhase phase("Building chunk", chunk_); 449 HPhase phase("Building chunk", chunk_);
126 status_ = BUILDING; 450 status_ = BUILDING;
127 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); 451 const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
128 for (int i = 0; i < blocks->length(); i++) { 452 for (int i = 0; i < blocks->length(); i++) {
129 HBasicBlock* next = NULL; 453 HBasicBlock* next = NULL;
130 if (i < blocks->length() - 1) next = blocks->at(i + 1); 454 if (i < blocks->length() - 1) next = blocks->at(i + 1);
131 DoBasicBlock(blocks->at(i), next); 455 DoBasicBlock(blocks->at(i), next);
(...skipping 11 matching lines...) Expand all
143 va_list arguments; 467 va_list arguments;
144 va_start(arguments, format); 468 va_start(arguments, format);
145 OS::VPrint(format, arguments); 469 OS::VPrint(format, arguments);
146 va_end(arguments); 470 va_end(arguments);
147 PrintF("\n"); 471 PrintF("\n");
148 } 472 }
149 status_ = ABORTED; 473 status_ = ABORTED;
150 } 474 }
151 475
152 476
477 LRegister* LChunkBuilder::ToOperand(Register reg) {
478 return LRegister::Create(Register::ToAllocationIndex(reg));
479 }
480
481
482 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
483 return new LUnallocated(LUnallocated::FIXED_REGISTER,
484 Register::ToAllocationIndex(reg));
485 }
486
487
488 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
489 return new LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
490 XMMRegister::ToAllocationIndex(reg));
491 }
492
493
494 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
495 return Use(value, ToUnallocated(fixed_register));
496 }
497
498
499 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
500 return Use(value, ToUnallocated(reg));
501 }
502
503
504 LOperand* LChunkBuilder::UseRegister(HValue* value) {
505 return Use(value, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
506 }
507
508
509 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
510 return Use(value,
511 new LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
512 LUnallocated::USED_AT_START));
513 }
514
515
516 LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
517 return Use(value, new LUnallocated(LUnallocated::WRITABLE_REGISTER));
518 }
519
520
521 LOperand* LChunkBuilder::Use(HValue* value) {
522 return Use(value, new LUnallocated(LUnallocated::NONE));
523 }
524
525
526 LOperand* LChunkBuilder::UseAtStart(HValue* value) {
527 return Use(value, new LUnallocated(LUnallocated::NONE,
528 LUnallocated::USED_AT_START));
529 }
530
531
532 LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
533 return value->IsConstant()
534 ? chunk_->DefineConstantOperand(HConstant::cast(value))
535 : Use(value);
536 }
537
538
539 LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
540 return value->IsConstant()
541 ? chunk_->DefineConstantOperand(HConstant::cast(value))
542 : UseAtStart(value);
543 }
544
545
546 LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
547 return value->IsConstant()
548 ? chunk_->DefineConstantOperand(HConstant::cast(value))
549 : UseRegister(value);
550 }
551
552
553 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
554 return value->IsConstant()
555 ? chunk_->DefineConstantOperand(HConstant::cast(value))
556 : UseRegisterAtStart(value);
557 }
558
559
560 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
561 if (value->EmitAtUses()) {
562 HInstruction* instr = HInstruction::cast(value);
563 VisitInstruction(instr);
564 }
565 allocator_->RecordUse(value, operand);
566 return operand;
567 }
568
569
570 template<int I, int T>
571 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
572 LUnallocated* result) {
573 allocator_->RecordDefinition(current_instruction_, result);
574 instr->set_result(result);
575 return instr;
576 }
577
578
579 template<int I, int T>
580 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr) {
581 return Define(instr, new LUnallocated(LUnallocated::NONE));
582 }
583
584
585 template<int I, int T>
586 LInstruction* LChunkBuilder::DefineAsRegister(
587 LTemplateInstruction<1, I, T>* instr) {
588 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
589 }
590
591
592 template<int I, int T>
593 LInstruction* LChunkBuilder::DefineAsSpilled(
594 LTemplateInstruction<1, I, T>* instr,
595 int index) {
596 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index));
597 }
598
599
600 template<int I, int T>
601 LInstruction* LChunkBuilder::DefineSameAsFirst(
602 LTemplateInstruction<1, I, T>* instr) {
603 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
604 }
605
606
607 template<int I, int T>
608 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1, I, T>* instr,
609 Register reg) {
610 return Define(instr, ToUnallocated(reg));
611 }
612
613
614 template<int I, int T>
615 LInstruction* LChunkBuilder::DefineFixedDouble(
616 LTemplateInstruction<1, I, T>* instr,
617 XMMRegister reg) {
618 return Define(instr, ToUnallocated(reg));
619 }
620
621
622 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
623 HEnvironment* hydrogen_env = current_block_->last_environment();
624 instr->set_environment(CreateEnvironment(hydrogen_env));
625 return instr;
626 }
627
628
629 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
630 LInstruction* instr, int ast_id) {
631 ASSERT(instructions_pending_deoptimization_environment_ == NULL);
632 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
633 instructions_pending_deoptimization_environment_ = instr;
634 pending_deoptimization_ast_id_ = ast_id;
635 return instr;
636 }
637
638
639 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
640 instructions_pending_deoptimization_environment_ = NULL;
641 pending_deoptimization_ast_id_ = AstNode::kNoNumber;
642 }
643
644
645 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
646 HInstruction* hinstr,
647 CanDeoptimize can_deoptimize) {
648 allocator_->MarkAsCall();
649 instr = AssignPointerMap(instr);
650
651 if (hinstr->HasSideEffects()) {
652 ASSERT(hinstr->next()->IsSimulate());
653 HSimulate* sim = HSimulate::cast(hinstr->next());
654 instr = SetInstructionPendingDeoptimizationEnvironment(
655 instr, sim->ast_id());
656 }
657
658 // If instruction does not have side-effects lazy deoptimization
659 // after the call will try to deoptimize to the point before the call.
660 // Thus we still need to attach environment to this call even if
661 // call sequence can not deoptimize eagerly.
662 bool needs_environment =
663 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
664 if (needs_environment && !instr->HasEnvironment()) {
665 instr = AssignEnvironment(instr);
666 }
667
668 return instr;
669 }
670
671
672 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
673 allocator_->MarkAsSaveDoubles();
674 return instr;
675 }
676
677
678 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
679 ASSERT(!instr->HasPointerMap());
680 instr->set_pointer_map(new LPointerMap(position_));
681 return instr;
682 }
683
684
685 LUnallocated* LChunkBuilder::TempRegister() {
686 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
687 allocator_->RecordTemporary(operand);
688 return operand;
689 }
690
691
692 LOperand* LChunkBuilder::FixedTemp(Register reg) {
693 LUnallocated* operand = ToUnallocated(reg);
694 allocator_->RecordTemporary(operand);
695 return operand;
696 }
697
698
699 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) {
700 LUnallocated* operand = ToUnallocated(reg);
701 allocator_->RecordTemporary(operand);
702 return operand;
703 }
704
705
706 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
707 return new LLabel(instr->block());
708 }
709
710
711 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
712 return AssignEnvironment(new LDeoptimize);
713 }
714
715
716 LInstruction* LChunkBuilder::DoBit(Token::Value op,
717 HBitwiseBinaryOperation* instr) {
718 Abort("Unimplemented: %s", "DoBit");
719 return NULL;
720 }
721
722
723 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
724 HArithmeticBinaryOperation* instr) {
725 Abort("Unimplemented: %s", "DoArithmeticD");
726 return NULL;
727 }
728
729
730 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
731 HArithmeticBinaryOperation* instr) {
732 Abort("Unimplemented: %s", "DoArithmeticT");
733 return NULL;
734 }
735
153 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 736 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
154 ASSERT(is_building()); 737 Abort("Unimplemented: %s", "DoBasicBlock");
155 Abort("Lithium not implemented on x64."); 738 }
156 } 739
157 740
741 void LChunkBuilder::VisitInstruction(HInstruction* current) {
742 HInstruction* old_current = current_instruction_;
743 current_instruction_ = current;
744 allocator_->BeginInstruction();
745 if (current->has_position()) position_ = current->position();
746 LInstruction* instr = current->CompileToLithium(this);
747
748 if (instr != NULL) {
749 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
750 instr = AssignPointerMap(instr);
751 }
752 if (FLAG_stress_environments && !instr->HasEnvironment()) {
753 instr = AssignEnvironment(instr);
754 }
755 if (current->IsBranch()) {
756 instr->set_hydrogen_value(HBranch::cast(current)->value());
757 } else {
758 instr->set_hydrogen_value(current);
759 }
760
761 int index = chunk_->AddInstruction(instr, current_block_);
762 allocator_->SummarizeInstruction(index);
763 } else {
764 // This instruction should be omitted.
765 allocator_->OmitInstruction();
766 }
767 current_instruction_ = old_current;
768 }
769
770
771 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
772 if (hydrogen_env == NULL) return NULL;
773
774 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
775 int ast_id = hydrogen_env->ast_id();
776 ASSERT(ast_id != AstNode::kNoNumber);
777 int value_count = hydrogen_env->length();
778 LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
779 ast_id,
780 hydrogen_env->parameter_count(),
781 argument_count_,
782 value_count,
783 outer);
784 int argument_index = 0;
785 for (int i = 0; i < value_count; ++i) {
786 HValue* value = hydrogen_env->values()->at(i);
787 LOperand* op = NULL;
788 if (value->IsArgumentsObject()) {
789 op = NULL;
790 } else if (value->IsPushArgument()) {
791 op = new LArgument(argument_index++);
792 } else {
793 op = UseOrConstant(value);
794 if (op->IsUnallocated()) {
795 LUnallocated* unalloc = LUnallocated::cast(op);
796 unalloc->set_policy(LUnallocated::ANY);
797 }
798 }
799 result->AddValue(op, value->representation());
800 }
801
802 return result;
803 }
804
805
806 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
807 Abort("Unimplemented: %s", "DoGoto");
808 return NULL;
809 }
810
811
812 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
813 Abort("Unimplemented: %s", "DoBranch");
814 return NULL;
815 }
816
817
818 LInstruction* LChunkBuilder::DoCompareMapAndBranch(
819 HCompareMapAndBranch* instr) {
820 Abort("Unimplemented: %s", "DoCompareMapAndBranch");
821 return NULL;
822 }
823
824
825 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
826 Abort("Unimplemented: %s", "DoArgumentsLength");
827 return NULL;
828 }
829
830
831 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
832 Abort("Unimplemented: %s", "DoArgumentsElements");
833 return NULL;
834 }
835
836
837 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
838 Abort("Unimplemented: %s", "DoInstanceOf");
839 return NULL;
840 }
841
842
843 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
844 HInstanceOfKnownGlobal* instr) {
845 Abort("Unimplemented: %s", "DoInstanceOfKnownGlobal");
846 return NULL;
847 }
848
849
850 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
851 Abort("Unimplemented: %s", "DoApplyArguments");
852 return NULL;
853 }
854
855
856 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
857 Abort("Unimplemented: %s", "DoPushArgument");
858 return NULL;
859 }
860
861
862 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
863 Abort("Unimplemented: %s", "DoGlobalObject");
864 return NULL;
865 }
866
867
868 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
869 Abort("Unimplemented: %s", "DoGlobalReceiver");
870 return NULL;
871 }
872
873
874 LInstruction* LChunkBuilder::DoCallConstantFunction(
875 HCallConstantFunction* instr) {
876 Abort("Unimplemented: %s", "DoCallConstantFunction");
877 return NULL;
878 }
879
880
881 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
882 Abort("Unimplemented: %s", "DoUnaryMathOperation");
883 return NULL;
884 }
885
886
887 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
888 Abort("Unimplemented: %s", "DoCallKeyed");
889 return NULL;
890 }
891
892
893 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
894 Abort("Unimplemented: %s", "DoCallNamed");
895 return NULL;
896 }
897
898
899 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
900 Abort("Unimplemented: %s", "DoCallGlobal");
901 return NULL;
902 }
903
904
905 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
906 Abort("Unimplemented: %s", "DoCallKnownGlobal");
907 return NULL;
908 }
909
910
911 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
912 Abort("Unimplemented: %s", "DoCallNew");
913 return NULL;
914 }
915
916
917 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
918 Abort("Unimplemented: %s", "DoCallFunction");
919 return NULL;
920 }
921
922
923 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
924 Abort("Unimplemented: %s", "DoCallRuntime");
925 return NULL;
926 }
927
928
929 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
930 Abort("Unimplemented: %s", "DoShr");
931 return NULL;
932 }
933
934
935 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
936 Abort("Unimplemented: %s", "DoSar");
937 return NULL;
938 }
939
940
941 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
942 Abort("Unimplemented: %s", "DoShl");
943 return NULL;
944 }
945
946
947 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
948 Abort("Unimplemented: %s", "DoBitAnd");
949 return NULL;
950 }
951
952
953 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
954 Abort("Unimplemented: %s", "DoBitNot");
955 return NULL;
956 }
957
958
959 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
960 Abort("Unimplemented: %s", "DoBitOr");
961 return NULL;
962 }
963
964
965 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
966 Abort("Unimplemented: %s", "DoBitXor");
967 return NULL;
968 }
969
970
971 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
972 Abort("Unimplemented: %s", "DoDiv");
973 return NULL;
974 }
975
976
977 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
978 Abort("Unimplemented: %s", "DoMod");
979 return NULL;
980 }
981
982
983 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
984 Abort("Unimplemented: %s", "DoMul");
985 return NULL;
986 }
987
988
989 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
990 Abort("Unimplemented: %s", "DoSub");
991 return NULL;
992 }
993
994
995 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
996 Abort("Unimplemented: %s", "DoAdd");
997 return NULL;
998 }
999
1000
1001 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1002 Abort("Unimplemented: %s", "DoPower");
1003 return NULL;
1004 }
1005
1006
1007 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1008 Abort("Unimplemented: %s", "DoCompare");
1009 return NULL;
1010 }
1011
1012
1013 LInstruction* LChunkBuilder::DoCompareJSObjectEq(
1014 HCompareJSObjectEq* instr) {
1015 Abort("Unimplemented: %s", "DoCompareJSObjectEq");
1016 return NULL;
1017 }
1018
1019
1020 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
1021 Abort("Unimplemented: %s", "DoIsNull");
1022 return NULL;
1023 }
1024
1025
1026 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
1027 Abort("Unimplemented: %s", "DoIsObject");
1028 return NULL;
1029 }
1030
1031
1032 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
1033 Abort("Unimplemented: %s", "DoIsSmi");
1034 return NULL;
1035 }
1036
1037
1038 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
1039 Abort("Unimplemented: %s", "DoHasInstanceType");
1040 return NULL;
1041 }
1042
1043
1044 LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
1045 HHasCachedArrayIndex* instr) {
1046 Abort("Unimplemented: %s", "DoHasCachedArrayIndex");
1047 return NULL;
1048 }
1049
1050
1051 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1052 Abort("Unimplemented: %s", "DoClassOfTest");
1053 return NULL;
1054 }
1055
1056
1057 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1058 Abort("Unimplemented: %s", "DoJSArrayLength");
1059 return NULL;
1060 }
1061
1062
1063 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1064 Abort("Unimplemented: %s", "DoFixedArrayLength");
1065 return NULL;
1066 }
1067
1068
1069 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1070 Abort("Unimplemented: %s", "DoValueOf");
1071 return NULL;
1072 }
1073
1074
1075 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1076 Abort("Unimplemented: %s", "DoBoundsCheck");
1077 return NULL;
1078 }
1079
1080
1081 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1082 Abort("Unimplemented: %s", "DoThrow");
1083 return NULL;
1084 }
1085
1086
1087 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1088 Abort("Unimplemented: %s", "DoChange");
1089 return NULL;
1090 }
1091
1092
1093 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1094 Abort("Unimplemented: %s", "DoCheckNonSmi");
1095 return NULL;
1096 }
1097
1098
1099 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1100 Abort("Unimplemented: %s", "DoCheckInstanceType");
1101 return NULL;
1102 }
1103
1104
1105 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1106 Abort("Unimplemented: %s", "DoCheckPrototypeMaps");
1107 return NULL;
1108 }
1109
1110
1111 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1112 Abort("Unimplemented: %s", "DoCheckSmi");
1113 return NULL;
1114 }
1115
1116
1117 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1118 Abort("Unimplemented: %s", "DoCheckFunction");
1119 return NULL;
1120 }
1121
1122
1123 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
1124 Abort("Unimplemented: %s", "DoCheckMap");
1125 return NULL;
1126 }
1127
1128
1129 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1130 Abort("Unimplemented: %s", "DoReturn");
1131 return NULL;
1132 }
1133
1134
1135 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1136 Abort("Unimplemented: %s", "DoConstant");
1137 return NULL;
1138 }
1139
1140
1141 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1142 Abort("Unimplemented: %s", "DoLoadGlobal");
1143 return NULL;
1144 }
1145
1146
1147 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1148 Abort("Unimplemented: %s", "DoStoreGlobal");
1149 return NULL;
1150 }
1151
1152
1153 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1154 Abort("Unimplemented: %s", "DoLoadNamedField");
1155 return NULL;
1156 }
1157
1158
1159 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1160 Abort("Unimplemented: %s", "DoLoadNamedGeneric");
1161 return NULL;
1162 }
1163
1164
1165 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1166 HLoadFunctionPrototype* instr) {
1167 Abort("Unimplemented: %s", "DoLoadFunctionPrototype");
1168 return NULL;
1169 }
1170
1171
1172 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1173 Abort("Unimplemented: %s", "DoLoadElements");
1174 return NULL;
1175 }
1176
1177
1178 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1179 HLoadKeyedFastElement* instr) {
1180 Abort("Unimplemented: %s", "DoLoadKeyedFastElement");
1181 return NULL;
1182 }
1183
1184
1185 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1186 Abort("Unimplemented: %s", "DoLoadKeyedGeneric");
1187 return NULL;
1188 }
1189
1190
1191 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1192 HStoreKeyedFastElement* instr) {
1193 Abort("Unimplemented: %s", "DoStoreKeyedFastElement");
1194 return NULL;
1195 }
1196
1197
1198 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
1199 Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
1200 return NULL;
1201 }
1202
1203
1204 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1205 Abort("Unimplemented: %s", "DoStoreNamedField");
1206 return NULL;
1207 }
1208
1209
1210 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1211 Abort("Unimplemented: %s", "DoStoreNamedGeneric");
1212 return NULL;
1213 }
1214
1215
1216 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1217 Abort("Unimplemented: %s", "DoArrayLiteral");
1218 return NULL;
1219 }
1220
1221
1222 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1223 Abort("Unimplemented: %s", "DoObjectLiteral");
1224 return NULL;
1225 }
1226
1227
1228 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1229 Abort("Unimplemented: %s", "DoRegExpLiteral");
1230 return NULL;
1231 }
1232
1233
1234 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1235 Abort("Unimplemented: %s", "DoFunctionLiteral");
1236 return NULL;
1237 }
1238
1239
1240 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1241 Abort("Unimplemented: %s", "DoDeleteProperty");
1242 return NULL;
1243 }
1244
1245
1246 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1247 Abort("Unimplemented: %s", "DoOsrEntry");
1248 return NULL;
1249 }
1250
1251
1252 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
1253 Abort("Unimplemented: %s", "DoParameter");
1254 return NULL;
1255 }
1256
1257
1258 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
1259 Abort("Unimplemented: %s", "DoUnknownOSRValue");
1260 return NULL;
1261 }
1262
1263
1264 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
1265 Abort("Unimplemented: %s", "DoCallStub");
1266 return NULL;
1267 }
1268
1269
1270 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
1271 Abort("Unimplemented: %s", "DoArgumentsObject");
1272 return NULL;
1273 }
1274
1275
1276 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
1277 Abort("Unimplemented: %s", "DoAccessArgumentsAt");
1278 return NULL;
1279 }
1280
1281
1282 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
1283 Abort("Unimplemented: %s", "DoTypeof");
1284 return NULL;
1285 }
1286
1287
1288 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
1289 Abort("Unimplemented: %s", "DoTypeofIs");
1290 return NULL;
1291 }
1292
1293 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
1294 Abort("Unimplemented: %s", "DoSimulate");
1295 return NULL;
1296 }
1297
1298
1299 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
1300 Abort("Unimplemented: %s", "DoStackCheck");
1301 return NULL;
1302 }
1303
1304
1305 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
1306 Abort("Unimplemented: %s", "DoEnterInlined");
1307 return NULL;
1308 }
1309
1310
1311 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
1312 Abort("Unimplemented: %s", "DoLeaveInlined");
1313 return NULL;
1314 }
158 1315
159 } } // namespace v8::internal 1316 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698