| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
| 6 #define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
| 7 | 7 |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/compiler/bytecode-branch-analysis.h" | 9 #include "src/compiler/bytecode-branch-analysis.h" |
| 10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 public: | 21 public: |
| 22 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, | 22 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, |
| 23 JSGraph* jsgraph); | 23 JSGraph* jsgraph); |
| 24 | 24 |
| 25 // Creates a graph by visiting bytecodes. | 25 // Creates a graph by visiting bytecodes. |
| 26 bool CreateGraph(bool stack_check = true); | 26 bool CreateGraph(bool stack_check = true); |
| 27 | 27 |
| 28 Graph* graph() const { return jsgraph_->graph(); } | 28 Graph* graph() const { return jsgraph_->graph(); } |
| 29 | 29 |
| 30 private: | 30 private: |
| 31 enum class AccumulatorUpdateMode { |
| 32 kOutputIgnored, |
| 33 kOutputInAccumulator, |
| 34 }; |
| 35 |
| 31 class Environment; | 36 class Environment; |
| 37 class FrameStateBeforeAndAfter; |
| 32 | 38 |
| 33 void CreateGraphBody(bool stack_check); | 39 void CreateGraphBody(bool stack_check); |
| 34 void VisitBytecodes(); | 40 void VisitBytecodes(); |
| 35 | 41 |
| 36 Node* LoadAccumulator(Node* value); | 42 Node* LoadAccumulator(Node* value); |
| 37 | 43 |
| 38 // Get or create the node that represents the outer function closure. | 44 // Get or create the node that represents the outer function closure. |
| 39 Node* GetFunctionClosure(); | 45 Node* GetFunctionClosure(); |
| 40 | 46 |
| 41 // Get or create the node that represents the outer function context. | 47 // Get or create the node that represents the outer function context. |
| 42 Node* GetFunctionContext(); | 48 Node* GetFunctionContext(); |
| 43 | 49 |
| 44 // Get or create the node that represents the incoming new target value. | 50 // Get or create the node that represents the incoming new target value. |
| 45 Node* GetNewTarget(); | 51 Node* GetNewTarget(); |
| 46 | 52 |
| 47 // Builder for accessing a (potentially immutable) object field. | 53 // Builder for accessing a (potentially immutable) object field. |
| 48 Node* BuildLoadObjectField(Node* object, int offset); | 54 Node* BuildLoadObjectField(Node* object, int offset); |
| 49 Node* BuildLoadImmutableObjectField(Node* object, int offset); | 55 Node* BuildLoadImmutableObjectField(Node* object, int offset); |
| 50 | 56 |
| 51 // Builder for accessing type feedback vector. | 57 // Builder for accessing type feedback vector. |
| 52 Node* BuildLoadFeedbackVector(); | 58 Node* BuildLoadFeedbackVector(); |
| 53 | 59 |
| 54 // Builder for loading the a native context field. | 60 // Builder for loading the a native context field. |
| 55 Node* BuildLoadNativeContextField(int index); | 61 Node* BuildLoadNativeContextField(int index); |
| 56 | 62 |
| 57 // Helper function for creating a pair containing type feedback vector and | 63 // Helper function for creating a pair containing type feedback vector and |
| 58 // a feedback slot. | 64 // a feedback slot. |
| 59 VectorSlotPair CreateVectorSlotPair(int slot_id); | 65 VectorSlotPair CreateVectorSlotPair(int slot_id); |
| 60 | 66 |
| 61 // Replaces the frame state inputs with empty frame states. | |
| 62 void AddEmptyFrameStateInputs(Node* node); | |
| 63 | |
| 64 void set_environment(Environment* env) { environment_ = env; } | 67 void set_environment(Environment* env) { environment_ = env; } |
| 65 const Environment* environment() const { return environment_; } | 68 const Environment* environment() const { return environment_; } |
| 66 Environment* environment() { return environment_; } | 69 Environment* environment() { return environment_; } |
| 67 | 70 |
| 68 // Node creation helpers | 71 // Node creation helpers |
| 69 Node* NewNode(const Operator* op, bool incomplete = false) { | 72 Node* NewNode(const Operator* op, bool incomplete = false) { |
| 70 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); | 73 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); |
| 71 } | 74 } |
| 72 | 75 |
| 73 Node* NewNode(const Operator* op, Node* n1) { | 76 Node* NewNode(const Operator* op, Node* n1) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 123 |
| 121 Node* ProcessCallArguments(const Operator* call_op, Node* callee, | 124 Node* ProcessCallArguments(const Operator* call_op, Node* callee, |
| 122 interpreter::Register receiver, size_t arity); | 125 interpreter::Register receiver, size_t arity); |
| 123 Node* ProcessCallNewArguments(const Operator* call_new_op, | 126 Node* ProcessCallNewArguments(const Operator* call_new_op, |
| 124 interpreter::Register callee, | 127 interpreter::Register callee, |
| 125 interpreter::Register first_arg, size_t arity); | 128 interpreter::Register first_arg, size_t arity); |
| 126 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, | 129 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, |
| 127 interpreter::Register first_arg, | 130 interpreter::Register first_arg, |
| 128 size_t arity); | 131 size_t arity); |
| 129 | 132 |
| 130 void BuildCreateLiteral(const Operator* op); | 133 void BuildCreateLiteral(const Operator* op, |
| 134 const interpreter::BytecodeArrayIterator& iterator); |
| 131 void BuildCreateRegExpLiteral( | 135 void BuildCreateRegExpLiteral( |
| 132 const interpreter::BytecodeArrayIterator& iterator); | 136 const interpreter::BytecodeArrayIterator& iterator); |
| 133 void BuildCreateArrayLiteral( | 137 void BuildCreateArrayLiteral( |
| 134 const interpreter::BytecodeArrayIterator& iterator); | 138 const interpreter::BytecodeArrayIterator& iterator); |
| 135 void BuildCreateObjectLiteral( | 139 void BuildCreateObjectLiteral( |
| 136 const interpreter::BytecodeArrayIterator& iterator); | 140 const interpreter::BytecodeArrayIterator& iterator); |
| 137 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, | 141 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, |
| 138 TypeofMode typeof_mode); | 142 TypeofMode typeof_mode); |
| 139 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); | 143 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); |
| 140 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator); | 144 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 // Field accessors | 176 // Field accessors |
| 173 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 177 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
| 174 Zone* graph_zone() const { return graph()->zone(); } | 178 Zone* graph_zone() const { return graph()->zone(); } |
| 175 CompilationInfo* info() const { return info_; } | 179 CompilationInfo* info() const { return info_; } |
| 176 JSGraph* jsgraph() const { return jsgraph_; } | 180 JSGraph* jsgraph() const { return jsgraph_; } |
| 177 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } | 181 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } |
| 178 Zone* local_zone() const { return local_zone_; } | 182 Zone* local_zone() const { return local_zone_; } |
| 179 const Handle<BytecodeArray>& bytecode_array() const { | 183 const Handle<BytecodeArray>& bytecode_array() const { |
| 180 return bytecode_array_; | 184 return bytecode_array_; |
| 181 } | 185 } |
| 186 const FrameStateFunctionInfo* frame_state_function_info() const { |
| 187 return frame_state_function_info_; |
| 188 } |
| 182 | 189 |
| 183 LanguageMode language_mode() const { | 190 LanguageMode language_mode() const { |
| 184 // TODO(mythria): Don't rely on parse information to get language mode. | 191 // TODO(mythria): Don't rely on parse information to get language mode. |
| 185 return info()->language_mode(); | 192 return info()->language_mode(); |
| 186 } | 193 } |
| 187 | 194 |
| 188 const interpreter::BytecodeArrayIterator* bytecode_iterator() const { | 195 const interpreter::BytecodeArrayIterator* bytecode_iterator() const { |
| 189 return bytecode_iterator_; | 196 return bytecode_iterator_; |
| 190 } | 197 } |
| 191 | 198 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 204 | 211 |
| 205 #define DECLARE_VISIT_BYTECODE(name, ...) \ | 212 #define DECLARE_VISIT_BYTECODE(name, ...) \ |
| 206 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); | 213 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); |
| 207 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) | 214 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) |
| 208 #undef DECLARE_VISIT_BYTECODE | 215 #undef DECLARE_VISIT_BYTECODE |
| 209 | 216 |
| 210 Zone* local_zone_; | 217 Zone* local_zone_; |
| 211 CompilationInfo* info_; | 218 CompilationInfo* info_; |
| 212 JSGraph* jsgraph_; | 219 JSGraph* jsgraph_; |
| 213 Handle<BytecodeArray> bytecode_array_; | 220 Handle<BytecodeArray> bytecode_array_; |
| 221 const FrameStateFunctionInfo* frame_state_function_info_; |
| 214 const interpreter::BytecodeArrayIterator* bytecode_iterator_; | 222 const interpreter::BytecodeArrayIterator* bytecode_iterator_; |
| 215 const BytecodeBranchAnalysis* branch_analysis_; | 223 const BytecodeBranchAnalysis* branch_analysis_; |
| 216 Environment* environment_; | 224 Environment* environment_; |
| 217 | 225 |
| 226 |
| 218 // Merge environments are snapshots of the environment at a particular | 227 // Merge environments are snapshots of the environment at a particular |
| 219 // bytecode offset to be merged into a later environment. | 228 // bytecode offset to be merged into a later environment. |
| 220 ZoneMap<int, Environment*> merge_environments_; | 229 ZoneMap<int, Environment*> merge_environments_; |
| 221 | 230 |
| 222 // Loop header environments are environments created for bytecodes | 231 // Loop header environments are environments created for bytecodes |
| 223 // where it is known there are back branches, ie a loop header. | 232 // where it is known there are back branches, ie a loop header. |
| 224 ZoneMap<int, Environment*> loop_header_environments_; | 233 ZoneMap<int, Environment*> loop_header_environments_; |
| 225 | 234 |
| 226 // Temporary storage for building node input lists. | 235 // Temporary storage for building node input lists. |
| 227 int input_buffer_size_; | 236 int input_buffer_size_; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 246 public: | 255 public: |
| 247 Environment(BytecodeGraphBuilder* builder, int register_count, | 256 Environment(BytecodeGraphBuilder* builder, int register_count, |
| 248 int parameter_count, Node* control_dependency, Node* context); | 257 int parameter_count, Node* control_dependency, Node* context); |
| 249 | 258 |
| 250 int parameter_count() const { return parameter_count_; } | 259 int parameter_count() const { return parameter_count_; } |
| 251 int register_count() const { return register_count_; } | 260 int register_count() const { return register_count_; } |
| 252 | 261 |
| 253 void BindRegister(interpreter::Register the_register, Node* node); | 262 void BindRegister(interpreter::Register the_register, Node* node); |
| 254 Node* LookupRegister(interpreter::Register the_register) const; | 263 Node* LookupRegister(interpreter::Register the_register) const; |
| 255 | 264 |
| 256 void BindAccumulator(Node* node); | 265 void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr); |
| 257 Node* LookupAccumulator() const; | 266 Node* LookupAccumulator() const; |
| 258 | 267 |
| 268 void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states); |
| 269 |
| 259 bool IsMarkedAsUnreachable() const; | 270 bool IsMarkedAsUnreachable() const; |
| 260 void MarkAsUnreachable(); | 271 void MarkAsUnreachable(); |
| 261 | 272 |
| 262 // Effect dependency tracked by this environment. | 273 // Effect dependency tracked by this environment. |
| 263 Node* GetEffectDependency() { return effect_dependency_; } | 274 Node* GetEffectDependency() { return effect_dependency_; } |
| 264 void UpdateEffectDependency(Node* dependency) { | 275 void UpdateEffectDependency(Node* dependency) { |
| 265 effect_dependency_ = dependency; | 276 effect_dependency_ = dependency; |
| 266 } | 277 } |
| 267 | 278 |
| 279 // Preserve a checkpoint of the environment for the IR graph. Any |
| 280 // further mutation of the environment will not affect checkpoints. |
| 281 Node* Checkpoint(BailoutId ast_id, AccumulatorUpdateMode update_mode); |
| 282 |
| 283 // Returns true if the state values are up to date with the current |
| 284 // environment. If update_mode is AccumulatorUpdateMode::kOutputInAccumulator |
| 285 // then accumulator state can be different from the environment. |
| 286 bool StateValuesAreUpToDate(AccumulatorUpdateMode update_mode); |
| 287 |
| 268 // Control dependency tracked by this environment. | 288 // Control dependency tracked by this environment. |
| 269 Node* GetControlDependency() const { return control_dependency_; } | 289 Node* GetControlDependency() const { return control_dependency_; } |
| 270 void UpdateControlDependency(Node* dependency) { | 290 void UpdateControlDependency(Node* dependency) { |
| 271 control_dependency_ = dependency; | 291 control_dependency_ = dependency; |
| 272 } | 292 } |
| 273 | 293 |
| 274 Node* Context() const { return context_; } | 294 Node* Context() const { return context_; } |
| 275 void SetContext(Node* new_context) { context_ = new_context; } | 295 void SetContext(Node* new_context) { context_ = new_context; } |
| 276 | 296 |
| 277 Environment* CopyForConditional() const; | 297 Environment* CopyForConditional() const; |
| 278 Environment* CopyForLoop(); | 298 Environment* CopyForLoop(); |
| 279 void Merge(Environment* other); | 299 void Merge(Environment* other); |
| 280 | 300 |
| 281 private: | 301 private: |
| 282 explicit Environment(const Environment* copy); | 302 explicit Environment(const Environment* copy); |
| 283 void PrepareForLoop(); | 303 void PrepareForLoop(); |
| 304 bool StateValuesRequireUpdate(Node** state_values, int offset, int count); |
| 305 void UpdateStateValues(Node** state_values, int offset, int count); |
| 284 | 306 |
| 285 int RegisterToValuesIndex(interpreter::Register the_register) const; | 307 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| 308 |
| 286 Zone* zone() const { return builder_->local_zone(); } | 309 Zone* zone() const { return builder_->local_zone(); } |
| 287 Graph* graph() const { return builder_->graph(); } | 310 Graph* graph() const { return builder_->graph(); } |
| 288 CommonOperatorBuilder* common() const { return builder_->common(); } | 311 CommonOperatorBuilder* common() const { return builder_->common(); } |
| 289 BytecodeGraphBuilder* builder() const { return builder_; } | 312 BytecodeGraphBuilder* builder() const { return builder_; } |
| 290 const NodeVector* values() const { return &values_; } | 313 const NodeVector* values() const { return &values_; } |
| 291 NodeVector* values() { return &values_; } | 314 NodeVector* values() { return &values_; } |
| 292 Node* accumulator() { return accumulator_; } | |
| 293 int register_base() const { return register_base_; } | 315 int register_base() const { return register_base_; } |
| 316 int accumulator_base() const { return accumulator_base_; } |
| 294 | 317 |
| 295 BytecodeGraphBuilder* builder_; | 318 BytecodeGraphBuilder* builder_; |
| 296 int register_count_; | 319 int register_count_; |
| 297 int parameter_count_; | 320 int parameter_count_; |
| 298 Node* accumulator_; | |
| 299 Node* context_; | 321 Node* context_; |
| 300 Node* control_dependency_; | 322 Node* control_dependency_; |
| 301 Node* effect_dependency_; | 323 Node* effect_dependency_; |
| 302 NodeVector values_; | 324 NodeVector values_; |
| 325 Node* parameters_state_values_; |
| 326 Node* registers_state_values_; |
| 327 Node* accumulator_state_values_; |
| 303 int register_base_; | 328 int register_base_; |
| 329 int accumulator_base_; |
| 304 }; | 330 }; |
| 305 | 331 |
| 306 } // namespace compiler | 332 } // namespace compiler |
| 307 } // namespace internal | 333 } // namespace internal |
| 308 } // namespace v8 | 334 } // namespace v8 |
| 309 | 335 |
| 310 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 336 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
| OLD | NEW |