1 // Copyright 2014 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_CODE_GENERATOR_H_ 6 #define V8_COMPILER_CODE_GENERATOR_H_ 7 8 #include <deque> 9 10 #include "src/compiler/gap-resolver.h" 11 #include "src/compiler/instruction.h" 12 #include "src/deoptimizer.h" 13 #include "src/macro-assembler.h" 14 #include "src/safepoint-table.h" 15 16 namespace v8 { 17 namespace internal { 18 namespace compiler { 19 20 // Generates native code for a sequence of instructions. 21 class CodeGenerator FINAL : public GapResolver::Assembler { 22 public: 23 explicit CodeGenerator(InstructionSequence* code); 24 25 // Generate native code. 26 Handle<Code> GenerateCode(); 27 code()28 InstructionSequence* code() const { return code_; } frame()29 Frame* frame() const { return code()->frame(); } graph()30 Graph* graph() const { return code()->graph(); } isolate()31 Isolate* isolate() const { return zone()->isolate(); } linkage()32 Linkage* linkage() const { return code()->linkage(); } schedule()33 Schedule* schedule() const { return code()->schedule(); } 34 35 private: masm()36 MacroAssembler* masm() { return &masm_; } resolver()37 GapResolver* resolver() { return &resolver_; } safepoints()38 SafepointTableBuilder* safepoints() { return &safepoints_; } zone()39 Zone* zone() const { return code()->zone(); } 40 41 // Checks if {block} will appear directly after {current_block_} when 42 // assembling code, in which case, a fall-through can be used. IsNextInAssemblyOrder(const BasicBlock * block)43 bool IsNextInAssemblyOrder(const BasicBlock* block) const { 44 return block->rpo_number_ == (current_block_->rpo_number_ + 1) && 45 block->deferred_ == current_block_->deferred_; 46 } 47 48 // Record a safepoint with the given pointer map. 49 void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind, 50 int arguments, Safepoint::DeoptMode deopt_mode); 51 52 // Assemble code for the specified instruction. 53 void AssembleInstruction(Instruction* instr); 54 void AssembleSourcePosition(SourcePositionInstruction* instr); 55 void AssembleGap(GapInstruction* gap); 56 57 // =========================================================================== 58 // ============= Architecture-specific code generation methods. ============== 59 // =========================================================================== 60 61 void AssembleArchInstruction(Instruction* instr); 62 void AssembleArchBranch(Instruction* instr, FlagsCondition condition); 63 void AssembleArchBoolean(Instruction* instr, FlagsCondition condition); 64 65 void AssembleDeoptimizerCall(int deoptimization_id); 66 67 // Generates an architecture-specific, descriptor-specific prologue 68 // to set up a stack frame. 69 void AssemblePrologue(); 70 // Generates an architecture-specific, descriptor-specific return sequence 71 // to tear down a stack frame. 72 void AssembleReturn(); 73 74 // =========================================================================== 75 // ============== Architecture-specific gap resolver methods. ================ 76 // =========================================================================== 77 78 // Interface used by the gap resolver to emit moves and swaps. 79 virtual void AssembleMove(InstructionOperand* source, 80 InstructionOperand* destination) OVERRIDE; 81 virtual void AssembleSwap(InstructionOperand* source, 82 InstructionOperand* destination) OVERRIDE; 83 84 // =========================================================================== 85 // Deoptimization table construction 86 void AddSafepointAndDeopt(Instruction* instr); 87 void PopulateDeoptimizationData(Handle<Code> code); 88 int DefineDeoptimizationLiteral(Handle<Object> literal); 89 FrameStateDescriptor* GetFrameStateDescriptor(Instruction* instr, 90 size_t frame_state_offset); 91 int BuildTranslation(Instruction* instr, int pc_offset, 92 size_t frame_state_offset, 93 OutputFrameStateCombine state_combine); 94 void BuildTranslationForFrameStateDescriptor( 95 FrameStateDescriptor* descriptor, Instruction* instr, 96 Translation* translation, size_t frame_state_offset, 97 OutputFrameStateCombine state_combine); 98 void AddTranslationForOperand(Translation* translation, Instruction* instr, 99 InstructionOperand* op); 100 void AddNopForSmiCodeInlining(); 101 void EnsureSpaceForLazyDeopt(); 102 void MarkLazyDeoptSite(); 103 104 // =========================================================================== 105 struct DeoptimizationState : ZoneObject { 106 public: bailout_idDeoptimizationState107 BailoutId bailout_id() const { return bailout_id_; } translation_idDeoptimizationState108 int translation_id() const { return translation_id_; } pc_offsetDeoptimizationState109 int pc_offset() const { return pc_offset_; } 110 DeoptimizationStateDeoptimizationState111 DeoptimizationState(BailoutId bailout_id, int translation_id, int pc_offset) 112 : bailout_id_(bailout_id), 113 translation_id_(translation_id), 114 pc_offset_(pc_offset) {} 115 116 private: 117 BailoutId bailout_id_; 118 int translation_id_; 119 int pc_offset_; 120 }; 121 122 InstructionSequence* code_; 123 BasicBlock* current_block_; 124 SourcePosition current_source_position_; 125 MacroAssembler masm_; 126 GapResolver resolver_; 127 SafepointTableBuilder safepoints_; 128 ZoneDeque<DeoptimizationState*> deoptimization_states_; 129 ZoneDeque<Handle<Object> > deoptimization_literals_; 130 TranslationBuffer translations_; 131 int last_lazy_deopt_pc_; 132 }; 133 134 } // namespace compiler 135 } // namespace internal 136 } // namespace v8 137 138 #endif // V8_COMPILER_CODE_GENERATOR_H 139