OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
9 #include "src/compiler/pipeline.h" | 9 #include "src/compiler/pipeline.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace compiler { | 13 namespace compiler { |
14 | 14 |
15 CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, | 15 CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage, |
16 InstructionSequence* code, CompilationInfo* info) | 16 InstructionSequence* code, CompilationInfo* info) |
17 : frame_(frame), | 17 : frame_(frame), |
18 linkage_(linkage), | 18 linkage_(linkage), |
19 code_(code), | 19 code_(code), |
20 info_(info), | 20 info_(info), |
| 21 labels_(zone()->NewArray<Label>(code->InstructionBlockCount())), |
21 current_block_(BasicBlock::RpoNumber::Invalid()), | 22 current_block_(BasicBlock::RpoNumber::Invalid()), |
22 current_source_position_(SourcePosition::Invalid()), | 23 current_source_position_(SourcePosition::Invalid()), |
23 masm_(code->zone()->isolate(), NULL, 0), | 24 masm_(code->zone()->isolate(), NULL, 0), |
24 resolver_(this), | 25 resolver_(this), |
25 safepoints_(code->zone()), | 26 safepoints_(code->zone()), |
26 deoptimization_states_(code->zone()), | 27 deoptimization_states_(code->zone()), |
27 deoptimization_literals_(code->zone()), | 28 deoptimization_literals_(code->zone()), |
28 translations_(code->zone()), | 29 translations_(code->zone()), |
29 last_lazy_deopt_pc_(0) {} | 30 last_lazy_deopt_pc_(0) { |
| 31 for (int i = 0; i < code->InstructionBlockCount(); ++i) { |
| 32 new (&labels_[i]) Label; |
| 33 } |
| 34 } |
30 | 35 |
31 | 36 |
32 Handle<Code> CodeGenerator::GenerateCode() { | 37 Handle<Code> CodeGenerator::GenerateCode() { |
33 CompilationInfo* info = this->info(); | 38 CompilationInfo* info = this->info(); |
34 | 39 |
35 // Emit a code line info recording start event. | 40 // Emit a code line info recording start event. |
36 PositionsRecorder* recorder = masm()->positions_recorder(); | 41 PositionsRecorder* recorder = masm()->positions_recorder(); |
37 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); | 42 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); |
38 | 43 |
39 // Place function entry hook if requested to do so. | 44 // Place function entry hook if requested to do so. |
40 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { | 45 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { |
41 ProfileEntryHookStub::MaybeCallEntryHook(masm()); | 46 ProfileEntryHookStub::MaybeCallEntryHook(masm()); |
42 } | 47 } |
43 | 48 |
44 // Architecture-specific, linkage-specific prologue. | 49 // Architecture-specific, linkage-specific prologue. |
45 info->set_prologue_offset(masm()->pc_offset()); | 50 info->set_prologue_offset(masm()->pc_offset()); |
46 AssemblePrologue(); | 51 AssemblePrologue(); |
47 | 52 |
48 // Assemble all non-deferred instructions. | 53 // Assemble all non-deferred blocks, followed by deferred ones. |
49 for (auto const block : code()->instruction_blocks()) { | 54 for (int deferred = 0; deferred < 2; ++deferred) { |
50 if (block->IsDeferred()) continue; | 55 for (auto const block : code()->instruction_blocks()) { |
51 for (int i = block->code_start(); i < block->code_end(); ++i) { | 56 if (block->IsDeferred() == (deferred == 0)) { |
52 AssembleInstruction(code()->InstructionAt(i)); | 57 continue; |
| 58 } |
| 59 // Bind a label for a block. |
| 60 current_block_ = block->rpo_number(); |
| 61 if (FLAG_code_comments) { |
| 62 // TODO(titzer): these code comments are a giant memory leak. |
| 63 Vector<char> buffer = Vector<char>::New(32); |
| 64 SNPrintF(buffer, "-- B%d start --", block->id().ToInt()); |
| 65 masm()->RecordComment(buffer.start()); |
| 66 } |
| 67 masm()->bind(GetLabel(current_block_)); |
| 68 for (int i = block->code_start(); i < block->code_end(); ++i) { |
| 69 AssembleInstruction(code()->InstructionAt(i)); |
| 70 } |
53 } | 71 } |
54 } | 72 } |
55 | 73 |
56 // Assemble all deferred instructions. | |
57 for (auto const block : code()->instruction_blocks()) { | |
58 if (!block->IsDeferred()) continue; | |
59 for (int i = block->code_start(); i < block->code_end(); ++i) { | |
60 AssembleInstruction(code()->InstructionAt(i)); | |
61 } | |
62 } | |
63 | |
64 FinishCode(masm()); | 74 FinishCode(masm()); |
65 | 75 |
66 // Ensure there is space for lazy deopt. | 76 // Ensure there is space for lazy deopt. |
67 if (!info->IsStub()) { | 77 if (!info->IsStub()) { |
68 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); | 78 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); |
69 while (masm()->pc_offset() < target_offset) { | 79 while (masm()->pc_offset() < target_offset) { |
70 masm()->nop(); | 80 masm()->nop(); |
71 } | 81 } |
72 } | 82 } |
73 | 83 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 safepoint.DefinePointerSlot(pointer->index(), zone()); | 123 safepoint.DefinePointerSlot(pointer->index(), zone()); |
114 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { | 124 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { |
115 Register reg = Register::FromAllocationIndex(pointer->index()); | 125 Register reg = Register::FromAllocationIndex(pointer->index()); |
116 safepoint.DefinePointerRegister(reg, zone()); | 126 safepoint.DefinePointerRegister(reg, zone()); |
117 } | 127 } |
118 } | 128 } |
119 } | 129 } |
120 | 130 |
121 | 131 |
122 void CodeGenerator::AssembleInstruction(Instruction* instr) { | 132 void CodeGenerator::AssembleInstruction(Instruction* instr) { |
123 if (instr->IsBlockStart()) { | |
124 // Bind a label for a block start and handle parallel moves. | |
125 BlockStartInstruction* block_start = BlockStartInstruction::cast(instr); | |
126 current_block_ = block_start->rpo_number(); | |
127 if (FLAG_code_comments) { | |
128 // TODO(titzer): these code comments are a giant memory leak. | |
129 Vector<char> buffer = Vector<char>::New(32); | |
130 SNPrintF(buffer, "-- B%d start --", block_start->id().ToInt()); | |
131 masm()->RecordComment(buffer.start()); | |
132 } | |
133 masm()->bind(block_start->label()); | |
134 } | |
135 if (instr->IsGapMoves()) { | 133 if (instr->IsGapMoves()) { |
136 // Handle parallel moves associated with the gap instruction. | 134 // Handle parallel moves associated with the gap instruction. |
137 AssembleGap(GapInstruction::cast(instr)); | 135 AssembleGap(GapInstruction::cast(instr)); |
138 } else if (instr->IsSourcePosition()) { | 136 } else if (instr->IsSourcePosition()) { |
139 AssembleSourcePosition(SourcePositionInstruction::cast(instr)); | 137 AssembleSourcePosition(SourcePositionInstruction::cast(instr)); |
140 } else { | 138 } else { |
141 // Assemble architecture-specific code for the instruction. | 139 // Assemble architecture-specific code for the instruction. |
142 AssembleArchInstruction(instr); | 140 AssembleArchInstruction(instr); |
143 | 141 |
144 // Assemble branches or boolean materializations after this instruction. | 142 // Assemble branches or boolean materializations after this instruction. |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 523 } |
526 | 524 |
527 | 525 |
528 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 526 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
529 | 527 |
530 #endif // !V8_TURBOFAN_BACKEND | 528 #endif // !V8_TURBOFAN_BACKEND |
531 | 529 |
532 } // namespace compiler | 530 } // namespace compiler |
533 } // namespace internal | 531 } // namespace internal |
534 } // namespace v8 | 532 } // namespace v8 |
OLD | NEW |