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_(static_cast<size_t>(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) {} |
30 | 31 |
31 | 32 |
32 Handle<Code> CodeGenerator::GenerateCode() { | 33 Handle<Code> CodeGenerator::GenerateCode() { |
33 CompilationInfo* info = this->info(); | 34 CompilationInfo* info = this->info(); |
34 | 35 |
35 // Emit a code line info recording start event. | 36 // Emit a code line info recording start event. |
36 PositionsRecorder* recorder = masm()->positions_recorder(); | 37 PositionsRecorder* recorder = masm()->positions_recorder(); |
37 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); | 38 LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder)); |
38 | 39 |
39 // Place function entry hook if requested to do so. | 40 // Place function entry hook if requested to do so. |
40 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { | 41 if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) { |
41 ProfileEntryHookStub::MaybeCallEntryHook(masm()); | 42 ProfileEntryHookStub::MaybeCallEntryHook(masm()); |
42 } | 43 } |
43 | 44 |
44 // Architecture-specific, linkage-specific prologue. | 45 // Architecture-specific, linkage-specific prologue. |
45 info->set_prologue_offset(masm()->pc_offset()); | 46 info->set_prologue_offset(masm()->pc_offset()); |
46 AssemblePrologue(); | 47 AssemblePrologue(); |
47 | 48 |
48 // Assemble all non-deferred instructions. | 49 // Assemble all non-deferred blocks, followed by deferred ones. |
49 for (auto const block : code()->instruction_blocks()) { | 50 for (int deferred = 0; deferred < 2; ++deferred) { |
50 if (block->IsDeferred()) continue; | 51 for (auto const block : code()->instruction_blocks()) { |
51 for (int i = block->code_start(); i < block->code_end(); ++i) { | 52 if (block->IsDeferred() == (deferred == 0)) { |
52 AssembleInstruction(code()->InstructionAt(i)); | 53 continue; |
| 54 } |
| 55 // Bind a label for a block. |
| 56 current_block_ = block->rpo_number(); |
| 57 if (FLAG_code_comments) { |
| 58 // TODO(titzer): these code comments are a giant memory leak. |
| 59 Vector<char> buffer = Vector<char>::New(32); |
| 60 SNPrintF(buffer, "-- B%d start --", block->id().ToInt()); |
| 61 masm()->RecordComment(buffer.start()); |
| 62 } |
| 63 masm()->bind(GetLabel(current_block_)); |
| 64 for (int i = block->code_start(); i < block->code_end(); ++i) { |
| 65 AssembleInstruction(code()->InstructionAt(i)); |
| 66 } |
53 } | 67 } |
54 } | 68 } |
55 | 69 |
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()); | 70 FinishCode(masm()); |
65 | 71 |
66 // Ensure there is space for lazy deopt. | 72 // Ensure there is space for lazy deopt. |
67 if (!info->IsStub()) { | 73 if (!info->IsStub()) { |
68 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); | 74 int target_offset = masm()->pc_offset() + Deoptimizer::patch_size(); |
69 while (masm()->pc_offset() < target_offset) { | 75 while (masm()->pc_offset() < target_offset) { |
70 masm()->nop(); | 76 masm()->nop(); |
71 } | 77 } |
72 } | 78 } |
73 | 79 |
(...skipping 39 matching lines...) Loading... |
113 safepoint.DefinePointerSlot(pointer->index(), zone()); | 119 safepoint.DefinePointerSlot(pointer->index(), zone()); |
114 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { | 120 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { |
115 Register reg = Register::FromAllocationIndex(pointer->index()); | 121 Register reg = Register::FromAllocationIndex(pointer->index()); |
116 safepoint.DefinePointerRegister(reg, zone()); | 122 safepoint.DefinePointerRegister(reg, zone()); |
117 } | 123 } |
118 } | 124 } |
119 } | 125 } |
120 | 126 |
121 | 127 |
122 void CodeGenerator::AssembleInstruction(Instruction* instr) { | 128 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()) { | 129 if (instr->IsGapMoves()) { |
136 // Handle parallel moves associated with the gap instruction. | 130 // Handle parallel moves associated with the gap instruction. |
137 AssembleGap(GapInstruction::cast(instr)); | 131 AssembleGap(GapInstruction::cast(instr)); |
138 } else if (instr->IsSourcePosition()) { | 132 } else if (instr->IsSourcePosition()) { |
139 AssembleSourcePosition(SourcePositionInstruction::cast(instr)); | 133 AssembleSourcePosition(SourcePositionInstruction::cast(instr)); |
140 } else { | 134 } else { |
141 // Assemble architecture-specific code for the instruction. | 135 // Assemble architecture-specific code for the instruction. |
142 AssembleArchInstruction(instr); | 136 AssembleArchInstruction(instr); |
143 | 137 |
144 // Assemble branches or boolean materializations after this instruction. | 138 // Assemble branches or boolean materializations after this instruction. |
(...skipping 380 matching lines...) Loading... |
525 } | 519 } |
526 | 520 |
527 | 521 |
528 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 522 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
529 | 523 |
530 #endif // !V8_TURBOFAN_BACKEND | 524 #endif // !V8_TURBOFAN_BACKEND |
531 | 525 |
532 } // namespace compiler | 526 } // namespace compiler |
533 } // namespace internal | 527 } // namespace internal |
534 } // namespace v8 | 528 } // namespace v8 |
OLD | NEW |