Home | History | Annotate | Download | only in compiler
      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 "src/compiler/gap-resolver.h"
      9 #include "src/compiler/instruction.h"
     10 #include "src/deoptimizer.h"
     11 #include "src/macro-assembler.h"
     12 #include "src/safepoint-table.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 namespace compiler {
     17 
     18 // Forward declarations.
     19 class FrameAccessState;
     20 class Linkage;
     21 class OutOfLineCode;
     22 
     23 struct BranchInfo {
     24   FlagsCondition condition;
     25   Label* true_label;
     26   Label* false_label;
     27   bool fallthru;
     28 };
     29 
     30 
     31 class InstructionOperandIterator {
     32  public:
     33   InstructionOperandIterator(Instruction* instr, size_t pos)
     34       : instr_(instr), pos_(pos) {}
     35 
     36   Instruction* instruction() const { return instr_; }
     37   InstructionOperand* Advance() { return instr_->InputAt(pos_++); }
     38 
     39  private:
     40   Instruction* instr_;
     41   size_t pos_;
     42 };
     43 
     44 
     45 // Generates native code for a sequence of instructions.
     46 class CodeGenerator final : public GapResolver::Assembler {
     47  public:
     48   explicit CodeGenerator(Frame* frame, Linkage* linkage,
     49                          InstructionSequence* code, CompilationInfo* info);
     50 
     51   // Generate native code.
     52   Handle<Code> GenerateCode();
     53 
     54   InstructionSequence* code() const { return code_; }
     55   FrameAccessState* frame_access_state() const { return frame_access_state_; }
     56   Frame* frame() const { return frame_access_state_->frame(); }
     57   Isolate* isolate() const { return info_->isolate(); }
     58   Linkage* linkage() const { return linkage_; }
     59 
     60   Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
     61 
     62  private:
     63   MacroAssembler* masm() { return &masm_; }
     64   GapResolver* resolver() { return &resolver_; }
     65   SafepointTableBuilder* safepoints() { return &safepoints_; }
     66   Zone* zone() const { return code()->zone(); }
     67   CompilationInfo* info() const { return info_; }
     68 
     69   // Checks if {block} will appear directly after {current_block_} when
     70   // assembling code, in which case, a fall-through can be used.
     71   bool IsNextInAssemblyOrder(RpoNumber block) const;
     72 
     73   // Record a safepoint with the given pointer map.
     74   void RecordSafepoint(ReferenceMap* references, Safepoint::Kind kind,
     75                        int arguments, Safepoint::DeoptMode deopt_mode);
     76 
     77   // Check if a heap object can be materialized by loading from the frame, which
     78   // is usually way cheaper than materializing the actual heap object constant.
     79   bool IsMaterializableFromFrame(Handle<HeapObject> object, int* offset_return);
     80   // Check if a heap object can be materialized by loading from a heap root,
     81   // which is cheaper on some platforms than materializing the actual heap
     82   // object constant.
     83   bool IsMaterializableFromRoot(Handle<HeapObject> object,
     84                                 Heap::RootListIndex* index_return);
     85 
     86   // Assemble code for the specified instruction.
     87   void AssembleInstruction(Instruction* instr);
     88   void AssembleSourcePosition(Instruction* instr);
     89   void AssembleGaps(Instruction* instr);
     90 
     91   // ===========================================================================
     92   // ============= Architecture-specific code generation methods. ==============
     93   // ===========================================================================
     94 
     95   void AssembleArchInstruction(Instruction* instr);
     96   void AssembleArchJump(RpoNumber target);
     97   void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
     98   void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
     99   void AssembleArchLookupSwitch(Instruction* instr);
    100   void AssembleArchTableSwitch(Instruction* instr);
    101 
    102   void AssembleDeoptimizerCall(int deoptimization_id,
    103                                Deoptimizer::BailoutType bailout_type);
    104 
    105   // Generates an architecture-specific, descriptor-specific prologue
    106   // to set up a stack frame.
    107   void AssemblePrologue();
    108   // Generates an architecture-specific, descriptor-specific return sequence
    109   // to tear down a stack frame.
    110   void AssembleReturn();
    111 
    112   // Generates code to deconstruct a the caller's frame, including arguments.
    113   void AssembleDeconstructActivationRecord(int stack_param_delta);
    114 
    115   // Generates code to manipulate the stack in preparation for a tail call.
    116   void AssemblePrepareTailCall(int stack_param_delta);
    117 
    118   // ===========================================================================
    119   // ============== Architecture-specific gap resolver methods. ================
    120   // ===========================================================================
    121 
    122   // Interface used by the gap resolver to emit moves and swaps.
    123   void AssembleMove(InstructionOperand* source,
    124                     InstructionOperand* destination) final;
    125   void AssembleSwap(InstructionOperand* source,
    126                     InstructionOperand* destination) final;
    127 
    128   // ===========================================================================
    129   // =================== Jump table construction methods. ======================
    130   // ===========================================================================
    131 
    132   class JumpTable;
    133   // Adds a jump table that is emitted after the actual code.  Returns label
    134   // pointing to the beginning of the table.  {targets} is assumed to be static
    135   // or zone allocated.
    136   Label* AddJumpTable(Label** targets, size_t target_count);
    137   // Emits a jump table.
    138   void AssembleJumpTable(Label** targets, size_t target_count);
    139 
    140   // ===========================================================================
    141   // ================== Deoptimization table construction. =====================
    142   // ===========================================================================
    143 
    144   void RecordCallPosition(Instruction* instr);
    145   void PopulateDeoptimizationData(Handle<Code> code);
    146   int DefineDeoptimizationLiteral(Handle<Object> literal);
    147   FrameStateDescriptor* GetFrameStateDescriptor(
    148       Instruction* instr, size_t frame_access_state_offset);
    149   int BuildTranslation(Instruction* instr, int pc_offset,
    150                        size_t frame_access_state_offset,
    151                        OutputFrameStateCombine state_combine);
    152   void BuildTranslationForFrameStateDescriptor(
    153       FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
    154       Translation* translation, OutputFrameStateCombine state_combine);
    155   void TranslateStateValueDescriptor(StateValueDescriptor* desc,
    156                                      Translation* translation,
    157                                      InstructionOperandIterator* iter);
    158   void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
    159                                              InstructionOperandIterator* iter,
    160                                              OutputFrameStateCombine combine,
    161                                              Translation* translation);
    162   void AddTranslationForOperand(Translation* translation, Instruction* instr,
    163                                 InstructionOperand* op, MachineType type);
    164   void AddNopForSmiCodeInlining();
    165   void EnsureSpaceForLazyDeopt();
    166   void MarkLazyDeoptSite();
    167 
    168   // Converts the delta in the number of stack parameter passed from a tail
    169   // caller to the callee into the distance (in pointers) the SP must be
    170   // adjusted, taking frame elision and other relevant factors into
    171   // consideration.
    172   int TailCallFrameStackSlotDelta(int stack_param_delta);
    173 
    174   // ===========================================================================
    175 
    176   struct DeoptimizationState : ZoneObject {
    177    public:
    178     BailoutId bailout_id() const { return bailout_id_; }
    179     int translation_id() const { return translation_id_; }
    180     int pc_offset() const { return pc_offset_; }
    181 
    182     DeoptimizationState(BailoutId bailout_id, int translation_id, int pc_offset)
    183         : bailout_id_(bailout_id),
    184           translation_id_(translation_id),
    185           pc_offset_(pc_offset) {}
    186 
    187    private:
    188     BailoutId bailout_id_;
    189     int translation_id_;
    190     int pc_offset_;
    191   };
    192 
    193   struct HandlerInfo {
    194     bool caught_locally;
    195     Label* handler;
    196     int pc_offset;
    197   };
    198 
    199   friend class OutOfLineCode;
    200 
    201   FrameAccessState* frame_access_state_;
    202   Linkage* const linkage_;
    203   InstructionSequence* const code_;
    204   CompilationInfo* const info_;
    205   Label* const labels_;
    206   Label return_label_;
    207   RpoNumber current_block_;
    208   SourcePosition current_source_position_;
    209   MacroAssembler masm_;
    210   GapResolver resolver_;
    211   SafepointTableBuilder safepoints_;
    212   ZoneVector<HandlerInfo> handlers_;
    213   ZoneDeque<DeoptimizationState*> deoptimization_states_;
    214   ZoneDeque<Handle<Object>> deoptimization_literals_;
    215   size_t inlined_function_count_;
    216   TranslationBuffer translations_;
    217   int last_lazy_deopt_pc_;
    218   JumpTable* jump_tables_;
    219   OutOfLineCode* ools_;
    220   int osr_pc_offset_;
    221 };
    222 
    223 }  // namespace compiler
    224 }  // namespace internal
    225 }  // namespace v8
    226 
    227 #endif  // V8_COMPILER_CODE_GENERATOR_H
    228