• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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