| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 public: | 53 public: |
| 54 explicit HBasicBlock(HGraph* graph); | 54 explicit HBasicBlock(HGraph* graph); |
| 55 virtual ~HBasicBlock() { } | 55 virtual ~HBasicBlock() { } |
| 56 | 56 |
| 57 // Simple accessors. | 57 // Simple accessors. |
| 58 int block_id() const { return block_id_; } | 58 int block_id() const { return block_id_; } |
| 59 void set_block_id(int id) { block_id_ = id; } | 59 void set_block_id(int id) { block_id_ = id; } |
| 60 HGraph* graph() const { return graph_; } | 60 HGraph* graph() const { return graph_; } |
| 61 const ZoneList<HPhi*>* phis() const { return &phis_; } | 61 const ZoneList<HPhi*>* phis() const { return &phis_; } |
| 62 HInstruction* first() const { return first_; } | 62 HInstruction* first() const { return first_; } |
| 63 HInstruction* last() const { return last_; } |
| 64 void set_last(HInstruction* instr) { last_ = instr; } |
| 63 HInstruction* GetLastInstruction(); | 65 HInstruction* GetLastInstruction(); |
| 64 HControlInstruction* end() const { return end_; } | 66 HControlInstruction* end() const { return end_; } |
| 65 HLoopInformation* loop_information() const { return loop_information_; } | 67 HLoopInformation* loop_information() const { return loop_information_; } |
| 66 const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; } | 68 const ZoneList<HBasicBlock*>* predecessors() const { return &predecessors_; } |
| 67 bool HasPredecessor() const { return predecessors_.length() > 0; } | 69 bool HasPredecessor() const { return predecessors_.length() > 0; } |
| 68 const ZoneList<HBasicBlock*>* dominated_blocks() const { | 70 const ZoneList<HBasicBlock*>* dominated_blocks() const { |
| 69 return &dominated_blocks_; | 71 return &dominated_blocks_; |
| 70 } | 72 } |
| 71 const ZoneList<int>* deleted_phis() const { | 73 const ZoneList<int>* deleted_phis() const { |
| 72 return &deleted_phis_; | 74 return &deleted_phis_; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 96 bool IsFinished() const { return end_ != NULL; } | 98 bool IsFinished() const { return end_ != NULL; } |
| 97 void AddPhi(HPhi* phi); | 99 void AddPhi(HPhi* phi); |
| 98 void RemovePhi(HPhi* phi); | 100 void RemovePhi(HPhi* phi); |
| 99 void AddInstruction(HInstruction* instr); | 101 void AddInstruction(HInstruction* instr); |
| 100 bool Dominates(HBasicBlock* other) const; | 102 bool Dominates(HBasicBlock* other) const; |
| 101 | 103 |
| 102 void SetInitialEnvironment(HEnvironment* env); | 104 void SetInitialEnvironment(HEnvironment* env); |
| 103 void ClearEnvironment() { last_environment_ = NULL; } | 105 void ClearEnvironment() { last_environment_ = NULL; } |
| 104 bool HasEnvironment() const { return last_environment_ != NULL; } | 106 bool HasEnvironment() const { return last_environment_ != NULL; } |
| 105 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } | 107 void UpdateEnvironment(HEnvironment* env) { last_environment_ = env; } |
| 106 HBasicBlock* parent_loop_header() const { | 108 HBasicBlock* parent_loop_header() const { return parent_loop_header_; } |
| 107 if (!HasParentLoopHeader()) return NULL; | 109 |
| 108 return parent_loop_header_.get(); | 110 void set_parent_loop_header(HBasicBlock* block) { |
| 111 ASSERT(parent_loop_header_ == NULL); |
| 112 parent_loop_header_ = block; |
| 109 } | 113 } |
| 110 | 114 |
| 111 void set_parent_loop_header(HBasicBlock* block) { | 115 bool HasParentLoopHeader() const { return parent_loop_header_ != NULL; } |
| 112 parent_loop_header_.set(block); | |
| 113 } | |
| 114 | |
| 115 bool HasParentLoopHeader() const { return parent_loop_header_.is_set(); } | |
| 116 | 116 |
| 117 void SetJoinId(int id); | 117 void SetJoinId(int id); |
| 118 | 118 |
| 119 void Finish(HControlInstruction* last); | 119 void Finish(HControlInstruction* last); |
| 120 void FinishExit(HControlInstruction* instruction); |
| 120 void Goto(HBasicBlock* block, bool include_stack_check = false); | 121 void Goto(HBasicBlock* block, bool include_stack_check = false); |
| 121 | 122 |
| 122 int PredecessorIndexOf(HBasicBlock* predecessor) const; | 123 int PredecessorIndexOf(HBasicBlock* predecessor) const; |
| 123 void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); } | 124 void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); } |
| 124 void AssignCommonDominator(HBasicBlock* other); | 125 void AssignCommonDominator(HBasicBlock* other); |
| 125 | 126 |
| 126 // Add the inlined function exit sequence, adding an HLeaveInlined | 127 // Add the inlined function exit sequence, adding an HLeaveInlined |
| 127 // instruction and updating the bailout environment. | 128 // instruction and updating the bailout environment. |
| 128 void AddLeaveInlined(HValue* return_value, HBasicBlock* target); | 129 void AddLeaveInlined(HValue* return_value, HBasicBlock* target); |
| 129 | 130 |
| 130 // If a target block is tagged as an inline function return, all | 131 // If a target block is tagged as an inline function return, all |
| 131 // predecessors should contain the inlined exit sequence: | 132 // predecessors should contain the inlined exit sequence: |
| 132 // | 133 // |
| 133 // LeaveInlined | 134 // LeaveInlined |
| 134 // Simulate (caller's environment) | 135 // Simulate (caller's environment) |
| 135 // Goto (target block) | 136 // Goto (target block) |
| 136 bool IsInlineReturnTarget() const { return is_inline_return_target_; } | 137 bool IsInlineReturnTarget() const { return is_inline_return_target_; } |
| 137 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; } | 138 void MarkAsInlineReturnTarget() { is_inline_return_target_ = true; } |
| 138 | 139 |
| 139 Handle<Object> cond() { return cond_; } | |
| 140 void set_cond(Handle<Object> value) { cond_ = value; } | |
| 141 | |
| 142 #ifdef DEBUG | 140 #ifdef DEBUG |
| 143 void Verify(); | 141 void Verify(); |
| 144 #endif | 142 #endif |
| 145 | 143 |
| 146 private: | 144 private: |
| 147 void RegisterPredecessor(HBasicBlock* pred); | 145 void RegisterPredecessor(HBasicBlock* pred); |
| 148 void AddDominatedBlock(HBasicBlock* block); | 146 void AddDominatedBlock(HBasicBlock* block); |
| 149 | 147 |
| 150 HSimulate* CreateSimulate(int id); | 148 HSimulate* CreateSimulate(int id); |
| 151 | 149 |
| 152 int block_id_; | 150 int block_id_; |
| 153 HGraph* graph_; | 151 HGraph* graph_; |
| 154 ZoneList<HPhi*> phis_; | 152 ZoneList<HPhi*> phis_; |
| 155 HInstruction* first_; | 153 HInstruction* first_; |
| 156 HInstruction* last_; // Last non-control instruction of the block. | 154 HInstruction* last_; |
| 157 HControlInstruction* end_; | 155 HControlInstruction* end_; |
| 158 HLoopInformation* loop_information_; | 156 HLoopInformation* loop_information_; |
| 159 ZoneList<HBasicBlock*> predecessors_; | 157 ZoneList<HBasicBlock*> predecessors_; |
| 160 HBasicBlock* dominator_; | 158 HBasicBlock* dominator_; |
| 161 ZoneList<HBasicBlock*> dominated_blocks_; | 159 ZoneList<HBasicBlock*> dominated_blocks_; |
| 162 HEnvironment* last_environment_; | 160 HEnvironment* last_environment_; |
| 163 // Outgoing parameter count at block exit, set during lithium translation. | 161 // Outgoing parameter count at block exit, set during lithium translation. |
| 164 int argument_count_; | 162 int argument_count_; |
| 165 // Instruction indices into the lithium code stream. | 163 // Instruction indices into the lithium code stream. |
| 166 int first_instruction_index_; | 164 int first_instruction_index_; |
| 167 int last_instruction_index_; | 165 int last_instruction_index_; |
| 168 ZoneList<int> deleted_phis_; | 166 ZoneList<int> deleted_phis_; |
| 169 SetOncePointer<HBasicBlock> parent_loop_header_; | 167 HBasicBlock* parent_loop_header_; |
| 170 bool is_inline_return_target_; | 168 bool is_inline_return_target_; |
| 171 Handle<Object> cond_; | |
| 172 }; | 169 }; |
| 173 | 170 |
| 174 | 171 |
| 175 class HLoopInformation: public ZoneObject { | 172 class HLoopInformation: public ZoneObject { |
| 176 public: | 173 public: |
| 177 explicit HLoopInformation(HBasicBlock* loop_header) | 174 explicit HLoopInformation(HBasicBlock* loop_header) |
| 178 : back_edges_(4), loop_header_(loop_header), blocks_(8) { | 175 : back_edges_(4), loop_header_(loop_header), blocks_(8) { |
| 179 blocks_.Add(loop_header); | 176 blocks_.Add(loop_header); |
| 180 } | 177 } |
| 181 virtual ~HLoopInformation() {} | 178 virtual ~HLoopInformation() {} |
| (...skipping 11 matching lines...) Expand all Loading... |
| 193 HBasicBlock* loop_header_; | 190 HBasicBlock* loop_header_; |
| 194 ZoneList<HBasicBlock*> blocks_; | 191 ZoneList<HBasicBlock*> blocks_; |
| 195 }; | 192 }; |
| 196 | 193 |
| 197 | 194 |
| 198 class HSubgraph: public ZoneObject { | 195 class HSubgraph: public ZoneObject { |
| 199 public: | 196 public: |
| 200 explicit HSubgraph(HGraph* graph) | 197 explicit HSubgraph(HGraph* graph) |
| 201 : graph_(graph), | 198 : graph_(graph), |
| 202 entry_block_(NULL), | 199 entry_block_(NULL), |
| 203 exit_block_(NULL), | 200 exit_block_(NULL) { |
| 204 break_continue_info_(4) { | |
| 205 } | 201 } |
| 206 | 202 |
| 207 HGraph* graph() const { return graph_; } | 203 HGraph* graph() const { return graph_; } |
| 208 HEnvironment* environment() const { | |
| 209 ASSERT(HasExit()); | |
| 210 return exit_block_->last_environment(); | |
| 211 } | |
| 212 | |
| 213 bool HasExit() const { return exit_block_ != NULL; } | |
| 214 | |
| 215 void PreProcessOsrEntry(IterationStatement* statement); | |
| 216 | |
| 217 void AppendOptional(HSubgraph* graph, | |
| 218 bool on_true_branch, | |
| 219 HValue* boolean_value); | |
| 220 void AppendJoin(HSubgraph* then_graph, HSubgraph* else_graph, AstNode* node); | |
| 221 void AppendWhile(HSubgraph* condition, | |
| 222 HSubgraph* body, | |
| 223 IterationStatement* statement, | |
| 224 HSubgraph* continue_subgraph, | |
| 225 HSubgraph* exit); | |
| 226 void AppendDoWhile(HSubgraph* body, | |
| 227 IterationStatement* statement, | |
| 228 HSubgraph* go_back, | |
| 229 HSubgraph* exit); | |
| 230 void AppendEndless(HSubgraph* body, IterationStatement* statement); | |
| 231 void Append(HSubgraph* next, BreakableStatement* statement); | |
| 232 void ResolveContinue(IterationStatement* statement); | |
| 233 HBasicBlock* BundleBreak(BreakableStatement* statement); | |
| 234 HBasicBlock* BundleContinue(IterationStatement* statement); | |
| 235 HBasicBlock* BundleBreakContinue(BreakableStatement* statement, | |
| 236 bool is_continue, | |
| 237 int join_id); | |
| 238 HBasicBlock* JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id); | |
| 239 | |
| 240 void FinishExit(HControlInstruction* instruction); | |
| 241 void FinishBreakContinue(BreakableStatement* target, bool is_continue); | |
| 242 void Initialize(HBasicBlock* block) { | |
| 243 ASSERT(entry_block_ == NULL); | |
| 244 entry_block_ = block; | |
| 245 exit_block_ = block; | |
| 246 } | |
| 247 HBasicBlock* entry_block() const { return entry_block_; } | 204 HBasicBlock* entry_block() const { return entry_block_; } |
| 248 HBasicBlock* exit_block() const { return exit_block_; } | 205 HBasicBlock* exit_block() const { return exit_block_; } |
| 249 void set_exit_block(HBasicBlock* block) { | 206 void set_exit_block(HBasicBlock* block) { |
| 250 exit_block_ = block; | 207 exit_block_ = block; |
| 251 } | 208 } |
| 252 | 209 |
| 253 void ConnectExitTo(HBasicBlock* other, bool include_stack_check = false) { | 210 void Initialize(HBasicBlock* block) { |
| 254 if (HasExit()) { | 211 ASSERT(entry_block_ == NULL); |
| 255 exit_block()->Goto(other, include_stack_check); | 212 entry_block_ = block; |
| 256 } | 213 exit_block_ = block; |
| 257 } | |
| 258 | |
| 259 void AddBreakContinueInfo(HSubgraph* other) { | |
| 260 break_continue_info_.AddAll(other->break_continue_info_); | |
| 261 } | 214 } |
| 262 | 215 |
| 263 protected: | 216 protected: |
| 264 class BreakContinueInfo: public ZoneObject { | |
| 265 public: | |
| 266 BreakContinueInfo(BreakableStatement* target, HBasicBlock* block, | |
| 267 bool is_continue) | |
| 268 : target_(target), block_(block), continue_(is_continue) {} | |
| 269 BreakableStatement* target() const { return target_; } | |
| 270 HBasicBlock* block() const { return block_; } | |
| 271 bool is_continue() const { return continue_; } | |
| 272 bool IsResolved() const { return block_ == NULL; } | |
| 273 void Resolve() { block_ = NULL; } | |
| 274 | |
| 275 private: | |
| 276 BreakableStatement* target_; | |
| 277 HBasicBlock* block_; | |
| 278 bool continue_; | |
| 279 }; | |
| 280 | |
| 281 const ZoneList<BreakContinueInfo*>* break_continue_info() const { | |
| 282 return &break_continue_info_; | |
| 283 } | |
| 284 | |
| 285 HGraph* graph_; // The graph this is a subgraph of. | 217 HGraph* graph_; // The graph this is a subgraph of. |
| 286 HBasicBlock* entry_block_; | 218 HBasicBlock* entry_block_; |
| 287 HBasicBlock* exit_block_; | 219 HBasicBlock* exit_block_; |
| 288 | |
| 289 private: | |
| 290 ZoneList<BreakContinueInfo*> break_continue_info_; | |
| 291 }; | 220 }; |
| 292 | 221 |
| 293 | 222 |
| 294 class HGraph: public HSubgraph { | 223 class HGraph: public HSubgraph { |
| 295 public: | 224 public: |
| 296 explicit HGraph(CompilationInfo* info); | 225 explicit HGraph(CompilationInfo* info); |
| 297 | 226 |
| 298 CompilationInfo* info() const { return info_; } | 227 CompilationInfo* info() const { return info_; } |
| 299 | 228 |
| 300 bool AllowCodeMotion() const; | 229 bool AllowCodeMotion() const; |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 // control flow. | 547 // control flow. |
| 619 void BuildBranch(HValue* value); | 548 void BuildBranch(HValue* value); |
| 620 | 549 |
| 621 HBasicBlock* if_true_; | 550 HBasicBlock* if_true_; |
| 622 HBasicBlock* if_false_; | 551 HBasicBlock* if_false_; |
| 623 }; | 552 }; |
| 624 | 553 |
| 625 | 554 |
| 626 class HGraphBuilder: public AstVisitor { | 555 class HGraphBuilder: public AstVisitor { |
| 627 public: | 556 public: |
| 557 enum BreakType { BREAK, CONTINUE }; |
| 558 |
| 559 // A class encapsulating (lazily-allocated) break and continue blocks for |
| 560 // a breakable statement. Separated from BreakAndContinueScope so that it |
| 561 // can have a separate lifetime. |
| 562 class BreakAndContinueInfo BASE_EMBEDDED { |
| 563 public: |
| 564 explicit BreakAndContinueInfo(BreakableStatement* target) |
| 565 : target_(target), break_block_(NULL), continue_block_(NULL) { |
| 566 } |
| 567 |
| 568 BreakableStatement* target() { return target_; } |
| 569 HBasicBlock* break_block() { return break_block_; } |
| 570 void set_break_block(HBasicBlock* block) { break_block_ = block; } |
| 571 HBasicBlock* continue_block() { return continue_block_; } |
| 572 void set_continue_block(HBasicBlock* block) { continue_block_ = block; } |
| 573 |
| 574 private: |
| 575 BreakableStatement* target_; |
| 576 HBasicBlock* break_block_; |
| 577 HBasicBlock* continue_block_; |
| 578 }; |
| 579 |
| 580 // A helper class to maintain a stack of current BreakAndContinueInfo |
| 581 // structures mirroring BreakableStatement nesting. |
| 582 class BreakAndContinueScope BASE_EMBEDDED { |
| 583 public: |
| 584 BreakAndContinueScope(BreakAndContinueInfo* info, HGraphBuilder* owner) |
| 585 : info_(info), owner_(owner), next_(owner->break_scope()) { |
| 586 owner->set_break_scope(this); |
| 587 } |
| 588 |
| 589 ~BreakAndContinueScope() { owner_->set_break_scope(next_); } |
| 590 |
| 591 BreakAndContinueInfo* info() { return info_; } |
| 592 HGraphBuilder* owner() { return owner_; } |
| 593 BreakAndContinueScope* next() { return next_; } |
| 594 |
| 595 // Search the break stack for a break or continue target. |
| 596 HBasicBlock* Get(BreakableStatement* stmt, BreakType type); |
| 597 |
| 598 private: |
| 599 BreakAndContinueInfo* info_; |
| 600 HGraphBuilder* owner_; |
| 601 BreakAndContinueScope* next_; |
| 602 }; |
| 603 |
| 628 explicit HGraphBuilder(TypeFeedbackOracle* oracle) | 604 explicit HGraphBuilder(TypeFeedbackOracle* oracle) |
| 629 : oracle_(oracle), | 605 : oracle_(oracle), |
| 630 graph_(NULL), | 606 graph_(NULL), |
| 631 current_subgraph_(NULL), | 607 current_subgraph_(NULL), |
| 632 peeled_statement_(NULL), | |
| 633 ast_context_(NULL), | 608 ast_context_(NULL), |
| 634 call_context_(NULL), | 609 call_context_(NULL), |
| 635 function_return_(NULL), | 610 function_return_(NULL), |
| 636 inlined_count_(0) { } | 611 inlined_count_(0), |
| 612 break_scope_(NULL) { |
| 613 } |
| 637 | 614 |
| 638 HGraph* CreateGraph(CompilationInfo* info); | 615 HGraph* CreateGraph(CompilationInfo* info); |
| 639 | 616 |
| 640 // Simple accessors. | 617 // Simple accessors. |
| 641 HGraph* graph() const { return graph_; } | 618 HGraph* graph() const { return graph_; } |
| 642 HSubgraph* subgraph() const { return current_subgraph_; } | 619 HSubgraph* subgraph() const { return current_subgraph_; } |
| 620 BreakAndContinueScope* break_scope() const { return break_scope_; } |
| 621 void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; } |
| 643 | 622 |
| 644 HEnvironment* environment() const { return subgraph()->environment(); } | 623 HBasicBlock* current_block() const { return subgraph()->exit_block(); } |
| 645 HBasicBlock* CurrentBlock() const { return subgraph()->exit_block(); } | 624 void set_current_block(HBasicBlock* block) { |
| 625 subgraph()->set_exit_block(block); |
| 626 } |
| 627 HEnvironment* environment() const { |
| 628 return current_block()->last_environment(); |
| 629 } |
| 646 | 630 |
| 647 // Adding instructions. | 631 // Adding instructions. |
| 648 HInstruction* AddInstruction(HInstruction* instr); | 632 HInstruction* AddInstruction(HInstruction* instr); |
| 649 void AddSimulate(int id); | 633 void AddSimulate(int id); |
| 650 | 634 |
| 651 // Bailout environment manipulation. | 635 // Bailout environment manipulation. |
| 652 void Push(HValue* value) { environment()->Push(value); } | 636 void Push(HValue* value) { environment()->Push(value); } |
| 653 HValue* Pop() { return environment()->Pop(); } | 637 HValue* Pop() { return environment()->Pop(); } |
| 654 | 638 |
| 655 private: | 639 private: |
| 656 // Type of a member function that generates inline code for a native function. | 640 // Type of a member function that generates inline code for a native function. |
| 657 typedef void (HGraphBuilder::*InlineFunctionGenerator)(int argument_count, | 641 typedef void (HGraphBuilder::*InlineFunctionGenerator)(CallRuntime* call); |
| 658 int ast_id); | |
| 659 | 642 |
| 660 // Forward declarations for inner scope classes. | 643 // Forward declarations for inner scope classes. |
| 661 class SubgraphScope; | 644 class SubgraphScope; |
| 662 | 645 |
| 663 static const InlineFunctionGenerator kInlineFunctionGenerators[]; | 646 static const InlineFunctionGenerator kInlineFunctionGenerators[]; |
| 664 | 647 |
| 665 static const int kMaxCallPolymorphism = 4; | 648 static const int kMaxCallPolymorphism = 4; |
| 666 static const int kMaxLoadPolymorphism = 4; | 649 static const int kMaxLoadPolymorphism = 4; |
| 667 static const int kMaxStorePolymorphism = 4; | 650 static const int kMaxStorePolymorphism = 4; |
| 668 | 651 |
| 669 static const int kMaxInlinedNodes = 196; | 652 static const int kMaxInlinedNodes = 196; |
| 670 static const int kMaxInlinedSize = 196; | 653 static const int kMaxInlinedSize = 196; |
| 671 static const int kMaxSourceSize = 600; | 654 static const int kMaxSourceSize = 600; |
| 672 | 655 |
| 673 // Simple accessors. | 656 // Simple accessors. |
| 674 TypeFeedbackOracle* oracle() const { return oracle_; } | 657 TypeFeedbackOracle* oracle() const { return oracle_; } |
| 675 AstContext* ast_context() const { return ast_context_; } | 658 AstContext* ast_context() const { return ast_context_; } |
| 676 void set_ast_context(AstContext* context) { ast_context_ = context; } | 659 void set_ast_context(AstContext* context) { ast_context_ = context; } |
| 677 AstContext* call_context() const { return call_context_; } | 660 AstContext* call_context() const { return call_context_; } |
| 678 HBasicBlock* function_return() const { return function_return_; } | 661 HBasicBlock* function_return() const { return function_return_; } |
| 679 | 662 |
| 680 // Generators for inline runtime functions. | 663 // Generators for inline runtime functions. |
| 681 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \ | 664 #define INLINE_FUNCTION_GENERATOR_DECLARATION(Name, argc, ressize) \ |
| 682 void Generate##Name(int argument_count, int ast_id); | 665 void Generate##Name(CallRuntime* call); |
| 683 | 666 |
| 684 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 667 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 685 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) | 668 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_DECLARATION) |
| 686 #undef INLINE_FUNCTION_GENERATOR_DECLARATION | 669 #undef INLINE_FUNCTION_GENERATOR_DECLARATION |
| 687 | 670 |
| 688 void Bailout(const char* reason); | 671 void Bailout(const char* reason); |
| 689 | 672 |
| 690 void AppendPeeledWhile(IterationStatement* stmt, | 673 void PreProcessOsrEntry(IterationStatement* statement); |
| 691 HSubgraph* cond_graph, | 674 |
| 692 HSubgraph* body_graph, | 675 HBasicBlock* CreateJoin(HBasicBlock* first, |
| 693 HSubgraph* exit_graph); | 676 HBasicBlock* second, |
| 677 int join_id); |
| 678 |
| 679 // Create a back edge in the flow graph. body_exit is the predecessor |
| 680 // block and loop_entry is the successor block. loop_successor is the |
| 681 // block where control flow exits the loop normally (e.g., via failure of |
| 682 // the condition) and break_block is the block where control flow breaks |
| 683 // from the loop. All blocks except loop_entry can be NULL. The return |
| 684 // value is the new successor block which is the join of loop_successor |
| 685 // and break_block, or NULL. |
| 686 HBasicBlock* CreateLoop(IterationStatement* statement, |
| 687 HBasicBlock* loop_entry, |
| 688 HBasicBlock* body_exit, |
| 689 HBasicBlock* loop_successor, |
| 690 HBasicBlock* break_block); |
| 691 |
| 692 HBasicBlock* JoinContinue(IterationStatement* statement, |
| 693 HBasicBlock* exit_block, |
| 694 HBasicBlock* continue_block); |
| 694 | 695 |
| 695 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); | 696 void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts); |
| 696 void AddToSubgraph(HSubgraph* graph, Statement* stmt); | 697 void AddToSubgraph(HSubgraph* graph, Statement* stmt); |
| 697 void AddToSubgraph(HSubgraph* graph, Expression* expr); | 698 void AddToSubgraph(HSubgraph* graph, Expression* expr); |
| 698 | 699 |
| 699 HValue* Top() const { return environment()->Top(); } | 700 HValue* Top() const { return environment()->Top(); } |
| 700 void Drop(int n) { environment()->Drop(n); } | 701 void Drop(int n) { environment()->Drop(n); } |
| 701 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } | 702 void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); } |
| 702 | 703 |
| 703 void VisitForValue(Expression* expr); | 704 void VisitForValue(Expression* expr); |
| 704 void VisitForEffect(Expression* expr); | 705 void VisitForEffect(Expression* expr); |
| 705 void VisitForControl(Expression* expr, | 706 void VisitForControl(Expression* expr, |
| 706 HBasicBlock* true_block, | 707 HBasicBlock* true_block, |
| 707 HBasicBlock* false_block); | 708 HBasicBlock* false_block); |
| 708 | 709 |
| 709 // Visit an argument and wrap it in a PushArgument instruction. | 710 // Visit an argument subexpression and emit a push to the outgoing |
| 710 HValue* VisitArgument(Expression* expr); | 711 // arguments. |
| 712 void VisitArgument(Expression* expr); |
| 711 void VisitArgumentList(ZoneList<Expression*>* arguments); | 713 void VisitArgumentList(ZoneList<Expression*>* arguments); |
| 712 | 714 |
| 715 // Visit a list of expressions from left to right, each in a value context. |
| 716 void VisitExpressions(ZoneList<Expression*>* exprs); |
| 717 |
| 713 void AddPhi(HPhi* phi); | 718 void AddPhi(HPhi* phi); |
| 714 | 719 |
| 715 void PushAndAdd(HInstruction* instr); | 720 void PushAndAdd(HInstruction* instr); |
| 716 | 721 |
| 717 void PushArgumentsForStubCall(int argument_count); | |
| 718 | |
| 719 // Remove the arguments from the bailout environment and emit instructions | 722 // Remove the arguments from the bailout environment and emit instructions |
| 720 // to push them as outgoing parameters. | 723 // to push them as outgoing parameters. |
| 721 void ProcessCall(HCall* call); | 724 template <int V> HInstruction* PreProcessCall(HCall<V>* call); |
| 722 | 725 |
| 723 void AssumeRepresentation(HValue* value, Representation r); | 726 void AssumeRepresentation(HValue* value, Representation r); |
| 724 static Representation ToRepresentation(TypeInfo info); | 727 static Representation ToRepresentation(TypeInfo info); |
| 725 | 728 |
| 726 void SetupScope(Scope* scope); | 729 void SetupScope(Scope* scope); |
| 727 virtual void VisitStatements(ZoneList<Statement*>* statements); | 730 virtual void VisitStatements(ZoneList<Statement*>* statements); |
| 728 | 731 |
| 729 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); | 732 #define DECLARE_VISIT(type) virtual void Visit##type(type* node); |
| 730 AST_NODE_LIST(DECLARE_VISIT) | 733 AST_NODE_LIST(DECLARE_VISIT) |
| 731 #undef DECLARE_VISIT | 734 #undef DECLARE_VISIT |
| 732 | 735 |
| 733 bool ShouldPeel(HSubgraph* cond, HSubgraph* body); | |
| 734 | |
| 735 HBasicBlock* CreateBasicBlock(HEnvironment* env); | 736 HBasicBlock* CreateBasicBlock(HEnvironment* env); |
| 736 HSubgraph* CreateEmptySubgraph(); | 737 HSubgraph* CreateEmptySubgraph(); |
| 737 HSubgraph* CreateGotoSubgraph(HEnvironment* env); | |
| 738 HSubgraph* CreateBranchSubgraph(HEnvironment* env); | 738 HSubgraph* CreateBranchSubgraph(HEnvironment* env); |
| 739 HSubgraph* CreateLoopHeaderSubgraph(HEnvironment* env); | 739 HBasicBlock* CreateLoopHeaderBlock(); |
| 740 HSubgraph* CreateInlinedSubgraph(HEnvironment* outer, | 740 HSubgraph* CreateInlinedSubgraph(HEnvironment* outer, |
| 741 Handle<JSFunction> target, | 741 Handle<JSFunction> target, |
| 742 FunctionLiteral* function); | 742 FunctionLiteral* function); |
| 743 | 743 |
| 744 // Helpers for flow graph construction. | 744 // Helpers for flow graph construction. |
| 745 void LookupGlobalPropertyCell(Variable* var, | 745 void LookupGlobalPropertyCell(Variable* var, |
| 746 LookupResult* lookup, | 746 LookupResult* lookup, |
| 747 bool is_store); | 747 bool is_store); |
| 748 | 748 |
| 749 bool TryArgumentsAccess(Property* expr); | 749 bool TryArgumentsAccess(Property* expr); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 HInstruction* BuildIncrement(HValue* value, bool increment); | 784 HInstruction* BuildIncrement(HValue* value, bool increment); |
| 785 HLoadNamedField* BuildLoadNamedField(HValue* object, | 785 HLoadNamedField* BuildLoadNamedField(HValue* object, |
| 786 Property* expr, | 786 Property* expr, |
| 787 Handle<Map> type, | 787 Handle<Map> type, |
| 788 LookupResult* result, | 788 LookupResult* result, |
| 789 bool smi_and_map_check); | 789 bool smi_and_map_check); |
| 790 HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr); | 790 HInstruction* BuildLoadNamedGeneric(HValue* object, Property* expr); |
| 791 HInstruction* BuildLoadKeyedFastElement(HValue* object, | 791 HInstruction* BuildLoadKeyedFastElement(HValue* object, |
| 792 HValue* key, | 792 HValue* key, |
| 793 Property* expr); | 793 Property* expr); |
| 794 HInstruction* BuildLoadKeyedPixelArrayElement(HValue* object, |
| 795 HValue* key, |
| 796 Property* expr); |
| 794 HInstruction* BuildLoadKeyedGeneric(HValue* object, | 797 HInstruction* BuildLoadKeyedGeneric(HValue* object, |
| 795 HValue* key); | 798 HValue* key); |
| 796 | 799 |
| 797 HInstruction* BuildLoadNamed(HValue* object, | 800 HInstruction* BuildLoadNamed(HValue* object, |
| 798 Property* prop, | 801 Property* prop, |
| 799 Handle<Map> map, | 802 Handle<Map> map, |
| 800 Handle<String> name); | 803 Handle<String> name); |
| 801 HInstruction* BuildStoreNamed(HValue* object, | 804 HInstruction* BuildStoreNamed(HValue* object, |
| 802 HValue* value, | 805 HValue* value, |
| 803 Expression* expr); | 806 Expression* expr); |
| 804 HInstruction* BuildStoreNamedField(HValue* object, | 807 HInstruction* BuildStoreNamedField(HValue* object, |
| 805 Handle<String> name, | 808 Handle<String> name, |
| 806 HValue* value, | 809 HValue* value, |
| 807 Handle<Map> type, | 810 Handle<Map> type, |
| 808 LookupResult* lookup, | 811 LookupResult* lookup, |
| 809 bool smi_and_map_check); | 812 bool smi_and_map_check); |
| 810 HInstruction* BuildStoreNamedGeneric(HValue* object, | 813 HInstruction* BuildStoreNamedGeneric(HValue* object, |
| 811 Handle<String> name, | 814 Handle<String> name, |
| 812 HValue* value); | 815 HValue* value); |
| 813 HInstruction* BuildStoreKeyedGeneric(HValue* object, | 816 HInstruction* BuildStoreKeyedGeneric(HValue* object, |
| 814 HValue* key, | 817 HValue* key, |
| 815 HValue* value); | 818 HValue* value); |
| 816 | 819 |
| 817 HInstruction* BuildStoreKeyedFastElement(HValue* object, | 820 HInstruction* BuildStoreKeyedFastElement(HValue* object, |
| 818 HValue* key, | 821 HValue* key, |
| 819 HValue* val, | 822 HValue* val, |
| 820 Expression* expr); | 823 Expression* expr); |
| 821 | 824 |
| 825 HInstruction* BuildStoreKeyedPixelArrayElement(HValue* object, |
| 826 HValue* key, |
| 827 HValue* val, |
| 828 Expression* expr); |
| 829 |
| 822 HCompare* BuildSwitchCompare(HSubgraph* subgraph, | 830 HCompare* BuildSwitchCompare(HSubgraph* subgraph, |
| 823 HValue* switch_value, | 831 HValue* switch_value, |
| 824 CaseClause* clause); | 832 CaseClause* clause); |
| 825 | 833 |
| 826 HValue* BuildContextChainWalk(Variable* var); | 834 HValue* BuildContextChainWalk(Variable* var); |
| 827 | 835 |
| 828 void AddCheckConstantFunction(Call* expr, | 836 void AddCheckConstantFunction(Call* expr, |
| 829 HValue* receiver, | 837 HValue* receiver, |
| 830 Handle<Map> receiver_map, | 838 Handle<Map> receiver_map, |
| 831 bool smi_and_map_check); | 839 bool smi_and_map_check); |
| 832 | 840 |
| 833 | 841 |
| 834 HBasicBlock* BuildTypeSwitch(ZoneMapList* maps, | 842 HBasicBlock* BuildTypeSwitch(HValue* receiver, |
| 835 ZoneList<HSubgraph*>* subgraphs, | 843 ZoneMapList* maps, |
| 836 HValue* receiver, | 844 ZoneList<HSubgraph*>* body_graphs, |
| 845 HSubgraph* default_graph, |
| 837 int join_id); | 846 int join_id); |
| 838 | 847 |
| 839 TypeFeedbackOracle* oracle_; | 848 TypeFeedbackOracle* oracle_; |
| 840 HGraph* graph_; | 849 HGraph* graph_; |
| 841 HSubgraph* current_subgraph_; | 850 HSubgraph* current_subgraph_; |
| 842 IterationStatement* peeled_statement_; | |
| 843 // Expression context of the currently visited subexpression. NULL when | 851 // Expression context of the currently visited subexpression. NULL when |
| 844 // visiting statements. | 852 // visiting statements. |
| 845 AstContext* ast_context_; | 853 AstContext* ast_context_; |
| 846 | 854 |
| 847 // During function inlining, expression context of the call being | 855 // During function inlining, expression context of the call being |
| 848 // inlined. NULL when not inlining. | 856 // inlined. NULL when not inlining. |
| 849 AstContext* call_context_; | 857 AstContext* call_context_; |
| 850 | 858 |
| 851 // When inlining a call in an effect or value context, the return | 859 // 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 | 860 // block. NULL otherwise. When inlining a call in a test context, there |
| 853 // are a pair of target blocks in the call context. | 861 // are a pair of target blocks in the call context. |
| 854 HBasicBlock* function_return_; | 862 HBasicBlock* function_return_; |
| 855 | 863 |
| 856 int inlined_count_; | 864 int inlined_count_; |
| 857 | 865 |
| 866 BreakAndContinueScope* break_scope_; |
| 867 |
| 858 friend class AstContext; // Pushes and pops the AST context stack. | 868 friend class AstContext; // Pushes and pops the AST context stack. |
| 859 | 869 |
| 860 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); | 870 DISALLOW_COPY_AND_ASSIGN(HGraphBuilder); |
| 861 }; | 871 }; |
| 862 | 872 |
| 863 | 873 |
| 864 class HValueMap: public ZoneObject { | 874 class HValueMap: public ZoneObject { |
| 865 public: | 875 public: |
| 866 HValueMap() | 876 HValueMap() |
| 867 : array_size_(0), | 877 : array_size_(0), |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 const char* filename_; | 1078 const char* filename_; |
| 1069 HeapStringAllocator string_allocator_; | 1079 HeapStringAllocator string_allocator_; |
| 1070 StringStream trace_; | 1080 StringStream trace_; |
| 1071 int indent_; | 1081 int indent_; |
| 1072 }; | 1082 }; |
| 1073 | 1083 |
| 1074 | 1084 |
| 1075 } } // namespace v8::internal | 1085 } } // namespace v8::internal |
| 1076 | 1086 |
| 1077 #endif // V8_HYDROGEN_H_ | 1087 #endif // V8_HYDROGEN_H_ |
| OLD | NEW |