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 |