| 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_CODE_GENERATOR_X64_H_ | 5 #ifndef VM_CODE_GENERATOR_X64_H_ |
| 6 #define VM_CODE_GENERATOR_X64_H_ | 6 #define VM_CODE_GENERATOR_X64_H_ |
| 7 | 7 |
| 8 #ifndef VM_CODE_GENERATOR_H_ | 8 #ifndef VM_CODE_GENERATOR_H_ |
| 9 #error Do not include code_generator_x64.h directly; use code_generator.h. | 9 #error Do not include code_generator_x64.h directly; use code_generator.h. |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "vm/assembler.h" | |
| 13 #include "vm/ast.h" | 12 #include "vm/ast.h" |
| 14 #include "vm/growable_array.h" | 13 #include "vm/growable_array.h" |
| 15 #include "vm/parser.h" | |
| 16 | 14 |
| 17 namespace dart { | 15 namespace dart { |
| 18 | 16 |
| 19 // Forward declarations. | 17 // Forward declarations. |
| 20 class Assembler; | 18 class Assembler; |
| 21 class AstNode; | 19 class AstNode; |
| 22 class CodeGenerator; | 20 class ParsedFunction; |
| 23 class DescriptorList; | |
| 24 class ExceptionHandlerList; | |
| 25 class SourceLabel; | |
| 26 class StackmapBuilder; | |
| 27 | |
| 28 | |
| 29 class CodeGeneratorState : public StackResource { | |
| 30 public: | |
| 31 explicit CodeGeneratorState(CodeGenerator* codegen); | |
| 32 virtual ~CodeGeneratorState(); | |
| 33 | |
| 34 CodeGeneratorState* parent() const { return parent_; } | |
| 35 | |
| 36 AstNode* root_node() const { return root_node_; } | |
| 37 void set_root_node(AstNode* value) { root_node_ = value; } | |
| 38 bool IsRootNode(AstNode* node) const { | |
| 39 return root_node_ == node; | |
| 40 } | |
| 41 | |
| 42 int try_index() const { return current_try_index_; } | |
| 43 void set_try_index(int value) { | |
| 44 current_try_index_ = value; | |
| 45 } | |
| 46 | |
| 47 private: | |
| 48 CodeGenerator* codegen_; | |
| 49 CodeGeneratorState* parent_; | |
| 50 AstNode* root_node_; | |
| 51 | |
| 52 // We identify each try block in this function with an unique 'try index' | |
| 53 // value. | |
| 54 // The 'try index' is used to match the try blocks with the corresponding | |
| 55 // catch block (if one exists). The PC descriptors generated for | |
| 56 // statements in the try block use this index so that it can be matched | |
| 57 // to the appropriate catch block. | |
| 58 // The 'try index' value is generated by incrementing the try_index_ | |
| 59 // variable in the CodeGenerator object. | |
| 60 // We store the 'try index' of the block of code that we are | |
| 61 // currently generating code for in the current_try_index_ variable. | |
| 62 int current_try_index_; | |
| 63 | |
| 64 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGeneratorState); | |
| 65 }; | |
| 66 | |
| 67 | 21 |
| 68 class CodeGenerator : public AstNodeVisitor { | 22 class CodeGenerator : public AstNodeVisitor { |
| 69 public: | 23 public: |
| 70 CodeGenerator(Assembler* assembler, const ParsedFunction& parsed_function); | 24 CodeGenerator(Assembler* assembler, const ParsedFunction& parsed_function) |
| 25 : pc_descriptors_list_(NULL) { } |
| 71 virtual ~CodeGenerator() { } | 26 virtual ~CodeGenerator() { } |
| 72 | 27 |
| 73 // Accessors. | 28 bool GenerateCode() { |
| 74 Assembler* assembler() const { return assembler_; } | 29 return false; |
| 75 | 30 } |
| 76 const ParsedFunction& parsed_function() const { return parsed_function_; } | |
| 77 | |
| 78 void GenerateCode(); | |
| 79 virtual void GenerateDeferredCode(); | |
| 80 | |
| 81 #define DEFINE_VISITOR_FUNCTION(type, name) \ | |
| 82 virtual void Visit##type(type* node); | |
| 83 NODE_LIST(DEFINE_VISITOR_FUNCTION) | |
| 84 #undef DEFINE_VISITOR_FUNCTION | |
| 85 | |
| 86 CodeGeneratorState* state() const { return state_; } | |
| 87 void set_state(CodeGeneratorState* state) { state_ = state; } | |
| 88 | 31 |
| 89 // Add exception handler table to code. | 32 // Add exception handler table to code. |
| 90 void FinalizeExceptionHandlers(const Code& code); | 33 void FinalizeExceptionHandlers(const Code& code) { UNIMPLEMENTED(); } |
| 91 | 34 |
| 92 // Add pc descriptors to code. | 35 // Add pc descriptors to code. |
| 93 void FinalizePcDescriptors(const Code& code); | 36 void FinalizePcDescriptors(const Code& code) { UNIMPLEMENTED(); } |
| 94 | 37 |
| 95 // Add stack maps to code. | 38 // Add stack maps to code. |
| 96 void FinalizeStackmaps(const Code& code); | 39 void FinalizeStackmaps(const Code& code) { UNIMPLEMENTED(); } |
| 97 | 40 |
| 98 // Add local variable descriptors to code. | 41 // Add local variable descriptors to code. |
| 99 void FinalizeVarDescriptors(const Code& code); | 42 void FinalizeVarDescriptors(const Code& code) { UNIMPLEMENTED(); } |
| 100 | 43 |
| 101 // Allocate and return an arguments descriptor. | 44 // Allocate and return an arguments descriptor. |
| 102 // Let 'num_names' be the length of 'optional_arguments_names'. | 45 // Let 'num_names' be the length of 'optional_arguments_names'. |
| 103 // Treat the first 'num_arguments - num_names' arguments as positional and | 46 // Treat the first 'num_arguments - num_names' arguments as positional and |
| 104 // treat the following 'num_names' arguments as named optional arguments. | 47 // treat the following 'num_names' arguments as named optional arguments. |
| 105 static const Array& ArgumentsDescriptor( | 48 static const Array& ArgumentsDescriptor( |
| 106 int num_arguments, | 49 int num_arguments, |
| 107 const Array& optional_arguments_names); | 50 const Array& optional_arguments_names); |
| 108 | 51 |
| 109 virtual bool IsOptimizing() const { | |
| 110 return false; | |
| 111 } | |
| 112 | |
| 113 void GenerateReturnEpilog(ReturnNode* node); | |
| 114 | |
| 115 // Return true if the VM may optimize functions. | 52 // Return true if the VM may optimize functions. |
| 116 static bool CanOptimize(); | 53 static bool CanOptimize(); |
| 117 | 54 |
| 118 private: | 55 private: |
| 119 // TODO(srdjan): Remove the friendship once the two compilers are properly | 56 // Forward declarations. |
| 120 // structured. | 57 class DescriptorList; |
| 121 friend class OptimizingCodeGenerator; | |
| 122 | 58 |
| 123 // Return true if intrinsification was completed and no other code | |
| 124 // needs to be generated. | |
| 125 virtual bool TryIntrinsify() { return false; } | |
| 126 virtual void GeneratePreEntryCode(); | |
| 127 void GenerateLegacyEntryCode(); | |
| 128 void GenerateEntryCode(); | |
| 129 void GenerateLoadVariable(Register dst, const LocalVariable& local); | |
| 130 void GeneratePushVariable(const LocalVariable& variable, Register scratch); | |
| 131 void GenerateStoreVariable(const LocalVariable& local, | |
| 132 Register src, | |
| 133 Register scratch); | |
| 134 void GenerateLogicalNotOp(UnaryOpNode* node); | |
| 135 void GenerateLogicalAndOrOp(BinaryOpNode* node); | |
| 136 void GenerateInstanceGetterCall(intptr_t node_id, | |
| 137 intptr_t token_index, | |
| 138 const String& field_name); | |
| 139 void GenerateInstanceSetterCall(intptr_t node_id, | |
| 140 intptr_t token_index, | |
| 141 const String& field_name); | |
| 142 void GenerateBinaryOperatorCall(intptr_t node_id, | |
| 143 intptr_t token_index, | |
| 144 const char* operator_name); | |
| 145 void GenerateStaticGetterCall(intptr_t token_index, | |
| 146 const Class& field_class, | |
| 147 const String& field_name); | |
| 148 void GenerateStaticSetterCall(intptr_t token_index, | |
| 149 const Class& field_class, | |
| 150 const String& field_name); | |
| 151 void GenerateLoadIndexed(intptr_t node_id, intptr_t token_index); | |
| 152 void GenerateStoreIndexed(intptr_t node_id, | |
| 153 intptr_t token_index, | |
| 154 bool preserve_value); | |
| 155 | |
| 156 // Invokes funtion via an inline cache stub. 'num_args_checked' specifies | |
| 157 // the number of call arguments that are being checked in the inline cache. | |
| 158 void GenerateInstanceCall(intptr_t node_id, | |
| 159 intptr_t token_index, | |
| 160 const String& function_name, | |
| 161 int num_arguments, | |
| 162 const Array& optional_arguments_names, | |
| 163 intptr_t num_args_checked); | |
| 164 | |
| 165 void GenerateInstanceOf(intptr_t node_id, | |
| 166 intptr_t token_index, | |
| 167 AstNode* value, | |
| 168 const AbstractType& type, | |
| 169 bool negate_result); | |
| 170 void GenerateAssertAssignable(intptr_t node_id, | |
| 171 intptr_t token_index, | |
| 172 AstNode* value, | |
| 173 const AbstractType& dst_type, | |
| 174 const String& dst_name); | |
| 175 void GenerateArgumentTypeChecks(); | |
| 176 void GenerateConditionTypeCheck(intptr_t node_id, intptr_t token_index); | |
| 177 | |
| 178 void GenerateInstantiatorTypeArguments(intptr_t token_index); | |
| 179 void GenerateTypeArguments(intptr_t node_id, | |
| 180 intptr_t token_index, | |
| 181 const AbstractTypeArguments& type_arguments, | |
| 182 bool instantiate_type_arguments); | |
| 183 | |
| 184 void TestClassAndJump(const Class& cls, Label *label); | |
| 185 | |
| 186 intptr_t locals_space_size() const { return locals_space_size_; } | |
| 187 void set_locals_space_size(intptr_t value) { locals_space_size_ = value; } | |
| 188 | |
| 189 bool IsResultNeeded(AstNode* node) const; | |
| 190 | |
| 191 void GenerateCall(intptr_t token_index, | |
| 192 const ExternalLabel* ext_label, | |
| 193 PcDescriptors::Kind desc_kind); | |
| 194 void GenerateCallRuntime(intptr_t node_id, | |
| 195 intptr_t token_index, | |
| 196 const RuntimeEntry& entry); | |
| 197 | |
| 198 void GenerateInlinedFinallyBlocks(SourceLabel* label); | |
| 199 | |
| 200 void HandleBackwardBranch(intptr_t loop_id, intptr_t token_index); | |
| 201 | |
| 202 void ErrorMsg(intptr_t token_index, const char* format, ...); | |
| 203 | |
| 204 int generate_next_try_index() { return try_index_ += 1; } | |
| 205 | |
| 206 void MarkDeoptPoint(intptr_t node_id, intptr_t token_index); | |
| 207 void AddCurrentDescriptor(PcDescriptors::Kind kind, | |
| 208 intptr_t node_id, | |
| 209 intptr_t token_index); | |
| 210 void CopyParameters(); | |
| 211 | |
| 212 void set_context_level(intptr_t value) { context_level_ = value; } | |
| 213 intptr_t context_level() const { return context_level_; } | |
| 214 | |
| 215 Assembler* assembler_; | |
| 216 const ParsedFunction& parsed_function_; | |
| 217 intptr_t locals_space_size_; | |
| 218 CodeGeneratorState* state_; | |
| 219 DescriptorList* pc_descriptors_list_; | 59 DescriptorList* pc_descriptors_list_; |
| 220 StackmapBuilder* stackmap_builder_; | |
| 221 ExceptionHandlerList* exception_handlers_list_; | |
| 222 int try_index_; | |
| 223 // The runtime context level is only incremented when a new context is | |
| 224 // allocated and chained to the list of contexts. | |
| 225 intptr_t context_level_; | |
| 226 | |
| 227 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGenerator); | 60 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGenerator); |
| 228 }; | 61 }; |
| 229 | 62 |
| 230 | 63 |
| 231 } // namespace dart | 64 } // namespace dart |
| 232 | 65 |
| 233 #endif // VM_CODE_GENERATOR_X64_H_ | 66 #endif // VM_CODE_GENERATOR_X64_H_ |
| OLD | NEW |