Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 HBasicBlock* loop_header_; | 189 HBasicBlock* loop_header_; |
| 190 ZoneList<HBasicBlock*> blocks_; | 190 ZoneList<HBasicBlock*> blocks_; |
| 191 }; | 191 }; |
| 192 | 192 |
| 193 | 193 |
| 194 class HSubgraph: public ZoneObject { | 194 class HSubgraph: public ZoneObject { |
| 195 public: | 195 public: |
| 196 explicit HSubgraph(HGraph* graph) | 196 explicit HSubgraph(HGraph* graph) |
| 197 : graph_(graph), | 197 : graph_(graph), |
| 198 entry_block_(NULL), | 198 entry_block_(NULL), |
| 199 exit_block_(NULL), | 199 exit_block_(NULL) { |
| 200 break_continue_info_(4) { | |
| 201 } | 200 } |
| 202 | 201 |
| 203 HGraph* graph() const { return graph_; } | 202 HGraph* graph() const { return graph_; } |
| 204 HEnvironment* environment() const { | 203 HEnvironment* environment() const { |
| 205 ASSERT(HasExit()); | 204 ASSERT(HasExit()); |
| 206 return exit_block_->last_environment(); | 205 return exit_block_->last_environment(); |
| 207 } | 206 } |
| 208 | 207 |
| 209 bool HasExit() const { return exit_block_ != NULL; } | 208 bool HasExit() const { return exit_block_ != NULL; } |
| 210 | 209 |
| 211 void PreProcessOsrEntry(IterationStatement* statement); | 210 void PreProcessOsrEntry(IterationStatement* statement); |
| 212 | 211 |
| 213 void AppendJoin(HSubgraph* then_graph, HSubgraph* else_graph, AstNode* node); | 212 void AppendJoin(HSubgraph* then_graph, HSubgraph* else_graph, AstNode* node); |
| 214 void AppendWhile(HSubgraph* condition, | 213 void AppendWhile(HSubgraph* condition, |
| 215 HSubgraph* body, | 214 HSubgraph* body, |
| 216 IterationStatement* statement, | 215 IterationStatement* statement, |
| 217 HSubgraph* continue_subgraph, | 216 HSubgraph* continue_subgraph, |
| 218 HSubgraph* exit); | 217 HSubgraph* exit, |
| 218 HBasicBlock* break_block); | |
| 219 void AppendDoWhile(HSubgraph* body, | 219 void AppendDoWhile(HSubgraph* body, |
| 220 IterationStatement* statement, | 220 IterationStatement* statement, |
| 221 HSubgraph* go_back, | 221 HSubgraph* go_back, |
| 222 HSubgraph* exit); | 222 HSubgraph* exit, |
| 223 void AppendEndless(HSubgraph* body, IterationStatement* statement); | 223 HBasicBlock* break_block); |
| 224 void Append(HSubgraph* next, BreakableStatement* statement); | 224 void AppendEndless(HSubgraph* body, |
| 225 void ResolveContinue(IterationStatement* statement); | 225 IterationStatement* statement, |
| 226 HBasicBlock* BundleBreak(BreakableStatement* statement); | 226 HBasicBlock* break_block); |
| 227 HBasicBlock* BundleContinue(IterationStatement* statement); | 227 void Append(HSubgraph* next, |
| 228 HBasicBlock* BundleBreakContinue(BreakableStatement* statement, | 228 BreakableStatement* stmt, |
| 229 bool is_continue, | 229 HBasicBlock* break_block); |
| 230 int join_id); | 230 void ResolveContinue(IterationStatement* statement, |
| 231 HBasicBlock* continue_block); | |
| 231 HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id); | 232 HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id); |
| 232 | 233 |
| 233 void FinishExit(HControlInstruction* instruction); | 234 void FinishExit(HControlInstruction* instruction); |
| 234 void FinishBreakContinue(BreakableStatement* target, bool is_continue); | |
| 235 void Initialize(HBasicBlock* block) { | 235 void Initialize(HBasicBlock* block) { |
| 236 ASSERT(entry_block_ == NULL); | 236 ASSERT(entry_block_ == NULL); |
| 237 entry_block_ = block; | 237 entry_block_ = block; |
| 238 exit_block_ = block; | 238 exit_block_ = block; |
| 239 } | 239 } |
| 240 HBasicBlock* entry_block() const { return entry_block_; } | 240 HBasicBlock* entry_block() const { return entry_block_; } |
| 241 HBasicBlock* exit_block() const { return exit_block_; } | 241 HBasicBlock* exit_block() const { return exit_block_; } |
| 242 void set_exit_block(HBasicBlock* block) { | 242 void set_exit_block(HBasicBlock* block) { |
| 243 exit_block_ = block; | 243 exit_block_ = block; |
| 244 } | 244 } |
| 245 | 245 |
| 246 void ConnectExitTo(HBasicBlock* other, bool include_stack_check = false) { | 246 void ConnectExitTo(HBasicBlock* other, bool include_stack_check = false) { |
| 247 if (HasExit()) { | 247 if (HasExit()) { |
| 248 exit_block()->Goto(other, include_stack_check); | 248 exit_block()->Goto(other, include_stack_check); |
| 249 } | 249 } |
| 250 } | 250 } |
| 251 | 251 |
| 252 void AddBreakContinueInfo(HSubgraph* other) { | |
| 253 break_continue_info_.AddAll(other->break_continue_info_); | |
| 254 } | |
| 255 | |
| 256 protected: | 252 protected: |
| 257 class BreakContinueInfo: public ZoneObject { | |
| 258 public: | |
| 259 BreakContinueInfo(BreakableStatement* target, HBasicBlock* block, | |
| 260 bool is_continue) | |
| 261 : target_(target), block_(block), continue_(is_continue) {} | |
| 262 BreakableStatement* target() const { return target_; } | |
| 263 HBasicBlock* block() const { return block_; } | |
| 264 bool is_continue() const { return continue_; } | |
| 265 bool IsResolved() const { return block_ == NULL; } | |
| 266 void Resolve() { block_ = NULL; } | |
| 267 | |
| 268 private: | |
| 269 BreakableStatement* target_; | |
| 270 HBasicBlock* block_; | |
| 271 bool continue_; | |
| 272 }; | |
| 273 | |
| 274 const ZoneList<BreakContinueInfo*>* break_continue_info() const { | |
| 275 return &break_continue_info_; | |
| 276 } | |
| 277 | |
| 278 HGraph* graph_; // The graph this is a subgraph of. | 253 HGraph* graph_; // The graph this is a subgraph of. |
| 279 HBasicBlock* entry_block_; | 254 HBasicBlock* entry_block_; |
| 280 HBasicBlock* exit_block_; | 255 HBasicBlock* exit_block_; |
| 281 | |
| 282 private: | |
| 283 ZoneList<BreakContinueInfo*> break_continue_info_; | |
| 284 }; | 256 }; |
| 285 | 257 |
| 286 | 258 |
| 287 class HGraph: public HSubgraph { | 259 class HGraph: public HSubgraph { |
| 288 public: | 260 public: |
| 289 explicit HGraph(CompilationInfo* info); | 261 explicit HGraph(CompilationInfo* info); |
| 290 | 262 |
| 291 CompilationInfo* info() const { return info_; } | 263 CompilationInfo* info() const { return info_; } |
| 292 | 264 |
| 293 bool AllowCodeMotion() const; | 265 bool AllowCodeMotion() const; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 // control flow. | 583 // control flow. |
| 612 void BuildBranch(HValue* value); | 584 void BuildBranch(HValue* value); |
| 613 | 585 |
| 614 HBasicBlock* if_true_; | 586 HBasicBlock* if_true_; |
| 615 HBasicBlock* if_false_; | 587 HBasicBlock* if_false_; |
| 616 }; | 588 }; |
| 617 | 589 |
| 618 | 590 |
| 619 class HGraphBuilder: public AstVisitor { | 591 class HGraphBuilder: public AstVisitor { |
| 620 public: | 592 public: |
| 593 enum BreakType { BREAK, CONTINUE }; | |
| 594 | |
| 595 // A (lazily-allocated) break and continue block for a breakable | |
| 596 // statement. | |
| 597 class BreakAndContinueInfo BASE_EMBEDDED { | |
| 598 public: | |
| 599 explicit BreakAndContinueInfo(BreakableStatement* target) | |
| 600 : target_(target), break_block_(NULL), continue_block_(NULL) { | |
| 601 } | |
| 602 | |
| 603 BreakableStatement* target() { return target_; } | |
| 604 HBasicBlock* break_block() { return break_block_; } | |
| 605 void set_break_block(HBasicBlock* block) { break_block_ = block; } | |
| 606 HBasicBlock* continue_block() { return continue_block_; } | |
| 607 void set_continue_block(HBasicBlock* block) { continue_block_ = block; } | |
| 608 | |
| 609 private: | |
| 610 BreakableStatement* target_; | |
| 611 HBasicBlock* break_block_; | |
| 612 HBasicBlock* continue_block_; | |
| 613 }; | |
| 614 | |
| 615 // A helper class to maintain a stack of current BreakAndContinueInfo | |
| 616 // structures mirroring BreakableStatement nesting. | |
| 617 class BreakStackEntry BASE_EMBEDDED { | |
|
Mads Ager (chromium)
2011/02/22 08:18:58
Why is the stack separate from the BreakAndContinu
| |
| 618 public: | |
| 619 BreakStackEntry(BreakAndContinueInfo* info, HGraphBuilder* owner) | |
| 620 : info_(info), owner_(owner), next_(owner->break_stack()) { | |
| 621 owner->set_break_stack(this); | |
| 622 } | |
| 623 | |
| 624 ~BreakStackEntry() { owner_->set_break_stack(next_); } | |
| 625 | |
| 626 BreakAndContinueInfo* info() { return info_; } | |
| 627 HGraphBuilder* owner() { return owner_; } | |
| 628 BreakStackEntry* next() { return next_; } | |
| 629 | |
| 630 // Search the break stack for a break or continue target. | |
| 631 HBasicBlock* Get(BreakableStatement* stmt, BreakType type); | |
| 632 | |
| 633 private: | |
| 634 BreakAndContinueInfo* info_; | |
| 635 HGraphBuilder* owner_; | |
| 636 BreakStackEntry* next_; | |
| 637 }; | |
| 638 | |
| 621 explicit HGraphBuilder(TypeFeedbackOracle* oracle) | 639 explicit HGraphBuilder(TypeFeedbackOracle* oracle) |
| 622 : oracle_(oracle), | 640 : oracle_(oracle), |
| 623 graph_(NULL), | 641 graph_(NULL), |
| 624 current_subgraph_(NULL), | 642 current_subgraph_(NULL), |
| 625 peeled_statement_(NULL), | 643 peeled_statement_(NULL), |
| 626 ast_context_(NULL), | 644 ast_context_(NULL), |
| 627 call_context_(NULL), | 645 call_context_(NULL), |
| 628 function_return_(NULL), | 646 function_return_(NULL), |
| 629 inlined_count_(0) { } | 647 inlined_count_(0), |
| 648 break_stack_(NULL) { | |
| 649 } | |
| 630 | 650 |
| 631 HGraph* CreateGraph(CompilationInfo* info); | 651 HGraph* CreateGraph(CompilationInfo* info); |
| 632 | 652 |
| 633 // Simple accessors. | 653 // Simple accessors. |
| 634 HGraph* graph() const { return graph_; } | 654 HGraph* graph() const { return graph_; } |
| 635 HSubgraph* subgraph() const { return current_subgraph_; } | 655 HSubgraph* subgraph() const { return current_subgraph_; } |
| 656 BreakStackEntry* break_stack() const { return break_stack_; } | |
| 657 void set_break_stack(BreakStackEntry* head) { break_stack_ = head; } | |
| 636 | 658 |
| 637 HEnvironment* environment() const { return subgraph()->environment(); } | 659 HEnvironment* environment() const { return subgraph()->environment(); } |
| 638 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } | 660 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } |
| 639 | 661 |
| 640 // Adding instructions. | 662 // Adding instructions. |
| 641 HInstruction* AddInstruction(HInstruction* instr); | 663 HInstruction* AddInstruction(HInstruction* instr); |
| 642 void AddSimulate(int id); | 664 void AddSimulate(int id); |
| 643 | 665 |
| 644 // Bailout environment manipulation. | 666 // Bailout environment manipulation. |
| 645 void Push(HValue* value) { environment()->Push(value); } | 667 void Push(HValue* value) { environment()->Push(value); } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 676 | 698 |
| 677 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 699 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 678 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 700 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 679 #undef INLINE_FUNCTION_GENERATOR_DECLARATION | 701 #undef INLINE_FUNCTION_GENERATOR_DECLARATION |
| 680 | 702 |
| 681 void Bailout(const char* reason); | 703 void Bailout(const char* reason); |
| 682 | 704 |
| 683 void AppendPeeledWhile(IterationStatement* stmt, | 705 void AppendPeeledWhile(IterationStatement* stmt, |
| 684 HSubgraph* cond_graph, | 706 HSubgraph* cond_graph, |
| 685 HSubgraph* body_graph, | 707 HSubgraph* body_graph, |
| 686 HSubgraph* exit_graph); | 708 HSubgraph* exit_graph, |
| 709 HBasicBlock* break_block); | |
| 687 | 710 |
| 688 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); | 711 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); |
| 689 void AddToSubgraph(HSubgraph* graph, Statement* stmt); | 712 void AddToSubgraph(HSubgraph* graph, Statement* stmt); |
| 690 void AddToSubgraph(HSubgraph* graph, Expression* expr); | 713 void AddToSubgraph(HSubgraph* graph, Expression* expr); |
| 691 | 714 |
| 692 HValue* Top() const { return environment()->Top(); } | 715 HValue* Top() const { return environment()->Top(); } |
| 693 void Drop(int n) { environment()->Drop(n); } | 716 void Drop(int n) { environment()->Drop(n); } |
| 694 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } | 717 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } |
| 695 | 718 |
| 696 void VisitForValue(Expression* expr); | 719 void VisitForValue(Expression* expr); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 // inlined. NULL when not inlining. | 871 // inlined. NULL when not inlining. |
| 849 AstContext* call_context_; | 872 AstContext* call_context_; |
| 850 | 873 |
| 851 // When inlining a call in an effect or value context, the return | 874 // When inlining a call in an effect or value context, the return |
| 852 // block. NULL otherwise. When inlining a call in a test context, there | 875 // block. NULL otherwise. When inlining a call in a test context, there |
| 853 // are a pair of target blocks in the call context. | 876 // are a pair of target blocks in the call context. |
| 854 HBasicBlock* function_return_; | 877 HBasicBlock* function_return_; |
| 855 | 878 |
| 856 int inlined_count_; | 879 int inlined_count_; |
| 857 | 880 |
| 881 BreakStackEntry* break_stack_; | |
| 882 | |
| 858 friend class AstContext; // Pushes and pops the AST context stack. | 883 friend class AstContext; // Pushes and pops the AST context stack. |
| 859 | 884 |
| 860 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); | 885 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); |
| 861 }; | 886 }; |
| 862 | 887 |
| 863 | 888 |
| 864 class HValueMap: public ZoneObject { | 889 class HValueMap: public ZoneObject { |
| 865 public: | 890 public: |
| 866 HValueMap() | 891 HValueMap() |
| 867 : array_size_(0), | 892 : array_size_(0), |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1068 const char* filename_; | 1093 const char* filename_; |
| 1069 HeapStringAllocator string_allocator_; | 1094 HeapStringAllocator string_allocator_; |
| 1070 StringStream trace_; | 1095 StringStream trace_; |
| 1071 int indent_; | 1096 int indent_; |
| 1072 }; | 1097 }; |
| 1073 | 1098 |
| 1074 | 1099 |
| 1075 } } // namespace v8::internal | 1100 } } // namespace v8::internal |
| 1076 | 1101 |
| 1077 #endif // V8_HYDROGEN_H_ | 1102 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |