| 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 |