OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 15 matching lines...) Expand all Loading... |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_CFG_H_ | 28 #ifndef V8_CFG_H_ |
29 #define V8_CFG_H_ | 29 #define V8_CFG_H_ |
30 | 30 |
31 #include "ast.h" | 31 #include "ast.h" |
32 | 32 |
33 namespace v8 { | 33 namespace v8 { |
34 namespace internal { | 34 namespace internal { |
35 | 35 |
| 36 class ExitNode; |
| 37 |
| 38 // A convenient class to keep 'global' values when building a CFG. Since |
| 39 // CFG construction can be invoked recursively, CFG globals are stacked. |
| 40 class CfgGlobals BASE_EMBEDDED { |
| 41 public: |
| 42 explicit CfgGlobals(FunctionLiteral* fun); |
| 43 |
| 44 ~CfgGlobals() { top_ = previous_; } |
| 45 |
| 46 static CfgGlobals* current() { |
| 47 ASSERT(top_ != NULL); |
| 48 return top_; |
| 49 } |
| 50 |
| 51 FunctionLiteral* fun() { return global_fun_; } |
| 52 |
| 53 ExitNode* exit() { return global_exit_; } |
| 54 |
| 55 #ifdef DEBUG |
| 56 int next_number() { return node_counter_++; } |
| 57 #endif |
| 58 |
| 59 private: |
| 60 static CfgGlobals* top_; |
| 61 |
| 62 // Function literal currently compiling. |
| 63 FunctionLiteral* global_fun_; |
| 64 |
| 65 // Shared global exit node for all returns from the same function. |
| 66 ExitNode* global_exit_; |
| 67 |
| 68 #ifdef DEBUG |
| 69 // Used to number nodes when printing. |
| 70 int node_counter_; |
| 71 #endif |
| 72 |
| 73 CfgGlobals* previous_; |
| 74 }; |
| 75 |
| 76 |
36 // Values appear in instructions. They represent trivial source | 77 // Values appear in instructions. They represent trivial source |
37 // expressions: ones with no side effects and that do not require code to be | 78 // expressions: ones with no side effects and that do not require code to be |
38 // generated. | 79 // generated. |
39 class Value : public ZoneObject { | 80 class Value : public ZoneObject { |
40 public: | 81 public: |
41 virtual ~Value() {} | 82 virtual ~Value() {} |
42 | 83 |
43 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0; | 84 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0; |
44 | 85 |
45 #ifdef DEBUG | 86 #ifdef DEBUG |
(...skipping 13 matching lines...) Expand all Loading... |
59 | 100 |
60 #ifdef DEBUG | 101 #ifdef DEBUG |
61 void Print(); | 102 void Print(); |
62 #endif | 103 #endif |
63 | 104 |
64 private: | 105 private: |
65 Handle<Object> handle_; | 106 Handle<Object> handle_; |
66 }; | 107 }; |
67 | 108 |
68 | 109 |
| 110 // Locations are values that can be stored into ('lvalues'). |
| 111 class Location : public Value { |
| 112 public: |
| 113 virtual ~Location() {} |
| 114 |
| 115 virtual void ToRegister(MacroAssembler* masm, Register reg) = 0; |
| 116 |
| 117 #ifdef DEBUG |
| 118 virtual void Print() = 0; |
| 119 #endif |
| 120 }; |
| 121 |
| 122 |
| 123 // SlotLocations represent parameters and stack-allocated (i.e., |
| 124 // non-context) local variables. |
| 125 class SlotLocation : public Location { |
| 126 public: |
| 127 SlotLocation(Slot::Type type, int index) : type_(type), index_(index) {} |
| 128 |
| 129 void ToRegister(MacroAssembler* masm, Register reg); |
| 130 |
| 131 #ifdef DEBUG |
| 132 void Print(); |
| 133 #endif |
| 134 |
| 135 private: |
| 136 Slot::Type type_; |
| 137 int index_; |
| 138 }; |
| 139 |
| 140 |
69 // Instructions are computations. The represent non-trivial source | 141 // Instructions are computations. The represent non-trivial source |
70 // expressions: typically ones that have side effects and require code to | 142 // expressions: typically ones that have side effects and require code to |
71 // be generated. | 143 // be generated. |
72 class Instruction : public ZoneObject { | 144 class Instruction : public ZoneObject { |
73 public: | 145 public: |
74 virtual ~Instruction() {} | 146 virtual ~Instruction() {} |
75 | 147 |
76 virtual void Compile(MacroAssembler* masm) = 0; | 148 virtual void Compile(MacroAssembler* masm) = 0; |
77 | 149 |
78 #ifdef DEBUG | 150 #ifdef DEBUG |
(...skipping 28 matching lines...) Expand all Loading... |
107 CfgNode() : is_marked_(false) { | 179 CfgNode() : is_marked_(false) { |
108 #ifdef DEBUG | 180 #ifdef DEBUG |
109 number_ = -1; | 181 number_ = -1; |
110 #endif | 182 #endif |
111 } | 183 } |
112 | 184 |
113 virtual ~CfgNode() {} | 185 virtual ~CfgNode() {} |
114 | 186 |
115 bool is_marked() { return is_marked_; } | 187 bool is_marked() { return is_marked_; } |
116 | 188 |
117 static void Reset(); | |
118 | |
119 virtual bool is_block() { return false; } | 189 virtual bool is_block() { return false; } |
120 | 190 |
121 virtual void Unmark() = 0; | 191 virtual void Unmark() = 0; |
122 | 192 |
123 virtual void Compile(MacroAssembler* masm) = 0; | 193 virtual void Compile(MacroAssembler* masm) = 0; |
124 | 194 |
125 #ifdef DEBUG | 195 #ifdef DEBUG |
126 int number() { | 196 int number() { |
127 if (number_ == -1) number_ = node_counter_++; | 197 if (number_ == -1) number_ = CfgGlobals::current()->next_number(); |
128 return number_; | 198 return number_; |
129 } | 199 } |
130 | 200 |
131 virtual void Print() = 0; | 201 virtual void Print() = 0; |
132 #endif | 202 #endif |
133 | 203 |
134 protected: | 204 protected: |
135 bool is_marked_; | 205 bool is_marked_; |
136 | 206 |
137 #ifdef DEBUG | 207 #ifdef DEBUG |
138 int number_; | 208 int number_; |
139 | |
140 static int node_counter_; | |
141 #endif | 209 #endif |
142 }; | 210 }; |
143 | 211 |
144 | 212 |
145 // A block is a single-entry, single-exit block of instructions. | 213 // A block is a single-entry, single-exit block of instructions. |
146 class InstructionBlock : public CfgNode { | 214 class InstructionBlock : public CfgNode { |
147 public: | 215 public: |
148 InstructionBlock() : successor_(NULL), instructions_(4) {} | 216 InstructionBlock() : successor_(NULL), instructions_(4) {} |
149 | 217 |
150 virtual ~InstructionBlock() {} | 218 virtual ~InstructionBlock() {} |
(...skipping 24 matching lines...) Expand all Loading... |
175 CfgNode* successor_; | 243 CfgNode* successor_; |
176 ZoneList<Instruction*> instructions_; | 244 ZoneList<Instruction*> instructions_; |
177 }; | 245 }; |
178 | 246 |
179 | 247 |
180 // The CFG for a function has a distinguished entry node. It has no | 248 // The CFG for a function has a distinguished entry node. It has no |
181 // predecessors and a single successor. The successor is the block | 249 // predecessors and a single successor. The successor is the block |
182 // containing the function's first instruction. | 250 // containing the function's first instruction. |
183 class EntryNode : public CfgNode { | 251 class EntryNode : public CfgNode { |
184 public: | 252 public: |
185 EntryNode(FunctionLiteral* fun, InstructionBlock* succ); | 253 explicit EntryNode(InstructionBlock* succ) : successor_(succ) {} |
186 | 254 |
187 virtual ~EntryNode() {} | 255 virtual ~EntryNode() {} |
188 | 256 |
189 void Unmark(); | 257 void Unmark(); |
190 | 258 |
191 void Compile(MacroAssembler* masm); | 259 void Compile(MacroAssembler* masm); |
192 | 260 |
193 #ifdef DEBUG | 261 #ifdef DEBUG |
194 void Print(); | 262 void Print(); |
195 #endif | 263 #endif |
196 | 264 |
197 private: | 265 private: |
198 InstructionBlock* successor_; | 266 InstructionBlock* successor_; |
199 int local_count_; | |
200 }; | 267 }; |
201 | 268 |
202 | 269 |
203 // The CFG for a function has a distinguished exit node. It has no | 270 // The CFG for a function has a distinguished exit node. It has no |
204 // successor and arbitrarily many predecessors. The predecessors are all | 271 // successor and arbitrarily many predecessors. The predecessors are all |
205 // the blocks returning from the function. | 272 // the blocks returning from the function. |
206 class ExitNode : public CfgNode { | 273 class ExitNode : public CfgNode { |
207 public: | 274 public: |
208 explicit ExitNode(FunctionLiteral* fun); | 275 ExitNode() {} |
209 | 276 |
210 virtual ~ExitNode() {} | 277 virtual ~ExitNode() {} |
211 | 278 |
212 void Unmark(); | 279 void Unmark(); |
213 | 280 |
214 void Compile(MacroAssembler* masm); | 281 void Compile(MacroAssembler* masm); |
215 | 282 |
216 #ifdef DEBUG | 283 #ifdef DEBUG |
217 void Print(); | 284 void Print(); |
218 #endif | 285 #endif |
219 | |
220 private: | |
221 int parameter_count_; | |
222 }; | 286 }; |
223 | 287 |
224 | 288 |
225 // A CFG is a consists of a linked structure of nodes. It has a single | 289 // A CFG consists of a linked structure of nodes. It has a single entry |
226 // entry node and optionally an exit node. There is a distinguished global | 290 // node and optionally an exit node. There is a distinguished global exit |
227 // exit node that is used as the successor of all blocks that return from | 291 // node that is used as the successor of all blocks that return from the |
228 // the function. | 292 // function. |
229 // | 293 // |
230 // Fragments of control-flow graphs, produced when traversing the statements | 294 // Fragments of control-flow graphs, produced when traversing the statements |
231 // and expressions in the source AST, are represented by the same class. | 295 // and expressions in the source AST, are represented by the same class. |
232 // They have instruction blocks as both their entry and exit (if there is | 296 // They have instruction blocks as both their entry and exit (if there is |
233 // one). Instructions can always be prepended or appended to fragments, and | 297 // one). Instructions can always be prepended or appended to fragments, and |
234 // fragments can always be concatenated. | 298 // fragments can always be concatenated. |
235 // | 299 // |
236 // A singleton CFG fragment (i.e., with only one node) has the same node as | 300 // A singleton CFG fragment (i.e., with only one node) has the same node as |
237 // both entry and exit (if the exit is available). | 301 // both entry and exit (if the exit is available). |
238 class Cfg : public ZoneObject { | 302 class Cfg : public ZoneObject { |
239 public: | 303 public: |
240 // Create a singleton CFG fragment. | 304 // Create a singleton CFG fragment. |
241 explicit Cfg(InstructionBlock* block) : entry_(block), exit_(block) {} | 305 explicit Cfg(InstructionBlock* block) : entry_(block), exit_(block) {} |
242 | 306 |
243 // Build the CFG for a function. | 307 // Build the CFG for a function. |
244 static Cfg* Build(FunctionLiteral* fun); | 308 static Cfg* Build(); |
245 | 309 |
246 // The entry and exit nodes. | 310 // The entry and exit nodes. |
247 CfgNode* entry() { return entry_; } | 311 CfgNode* entry() { return entry_; } |
248 CfgNode* exit() { return exit_; } | 312 CfgNode* exit() { return exit_; } |
249 | 313 |
250 // True if the CFG has no nodes. | 314 // True if the CFG has no nodes. |
251 bool is_empty() { return entry_ == NULL; } | 315 bool is_empty() { return entry_ == NULL; } |
252 | 316 |
253 // True if the CFG has an available exit node (i.e., it can be appended or | 317 // True if the CFG has an available exit node (i.e., it can be appended or |
254 // concatenated to). | 318 // concatenated to). |
255 bool has_exit() { return exit_ != NULL; } | 319 bool has_exit() { return exit_ != NULL; } |
256 | 320 |
257 // Add an entry node to a CFG fragment. It is no longer a fragment | 321 // Add an entry node to a CFG fragment. It is no longer a fragment |
258 // (instructions cannot be prepended). | 322 // (instructions cannot be prepended). |
259 void PrependEntryNode(FunctionLiteral* fun); | 323 void PrependEntryNode(); |
260 | 324 |
261 // Append an instruction to the end of a CFG fragment. Assumes it has an | 325 // Append an instruction to the end of a CFG fragment. Assumes it has an |
262 // available exit. | 326 // available exit. |
263 void Append(Instruction* instr); | 327 void Append(Instruction* instr); |
264 | 328 |
265 // Appends a return instruction to the end of a CFG fragment. It no | 329 // Appends a return instruction to the end of a CFG fragment. It no |
266 // longer has an available exit node. | 330 // longer has an available exit node. |
267 void AppendReturnInstruction(Value* value); | 331 void AppendReturnInstruction(Value* value); |
268 | 332 |
269 Handle<Code> Compile(FunctionLiteral* fun, Handle<Script> script); | 333 Handle<Code> Compile(Handle<Script> script); |
270 | 334 |
271 #ifdef DEBUG | 335 #ifdef DEBUG |
272 // Support for printing. | 336 // Support for printing. |
273 void Print(); | 337 void Print(); |
274 #endif | 338 #endif |
275 | 339 |
276 private: | 340 private: |
277 // Reset static variables before building the CFG for a function. | |
278 static void Reset(FunctionLiteral* fun); | |
279 | |
280 // Shared global exit nodes for all returns from the same function. | |
281 static ExitNode* global_exit_; | |
282 | |
283 // Entry and exit nodes. | 341 // Entry and exit nodes. |
284 CfgNode* entry_; | 342 CfgNode* entry_; |
285 CfgNode* exit_; | 343 CfgNode* exit_; |
286 }; | 344 }; |
287 | 345 |
288 | 346 |
289 // An Expression Builder traverses a trivial expression and returns a value. | 347 // An Expression Builder traverses a trivial expression and returns a value. |
290 class ExpressionBuilder : public AstVisitor { | 348 class ExpressionBuilder : public AstVisitor { |
291 public: | 349 public: |
292 ExpressionBuilder() : value_(new Constant(Handle<Object>::null())) {} | 350 ExpressionBuilder() : value_(new Constant(Handle<Object>::null())) {} |
(...skipping 25 matching lines...) Expand all Loading... |
318 #undef DECLARE_VISIT | 376 #undef DECLARE_VISIT |
319 | 377 |
320 private: | 378 private: |
321 Cfg* cfg_; | 379 Cfg* cfg_; |
322 }; | 380 }; |
323 | 381 |
324 | 382 |
325 } } // namespace v8::internal | 383 } } // namespace v8::internal |
326 | 384 |
327 #endif // V8_CFG_H_ | 385 #endif // V8_CFG_H_ |
OLD | NEW |