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/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/interpreter/bytecode-array-iterator.h" | 10 #include "src/interpreter/bytecode-array-iterator.h" |
11 #include "src/interpreter/bytecodes.h" | 11 #include "src/interpreter/bytecodes.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 // The BytecodeGraphBuilder produces a high-level IR graph based on | 17 // The BytecodeGraphBuilder produces a high-level IR graph based on |
18 // interpreter bytecodes. | 18 // interpreter bytecodes. |
19 class BytecodeGraphBuilder { | 19 class BytecodeGraphBuilder { |
20 public: | 20 public: |
21 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, | 21 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, |
22 JSGraph* jsgraph); | 22 JSGraph* jsgraph); |
23 | 23 |
24 // Creates a graph by visiting bytecodes. | 24 // Creates a graph by visiting bytecodes. |
25 bool CreateGraph(bool stack_check = true); | 25 bool CreateGraph(bool stack_check = true); |
26 | 26 |
27 Graph* graph() const { return jsgraph_->graph(); } | 27 Graph* graph() const { return jsgraph_->graph(); } |
28 | 28 |
29 private: | 29 private: |
| 30 enum class AccumulatorUpdateMode { |
| 31 kOutputIgnored, |
| 32 kOutputInAccumulator, |
| 33 }; |
| 34 |
30 class Environment; | 35 class Environment; |
| 36 class FrameStateBeforeAndAfter; |
31 | 37 |
32 void CreateGraphBody(bool stack_check); | 38 void CreateGraphBody(bool stack_check); |
33 void VisitBytecodes(); | 39 void VisitBytecodes(); |
34 | 40 |
35 Node* LoadAccumulator(Node* value); | 41 Node* LoadAccumulator(Node* value); |
36 | 42 |
37 // Get or create the node that represents the outer function closure. | 43 // Get or create the node that represents the outer function closure. |
38 Node* GetFunctionClosure(); | 44 Node* GetFunctionClosure(); |
39 | 45 |
40 // Get or create the node that represents the outer function context. | 46 // Get or create the node that represents the outer function context. |
41 Node* GetFunctionContext(); | 47 Node* GetFunctionContext(); |
42 | 48 |
43 // Get or create the node that represents the incoming new target value. | 49 // Get or create the node that represents the incoming new target value. |
44 Node* GetNewTarget(); | 50 Node* GetNewTarget(); |
45 | 51 |
46 // Builder for accessing a (potentially immutable) object field. | 52 // Builder for accessing a (potentially immutable) object field. |
47 Node* BuildLoadObjectField(Node* object, int offset); | 53 Node* BuildLoadObjectField(Node* object, int offset); |
48 Node* BuildLoadImmutableObjectField(Node* object, int offset); | 54 Node* BuildLoadImmutableObjectField(Node* object, int offset); |
49 | 55 |
50 // Builder for accessing type feedback vector. | 56 // Builder for accessing type feedback vector. |
51 Node* BuildLoadFeedbackVector(); | 57 Node* BuildLoadFeedbackVector(); |
52 | 58 |
53 // Builder for loading the a native context field. | 59 // Builder for loading the a native context field. |
54 Node* BuildLoadNativeContextField(int index); | 60 Node* BuildLoadNativeContextField(int index); |
55 | 61 |
56 // Helper function for creating a pair containing type feedback vector and | 62 // Helper function for creating a pair containing type feedback vector and |
57 // a feedback slot. | 63 // a feedback slot. |
58 VectorSlotPair CreateVectorSlotPair(int slot_id); | 64 VectorSlotPair CreateVectorSlotPair(int slot_id); |
59 | 65 |
60 // Replaces the frame state inputs with empty frame states. | |
61 void AddEmptyFrameStateInputs(Node* node); | |
62 | |
63 void set_environment(Environment* env) { environment_ = env; } | 66 void set_environment(Environment* env) { environment_ = env; } |
64 const Environment* environment() const { return environment_; } | 67 const Environment* environment() const { return environment_; } |
65 Environment* environment() { return environment_; } | 68 Environment* environment() { return environment_; } |
66 | 69 |
67 // Node creation helpers | 70 // Node creation helpers |
68 Node* NewNode(const Operator* op, bool incomplete = false) { | 71 Node* NewNode(const Operator* op, bool incomplete = false) { |
69 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); | 72 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); |
70 } | 73 } |
71 | 74 |
72 Node* NewNode(const Operator* op, Node* n1) { | 75 Node* NewNode(const Operator* op, Node* n1) { |
(...skipping 27 matching lines...) Expand all Loading... |
100 | 103 |
101 Node* ProcessCallArguments(const Operator* call_op, Node* callee, | 104 Node* ProcessCallArguments(const Operator* call_op, Node* callee, |
102 interpreter::Register receiver, size_t arity); | 105 interpreter::Register receiver, size_t arity); |
103 Node* ProcessCallNewArguments(const Operator* call_new_op, | 106 Node* ProcessCallNewArguments(const Operator* call_new_op, |
104 interpreter::Register callee, | 107 interpreter::Register callee, |
105 interpreter::Register first_arg, size_t arity); | 108 interpreter::Register first_arg, size_t arity); |
106 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, | 109 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, |
107 interpreter::Register first_arg, | 110 interpreter::Register first_arg, |
108 size_t arity); | 111 size_t arity); |
109 | 112 |
110 void BuildCreateLiteral(const Operator* op); | 113 void BuildCreateLiteral(const Operator* op, |
| 114 const interpreter::BytecodeArrayIterator& iterator); |
111 void BuildCreateRegExpLiteral( | 115 void BuildCreateRegExpLiteral( |
112 const interpreter::BytecodeArrayIterator& iterator); | 116 const interpreter::BytecodeArrayIterator& iterator); |
113 void BuildCreateArrayLiteral( | 117 void BuildCreateArrayLiteral( |
114 const interpreter::BytecodeArrayIterator& iterator); | 118 const interpreter::BytecodeArrayIterator& iterator); |
115 void BuildCreateObjectLiteral( | 119 void BuildCreateObjectLiteral( |
116 const interpreter::BytecodeArrayIterator& iterator); | 120 const interpreter::BytecodeArrayIterator& iterator); |
117 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, | 121 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, |
118 TypeofMode typeof_mode); | 122 TypeofMode typeof_mode); |
119 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); | 123 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); |
120 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator); | 124 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator); |
(...skipping 16 matching lines...) Expand all Loading... |
137 // Field accessors | 141 // Field accessors |
138 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 142 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
139 Zone* graph_zone() const { return graph()->zone(); } | 143 Zone* graph_zone() const { return graph()->zone(); } |
140 CompilationInfo* info() const { return info_; } | 144 CompilationInfo* info() const { return info_; } |
141 JSGraph* jsgraph() const { return jsgraph_; } | 145 JSGraph* jsgraph() const { return jsgraph_; } |
142 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } | 146 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } |
143 Zone* local_zone() const { return local_zone_; } | 147 Zone* local_zone() const { return local_zone_; } |
144 const Handle<BytecodeArray>& bytecode_array() const { | 148 const Handle<BytecodeArray>& bytecode_array() const { |
145 return bytecode_array_; | 149 return bytecode_array_; |
146 } | 150 } |
| 151 const FrameStateFunctionInfo* frame_state_function_info() const { |
| 152 return frame_state_function_info_; |
| 153 } |
147 | 154 |
148 LanguageMode language_mode() const { | 155 LanguageMode language_mode() const { |
149 // TODO(mythria): Don't rely on parse information to get language mode. | 156 // TODO(mythria): Don't rely on parse information to get language mode. |
150 return info()->language_mode(); | 157 return info()->language_mode(); |
151 } | 158 } |
152 | 159 |
153 #define DECLARE_VISIT_BYTECODE(name, ...) \ | 160 #define DECLARE_VISIT_BYTECODE(name, ...) \ |
154 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); | 161 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); |
155 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) | 162 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) |
156 #undef DECLARE_VISIT_BYTECODE | 163 #undef DECLARE_VISIT_BYTECODE |
157 | 164 |
158 Zone* local_zone_; | 165 Zone* local_zone_; |
159 CompilationInfo* info_; | 166 CompilationInfo* info_; |
160 JSGraph* jsgraph_; | 167 JSGraph* jsgraph_; |
161 Handle<BytecodeArray> bytecode_array_; | 168 Handle<BytecodeArray> bytecode_array_; |
| 169 const FrameStateFunctionInfo* frame_state_function_info_; |
162 Environment* environment_; | 170 Environment* environment_; |
163 | 171 |
164 // Temporary storage for building node input lists. | 172 // Temporary storage for building node input lists. |
165 int input_buffer_size_; | 173 int input_buffer_size_; |
166 Node** input_buffer_; | 174 Node** input_buffer_; |
167 | 175 |
168 // Nodes representing values in the activation record. | 176 // Nodes representing values in the activation record. |
169 SetOncePointer<Node> function_context_; | 177 SetOncePointer<Node> function_context_; |
170 SetOncePointer<Node> function_closure_; | 178 SetOncePointer<Node> function_closure_; |
171 SetOncePointer<Node> new_target_; | 179 SetOncePointer<Node> new_target_; |
(...skipping 24 matching lines...) Expand all Loading... |
196 | 204 |
197 bool IsMarkedAsUnreachable() const; | 205 bool IsMarkedAsUnreachable() const; |
198 void MarkAsUnreachable(); | 206 void MarkAsUnreachable(); |
199 | 207 |
200 // Effect dependency tracked by this environment. | 208 // Effect dependency tracked by this environment. |
201 Node* GetEffectDependency() { return effect_dependency_; } | 209 Node* GetEffectDependency() { return effect_dependency_; } |
202 void UpdateEffectDependency(Node* dependency) { | 210 void UpdateEffectDependency(Node* dependency) { |
203 effect_dependency_ = dependency; | 211 effect_dependency_ = dependency; |
204 } | 212 } |
205 | 213 |
| 214 // Preserve a checkpoint of the environment for the IR graph. Any |
| 215 // further mutation of the environment will not affect checkpoints. |
| 216 Node* Checkpoint(BailoutId ast_id, AccumulatorUpdateMode update_mode); |
| 217 |
206 // Control dependency tracked by this environment. | 218 // Control dependency tracked by this environment. |
207 Node* GetControlDependency() const { return control_dependency_; } | 219 Node* GetControlDependency() const { return control_dependency_; } |
208 void UpdateControlDependency(Node* dependency) { | 220 void UpdateControlDependency(Node* dependency) { |
209 control_dependency_ = dependency; | 221 control_dependency_ = dependency; |
210 } | 222 } |
211 | 223 |
212 Node* Context() const { return context_; } | 224 Node* Context() const { return context_; } |
213 void SetContext(Node* new_context) { context_ = new_context; } | 225 void SetContext(Node* new_context) { context_ = new_context; } |
214 | 226 |
215 private: | 227 private: |
216 int RegisterToValuesIndex(interpreter::Register the_register) const; | 228 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| 229 void UpdateStateValues(Node** state_values, int offset, int count); |
217 | 230 |
218 Zone* zone() const { return builder_->local_zone(); } | 231 Zone* zone() const { return builder_->local_zone(); } |
219 Graph* graph() const { return builder_->graph(); } | 232 Graph* graph() const { return builder_->graph(); } |
220 CommonOperatorBuilder* common() const { return builder_->common(); } | 233 CommonOperatorBuilder* common() const { return builder_->common(); } |
221 BytecodeGraphBuilder* builder() const { return builder_; } | 234 BytecodeGraphBuilder* builder() const { return builder_; } |
222 const NodeVector* values() const { return &values_; } | 235 const NodeVector* values() const { return &values_; } |
223 NodeVector* values() { return &values_; } | 236 NodeVector* values() { return &values_; } |
224 Node* accumulator() { return accumulator_; } | 237 Node* accumulator() { return accumulator_; } |
225 int register_base() const { return register_base_; } | 238 int register_base() const { return register_base_; } |
| 239 int accumulator_base() const { return accumulator_base_; } |
226 | 240 |
227 BytecodeGraphBuilder* builder_; | 241 BytecodeGraphBuilder* builder_; |
228 int register_count_; | 242 int register_count_; |
229 int parameter_count_; | 243 int parameter_count_; |
230 Node* accumulator_; | 244 Node* accumulator_; |
231 Node* context_; | 245 Node* context_; |
232 Node* control_dependency_; | 246 Node* control_dependency_; |
233 Node* effect_dependency_; | 247 Node* effect_dependency_; |
234 NodeVector values_; | 248 NodeVector values_; |
235 int register_base_; | 249 int register_base_; |
| 250 int accumulator_base_; |
| 251 Node* parameters_state_values_; |
| 252 Node* registers_state_values_; |
| 253 Node* accumulator_state_values_; |
236 }; | 254 }; |
237 | 255 |
238 | 256 |
239 } // namespace compiler | 257 } // namespace compiler |
240 } // namespace internal | 258 } // namespace internal |
241 } // namespace v8 | 259 } // namespace v8 |
242 | 260 |
243 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 261 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
OLD | NEW |