| OLD | NEW | 
|    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 #ifndef VM_FLOW_GRAPH_COMPILER_IA32_H_ |    5 #ifndef VM_FLOW_GRAPH_COMPILER_IA32_H_ | 
|    6 #define VM_FLOW_GRAPH_COMPILER_IA32_H_ |    6 #define VM_FLOW_GRAPH_COMPILER_IA32_H_ | 
|    7  |    7  | 
|    8 #ifndef VM_FLOW_GRAPH_COMPILER_H_ |    8 #ifndef VM_FLOW_GRAPH_COMPILER_H_ | 
|    9 #error Include flow_graph_compiler.h instead of flow_graph_compiler_ia32.h. |    9 #error Include flow_graph_compiler.h instead of flow_graph_compiler_ia32.h. | 
|   10 #endif |   10 #endif | 
|   11  |   11  | 
|   12 #include "vm/assembler.h" |   12 #include "vm/assembler.h" | 
|   13 #include "vm/assembler_macros.h" |   13 #include "vm/assembler_macros.h" | 
|   14 #include "vm/code_descriptors.h" |   14 #include "vm/code_descriptors.h" | 
|   15 #include "vm/code_generator.h" |   15 #include "vm/code_generator.h" | 
|   16 #include "vm/flow_graph_compiler_shared.h" |  | 
|   17 #include "vm/intermediate_language.h" |   16 #include "vm/intermediate_language.h" | 
|   18  |   17  | 
|   19 namespace dart { |   18 namespace dart { | 
|   20  |   19  | 
|   21 class AbstractType; |   20 class AbstractType; | 
|   22 class Assembler; |   21 class Assembler; | 
|   23 class Code; |   22 class Code; | 
|   24 class DeoptimizationStub; |   23 class DeoptimizationStub; | 
|   25 template <typename T> class GrowableArray; |   24 template <typename T> class GrowableArray; | 
|   26 class ParsedFunction; |   25 class ParsedFunction; | 
|   27 class StackMapBuilder; |   26 class StackMapBuilder; | 
|   28  |   27  | 
|   29 // Stubbed out implementation of graph compiler, bails out immediately if |   28 // Stubbed out implementation of graph compiler, bails out immediately if | 
|   30 // CompileGraph is called. The rest of the public API is UNIMPLEMENTED. |   29 // CompileGraph is called. The rest of the public API is UNIMPLEMENTED. | 
|   31 class FlowGraphCompiler : public FlowGraphCompilerShared { |   30 class FlowGraphCompiler : public ValueObject { | 
 |   31  private: | 
 |   32   struct BlockInfo : public ZoneAllocated { | 
 |   33    public: | 
 |   34     BlockInfo() : label() { } | 
 |   35     Label label; | 
 |   36   }; | 
 |   37  | 
|   32  public: |   38  public: | 
|   33   FlowGraphCompiler(Assembler* assembler, |   39   FlowGraphCompiler(Assembler* assembler, | 
|   34                     const ParsedFunction& parsed_function, |   40                     const ParsedFunction& parsed_function, | 
|   35                     const GrowableArray<BlockEntryInstr*>& block_order, |   41                     const GrowableArray<BlockEntryInstr*>& block_order, | 
|   36                     bool is_optimizing); |   42                     bool is_optimizing); | 
|   37  |   43  | 
 |   44   virtual ~FlowGraphCompiler(); | 
 |   45  | 
 |   46   // Accessors. | 
 |   47   Assembler* assembler() const { return assembler_; } | 
 |   48   const ParsedFunction& parsed_function() const { return parsed_function_; } | 
 |   49   const GrowableArray<BlockEntryInstr*>& block_order() const { | 
 |   50     return block_order_; | 
 |   51   } | 
 |   52   DescriptorList* pc_descriptors_list() const { | 
 |   53     return pc_descriptors_list_; | 
 |   54   } | 
 |   55   BlockEntryInstr* current_block() const { return current_block_; } | 
 |   56   void set_current_block(BlockEntryInstr* value) { | 
 |   57     current_block_ = value; | 
 |   58   } | 
 |   59   bool is_optimizing() const { return is_optimizing_; } | 
 |   60   const GrowableArray<BlockInfo*>& block_info() const { return block_info_; } | 
 |   61  | 
 |   62   // Constructor is lighweight, major initialization work should occur here. | 
 |   63   // This makes it easier to measure time spent in the compiler. | 
 |   64   void InitCompiler(); | 
 |   65  | 
|   38   void CompileGraph(); |   66   void CompileGraph(); | 
|   39  |   67  | 
|   40   void GenerateCallRuntime(intptr_t cid, |   68   void VisitBlocks(); | 
|   41                            intptr_t token_index, |  | 
|   42                            intptr_t try_index, |  | 
|   43                            const RuntimeEntry& entry); |  | 
|   44  |   69  | 
|   45   // Returns pc-offset (in bytes) of the pc after the call, can be used to emit |   70   // Bail out of the flow graph compiler. Does not return to the caller. | 
|   46   // pc-descriptor information. |   71   void Bailout(const char* reason); | 
|   47   virtual intptr_t EmitInstanceCall(ExternalLabel* target_label, |   72  | 
|   48                                     const ICData& ic_data, |   73   // Returns 'true' if code generation for this function is complete, i.e., | 
|   49                                     const Array& arguments_descriptor, |   74   // no fall-through to regular code is needed. | 
|   50                                     intptr_t argument_count); |   75   bool TryIntrinsify(); | 
 |   76  | 
 |   77   virtual void GenerateCallRuntime(intptr_t cid, | 
 |   78                                    intptr_t token_index, | 
 |   79                                    intptr_t try_index, | 
 |   80                                    const RuntimeEntry& entry); | 
|   51  |   81  | 
|   52   // Returns pc-offset (in bytes) of the pc after the call, can be used to emit |   82   // Returns pc-offset (in bytes) of the pc after the call, can be used to emit | 
|   53   // pc-descriptor information. |   83   // pc-descriptor information. | 
|   54   virtual intptr_t EmitStaticCall(const Function& function, |   84   virtual intptr_t EmitStaticCall(const Function& function, | 
|   55                                   const Array& arguments_descriptor, |   85                                   const Array& arguments_descriptor, | 
|   56                                   intptr_t argument_count); |   86                                   intptr_t argument_count); | 
|   57  |   87  | 
|   58   void GenerateCall(intptr_t token_index, |   88   virtual void GenerateCall(intptr_t token_index, | 
|   59                     intptr_t try_index, |   89                             intptr_t try_index, | 
|   60                     const ExternalLabel* label, |   90                             const ExternalLabel* label, | 
|   61                     PcDescriptors::Kind kind); |   91                             PcDescriptors::Kind kind); | 
|   62   void GenerateInstanceOf(intptr_t cid, |   92   virtual void GenerateInstanceOf(intptr_t cid, | 
 |   93                                   intptr_t token_index, | 
 |   94                                   intptr_t try_index, | 
 |   95                                   const AbstractType& type, | 
 |   96                                   bool negate_result); | 
 |   97   virtual void GenerateAssertAssignable(intptr_t cid, | 
 |   98                                         intptr_t token_index, | 
 |   99                                         intptr_t try_index, | 
 |  100                                         const AbstractType& dst_type, | 
 |  101                                         const String& dst_name); | 
 |  102  | 
 |  103   void GenerateInstanceCall(intptr_t cid, | 
 |  104                             intptr_t token_index, | 
 |  105                             intptr_t try_index, | 
 |  106                             const String& function_name, | 
 |  107                             intptr_t argument_count, | 
 |  108                             const Array& argument_names, | 
 |  109                             intptr_t checked_argument_count); | 
 |  110  | 
 |  111   void GenerateStaticCall(intptr_t cid, | 
|   63                           intptr_t token_index, |  112                           intptr_t token_index, | 
|   64                           intptr_t try_index, |  113                           intptr_t try_index, | 
|   65                           const AbstractType& type, |  114                           const Function& function, | 
|   66                           bool negate_result); |  115                           intptr_t argument_count, | 
|   67   void GenerateAssertAssignable(intptr_t cid, |  116                           const Array& argument_names); | 
|   68                                 intptr_t token_index, |  117  | 
|   69                                 intptr_t try_index, |  118   void GenerateNumberTypeCheck(Register kClassIdReg, | 
|   70                                 const AbstractType& dst_type, |  119                                const AbstractType& type, | 
|   71                                 const String& dst_name); |  120                                Label* is_instance_lbl, | 
 |  121                                Label* is_not_instance_lbl); | 
 |  122   void GenerateStringTypeCheck(Register kClassIdReg, | 
 |  123                                Label* is_instance_lbl, | 
 |  124                                Label* is_not_instance_lbl); | 
 |  125   void GenerateListTypeCheck(Register kClassIdReg, | 
 |  126                              Label* is_instance_lbl); | 
 |  127  | 
 |  128   // Returns pc-offset (in bytes) of the pc after the call, can be used to emit | 
 |  129   // pc-descriptor information. | 
 |  130   intptr_t EmitInstanceCall(ExternalLabel* target_label, | 
 |  131                             const ICData& ic_data, | 
 |  132                             const Array& arguments_descriptor, | 
 |  133                             intptr_t argument_count); | 
 |  134  | 
 |  135   void EmitComment(Instruction* instr); | 
 |  136  | 
 |  137   intptr_t StackSize() const; | 
 |  138  | 
 |  139   // Returns assembler label associated with the given block entry. | 
 |  140   Label* GetBlockLabel(BlockEntryInstr* block_entry) const; | 
 |  141  | 
 |  142   // Returns true if the next block after current in the current block order | 
 |  143   // is the given block. | 
 |  144   bool IsNextBlock(TargetEntryInstr* block_entry) const; | 
 |  145  | 
 |  146   void AddExceptionHandler(intptr_t try_index, intptr_t pc_offset); | 
 |  147   void AddCurrentDescriptor(PcDescriptors::Kind kind, | 
 |  148                             intptr_t cid, | 
 |  149                             intptr_t token_index, | 
 |  150                             intptr_t try_index); | 
 |  151   Label* AddDeoptStub(intptr_t deopt_id, | 
 |  152                       intptr_t deopt_token_index, | 
 |  153                       intptr_t try_index_, | 
 |  154                       DeoptReasonId reason, | 
 |  155                       Register reg1, | 
 |  156                       Register reg2); | 
 |  157  | 
 |  158   void FinalizeExceptionHandlers(const Code& code); | 
 |  159   void FinalizePcDescriptors(const Code& code); | 
 |  160   void FinalizeStackmaps(const Code& code); | 
 |  161   void FinalizeVarDescriptors(const Code& code); | 
 |  162   void FinalizeComments(const Code& code); | 
 |  163  | 
 |  164   static const int kLocalsOffsetFromFP = (-1 * kWordSize); | 
|   72  |  165  | 
|   73  private: |  166  private: | 
|   74   friend class DeoptimizationStub; |  167   friend class DeoptimizationStub; | 
|   75  |  168  | 
|   76   virtual void VisitBlocks(); |  169   void GenerateDeferredCode(); | 
|   77  |  170  | 
|   78   void CopyParameters(); |  171   void CopyParameters(); | 
|   79   void EmitInstructionPrologue(Instruction* instr); |  172   virtual void EmitInstructionPrologue(Instruction* instr); | 
|   80  |  173  | 
|   81   virtual void GenerateInlinedGetter(intptr_t offset); |  174   virtual void GenerateInlinedGetter(intptr_t offset); | 
|   82   virtual void GenerateInlinedSetter(intptr_t offset); |  175   virtual void GenerateInlinedSetter(intptr_t offset); | 
|   83  |  176  | 
|   84   RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, |  177   RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, | 
|   85                                                 intptr_t token_index, |  178                                                 intptr_t token_index, | 
|   86                                                 const AbstractType& type, |  179                                                 const AbstractType& type, | 
|   87                                                 Label* is_instance_lbl, |  180                                                 Label* is_instance_lbl, | 
|   88                                                 Label* is_not_instance_lbl); |  181                                                 Label* is_not_instance_lbl); | 
|   89  |  182  | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  127                                                    Label* is_instance_lbl, |  220                                                    Label* is_instance_lbl, | 
|  128                                                    Label* is_not_instance_lbl); |  221                                                    Label* is_not_instance_lbl); | 
|  129  |  222  | 
|  130   void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); |  223   void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); | 
|  131  |  224  | 
|  132   virtual void CheckClassIds(Register class_id_reg, |  225   virtual void CheckClassIds(Register class_id_reg, | 
|  133                              const GrowableArray<intptr_t>& class_ids, |  226                              const GrowableArray<intptr_t>& class_ids, | 
|  134                              Label* is_equal_lbl, |  227                              Label* is_equal_lbl, | 
|  135                              Label* is_not_equal_lbl); |  228                              Label* is_not_equal_lbl); | 
|  136  |  229  | 
|  137   void EmitComment(Instruction* instr); |  230  | 
|  138   void BailoutOnInstruction(Instruction* instr); |  231   // Map a block number in a forward iteration into the block number in the | 
 |  232   // corresponding reverse iteration.  Used to obtain an index into | 
 |  233   // block_order for reverse iterations. | 
 |  234   intptr_t reverse_index(intptr_t index) const { | 
 |  235     return block_order_.length() - index - 1; | 
 |  236   } | 
 |  237  | 
 |  238   class Assembler* assembler_; | 
 |  239   const ParsedFunction& parsed_function_; | 
 |  240   const GrowableArray<BlockEntryInstr*>& block_order_; | 
 |  241  | 
 |  242   // Compiler specific per-block state.  Indexed by postorder block number | 
 |  243   // for convenience.  This is not the block's index in the block order, | 
 |  244   // which is reverse postorder. | 
 |  245   BlockEntryInstr* current_block_; | 
 |  246   ExceptionHandlerList* exception_handlers_list_; | 
 |  247   DescriptorList* pc_descriptors_list_; | 
 |  248   StackmapBuilder* stackmap_builder_; | 
 |  249   GrowableArray<BlockInfo*> block_info_; | 
 |  250   GrowableArray<DeoptimizationStub*> deopt_stubs_; | 
 |  251   const bool is_optimizing_; | 
|  139  |  252  | 
|  140   DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |  253   DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 
|  141 }; |  254 }; | 
|  142  |  255  | 
 |  256  | 
 |  257 class DeoptimizationStub : public ZoneAllocated { | 
 |  258  public: | 
 |  259   DeoptimizationStub(intptr_t deopt_id, | 
 |  260                      intptr_t deopt_token_index, | 
 |  261                      intptr_t try_index, | 
 |  262                      DeoptReasonId reason) | 
 |  263       : deopt_id_(deopt_id), | 
 |  264         deopt_token_index_(deopt_token_index), | 
 |  265         try_index_(try_index), | 
 |  266         reason_(reason), | 
 |  267         registers_(2), | 
 |  268         entry_label_() {} | 
 |  269  | 
 |  270   void Push(Register reg) { registers_.Add(reg); } | 
 |  271   Label* entry_label() { return &entry_label_; } | 
 |  272  | 
 |  273   // Implementation is in architecture specific file. | 
 |  274   void GenerateCode(FlowGraphCompiler* compiler); | 
 |  275  | 
 |  276  private: | 
 |  277   const intptr_t deopt_id_; | 
 |  278   const intptr_t deopt_token_index_; | 
 |  279   const intptr_t try_index_; | 
 |  280   const DeoptReasonId reason_; | 
 |  281   GrowableArray<Register> registers_; | 
 |  282   Label entry_label_; | 
 |  283  | 
 |  284   DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); | 
 |  285 }; | 
 |  286  | 
 |  287  | 
|  143 }  // namespace dart |  288 }  // namespace dart | 
|  144  |  289  | 
|  145 #endif  // VM_FLOW_GRAPH_COMPILER_IA32_H_ |  290 #endif  // VM_FLOW_GRAPH_COMPILER_IA32_H_ | 
| OLD | NEW |