OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_FULL_CODEGEN_FULL_CODEGEN_H_ | 5 #ifndef V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 6 #define V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/assert-scope.h" | 9 #include "src/assert-scope.h" |
10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 #error Unsupported target architecture. | 75 #error Unsupported target architecture. |
76 #endif | 76 #endif |
77 | 77 |
78 static Register result_register(); | 78 static Register result_register(); |
79 | 79 |
80 private: | 80 private: |
81 typedef Deoptimizer::BailoutState BailoutState; | 81 typedef Deoptimizer::BailoutState BailoutState; |
82 | 82 |
83 class Breakable; | 83 class Breakable; |
84 class Iteration; | 84 class Iteration; |
85 class TryFinally; | |
86 | 85 |
87 class TestContext; | 86 class TestContext; |
88 | 87 |
89 class NestedStatement BASE_EMBEDDED { | 88 class NestedStatement BASE_EMBEDDED { |
90 public: | 89 public: |
91 explicit NestedStatement(FullCodeGenerator* codegen) | 90 explicit NestedStatement(FullCodeGenerator* codegen) |
92 : codegen_(codegen), | 91 : codegen_(codegen), |
93 stack_depth_at_target_(codegen->operand_stack_depth_) { | 92 stack_depth_at_target_(codegen->operand_stack_depth_) { |
94 // Link into codegen's nesting stack. | 93 // Link into codegen's nesting stack. |
95 previous_ = codegen->nesting_stack_; | 94 previous_ = codegen->nesting_stack_; |
96 codegen->nesting_stack_ = this; | 95 codegen->nesting_stack_ = this; |
97 } | 96 } |
98 virtual ~NestedStatement() { | 97 virtual ~NestedStatement() { |
99 // Unlink from codegen's nesting stack. | 98 // Unlink from codegen's nesting stack. |
100 DCHECK_EQ(this, codegen_->nesting_stack_); | 99 DCHECK_EQ(this, codegen_->nesting_stack_); |
101 codegen_->nesting_stack_ = previous_; | 100 codegen_->nesting_stack_ = previous_; |
102 } | 101 } |
103 | 102 |
104 virtual Breakable* AsBreakable() { return nullptr; } | 103 virtual Breakable* AsBreakable() { return nullptr; } |
105 virtual Iteration* AsIteration() { return nullptr; } | 104 virtual Iteration* AsIteration() { return nullptr; } |
106 virtual TryFinally* AsTryFinally() { return nullptr; } | |
107 | 105 |
108 virtual bool IsContinueTarget(Statement* target) { return false; } | 106 virtual bool IsContinueTarget(Statement* target) { return false; } |
109 virtual bool IsBreakTarget(Statement* target) { return false; } | 107 virtual bool IsBreakTarget(Statement* target) { return false; } |
110 virtual bool IsTryFinally() { return false; } | |
111 | 108 |
112 // Notify the statement that we are exiting it via break, continue, or | 109 // Notify the statement that we are exiting it via break, continue, or |
113 // return and give it a chance to generate cleanup code. Return the | 110 // return and give it a chance to generate cleanup code. Return the |
114 // next outer statement in the nesting stack. We accumulate in | 111 // next outer statement in the nesting stack. We accumulate in |
115 // {*context_length} the number of context chain links to unwind as we | 112 // {*context_length} the number of context chain links to unwind as we |
116 // traverse the nesting stack from an exit to its target. | 113 // traverse the nesting stack from an exit to its target. |
117 virtual NestedStatement* Exit(int* context_length) { return previous_; } | 114 virtual NestedStatement* Exit(int* context_length) { return previous_; } |
118 | 115 |
119 // Determine the expected operand stack depth when this statement is being | 116 // Determine the expected operand stack depth when this statement is being |
120 // used as the target of an exit. The caller will drop to this depth. | 117 // used as the target of an exit. The caller will drop to this depth. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 175 |
179 NestedStatement* Exit(int* context_length) override { | 176 NestedStatement* Exit(int* context_length) override { |
180 auto block_scope = statement()->AsBlock()->scope(); | 177 auto block_scope = statement()->AsBlock()->scope(); |
181 if (block_scope != nullptr) { | 178 if (block_scope != nullptr) { |
182 if (block_scope->ContextLocalCount() > 0) ++(*context_length); | 179 if (block_scope->ContextLocalCount() > 0) ++(*context_length); |
183 } | 180 } |
184 return previous_; | 181 return previous_; |
185 } | 182 } |
186 }; | 183 }; |
187 | 184 |
188 class DeferredCommands { | |
189 public: | |
190 enum Command { kReturn, kThrow, kBreak, kContinue }; | |
191 typedef int TokenId; | |
192 struct DeferredCommand { | |
193 Command command; | |
194 TokenId token; | |
195 Statement* target; | |
196 }; | |
197 | |
198 DeferredCommands(FullCodeGenerator* codegen, Label* finally_entry) | |
199 : codegen_(codegen), | |
200 commands_(codegen->zone()), | |
201 return_token_(TokenDispenserForFinally::kInvalidToken), | |
202 throw_token_(TokenDispenserForFinally::kInvalidToken), | |
203 finally_entry_(finally_entry) {} | |
204 | |
205 void EmitCommands(); | |
206 | |
207 void RecordBreak(Statement* target); | |
208 void RecordContinue(Statement* target); | |
209 void RecordReturn(); | |
210 void RecordThrow(); | |
211 void EmitFallThrough(); | |
212 | |
213 private: | |
214 MacroAssembler* masm() { return codegen_->masm(); } | |
215 void EmitJumpToFinally(TokenId token); | |
216 | |
217 FullCodeGenerator* codegen_; | |
218 ZoneVector<DeferredCommand> commands_; | |
219 TokenDispenserForFinally dispenser_; | |
220 TokenId return_token_; | |
221 TokenId throw_token_; | |
222 Label* finally_entry_; | |
223 }; | |
224 | |
225 // The try block of a try/finally statement. | |
226 class TryFinally : public NestedStatement { | |
227 public: | |
228 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) | |
229 : NestedStatement(codegen), deferred_commands_(commands) {} | |
230 | |
231 NestedStatement* Exit(int* context_length) override; | |
232 | |
233 bool IsTryFinally() override { return true; } | |
234 TryFinally* AsTryFinally() override { return this; } | |
235 | |
236 DeferredCommands* deferred_commands() { return deferred_commands_; } | |
237 | |
238 private: | |
239 DeferredCommands* deferred_commands_; | |
240 }; | |
241 | |
242 // The body of a with or catch. | 185 // The body of a with or catch. |
243 class WithOrCatch : public NestedStatement { | 186 class WithOrCatch : public NestedStatement { |
244 public: | 187 public: |
245 explicit WithOrCatch(FullCodeGenerator* codegen) | 188 explicit WithOrCatch(FullCodeGenerator* codegen) |
246 : NestedStatement(codegen) { | 189 : NestedStatement(codegen) { |
247 } | 190 } |
248 | 191 |
249 NestedStatement* Exit(int* context_length) override { | 192 NestedStatement* Exit(int* context_length) override { |
250 ++(*context_length); | 193 ++(*context_length); |
251 return previous_; | 194 return previous_; |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 TailCallMode tail_call_mode = TailCallMode::kDisallow); | 584 TailCallMode tail_call_mode = TailCallMode::kDisallow); |
642 | 585 |
643 void SetConstructCallPosition(Expression* expr) { | 586 void SetConstructCallPosition(Expression* expr) { |
644 // Currently call and construct calls are treated the same wrt debugging. | 587 // Currently call and construct calls are treated the same wrt debugging. |
645 SetCallPosition(expr); | 588 SetCallPosition(expr); |
646 } | 589 } |
647 | 590 |
648 void RecordStatementPosition(int pos); | 591 void RecordStatementPosition(int pos); |
649 void RecordPosition(int pos); | 592 void RecordPosition(int pos); |
650 | 593 |
651 // Non-local control flow support. | 594 // Local control flow support. |
652 void EnterTryBlock(int handler_index, Label* handler, | |
653 HandlerTable::CatchPrediction catch_prediction); | |
654 void ExitTryBlock(int handler_index); | |
655 void EnterFinallyBlock(); | |
656 void ExitFinallyBlock(); | |
657 void ClearPendingMessage(); | |
658 | |
659 void EmitContinue(Statement* target); | 595 void EmitContinue(Statement* target); |
660 void EmitBreak(Statement* target); | 596 void EmitBreak(Statement* target); |
661 | 597 |
662 // Loop nesting counter. | 598 // Loop nesting counter. |
663 int loop_depth() { return loop_depth_; } | 599 int loop_depth() { return loop_depth_; } |
664 void increment_loop_depth() { loop_depth_++; } | 600 void increment_loop_depth() { loop_depth_++; } |
665 void decrement_loop_depth() { | 601 void decrement_loop_depth() { |
666 DCHECK(loop_depth_ > 0); | 602 DCHECK(loop_depth_ > 0); |
667 loop_depth_--; | 603 loop_depth_--; |
668 } | 604 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 | 643 |
708 void VisitComma(BinaryOperation* expr); | 644 void VisitComma(BinaryOperation* expr); |
709 void VisitLogicalExpression(BinaryOperation* expr); | 645 void VisitLogicalExpression(BinaryOperation* expr); |
710 void VisitArithmeticExpression(BinaryOperation* expr); | 646 void VisitArithmeticExpression(BinaryOperation* expr); |
711 | 647 |
712 void VisitForTypeofValue(Expression* expr); | 648 void VisitForTypeofValue(Expression* expr); |
713 | 649 |
714 void Generate(); | 650 void Generate(); |
715 void PopulateDeoptimizationData(Handle<Code> code); | 651 void PopulateDeoptimizationData(Handle<Code> code); |
716 void PopulateTypeFeedbackInfo(Handle<Code> code); | 652 void PopulateTypeFeedbackInfo(Handle<Code> code); |
717 void PopulateHandlerTable(Handle<Code> code); | |
718 | 653 |
719 bool MustCreateObjectLiteralWithRuntime(ObjectLiteral* expr) const; | 654 bool MustCreateObjectLiteralWithRuntime(ObjectLiteral* expr) const; |
720 bool MustCreateArrayLiteralWithRuntime(ArrayLiteral* expr) const; | 655 bool MustCreateArrayLiteralWithRuntime(ArrayLiteral* expr) const; |
721 | 656 |
722 int NewHandlerTableEntry(); | |
723 | |
724 struct BailoutEntry { | 657 struct BailoutEntry { |
725 BailoutId id; | 658 BailoutId id; |
726 unsigned pc_and_state; | 659 unsigned pc_and_state; |
727 }; | 660 }; |
728 | 661 |
729 struct BackEdgeEntry { | 662 struct BackEdgeEntry { |
730 BailoutId id; | 663 BailoutId id; |
731 unsigned pc; | 664 unsigned pc; |
732 uint32_t loop_depth; | 665 uint32_t loop_depth; |
733 }; | 666 }; |
734 | 667 |
735 struct HandlerTableEntry { | |
736 unsigned range_start; | |
737 unsigned range_end; | |
738 unsigned handler_offset; | |
739 int stack_depth; | |
740 HandlerTable::CatchPrediction catch_prediction; | |
741 }; | |
742 | |
743 class ExpressionContext BASE_EMBEDDED { | 668 class ExpressionContext BASE_EMBEDDED { |
744 public: | 669 public: |
745 explicit ExpressionContext(FullCodeGenerator* codegen) | 670 explicit ExpressionContext(FullCodeGenerator* codegen) |
746 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { | 671 : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) { |
747 codegen->set_new_context(this); | 672 codegen->set_new_context(this); |
748 } | 673 } |
749 | 674 |
750 virtual ~ExpressionContext() { | 675 virtual ~ExpressionContext() { |
751 codegen_->set_new_context(old_); | 676 codegen_->set_new_context(old_); |
752 } | 677 } |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 Zone* zone_; | 855 Zone* zone_; |
931 Scope* scope_; | 856 Scope* scope_; |
932 Label return_label_; | 857 Label return_label_; |
933 NestedStatement* nesting_stack_; | 858 NestedStatement* nesting_stack_; |
934 int loop_depth_; | 859 int loop_depth_; |
935 int operand_stack_depth_; | 860 int operand_stack_depth_; |
936 ZoneList<Handle<Object> >* globals_; | 861 ZoneList<Handle<Object> >* globals_; |
937 const ExpressionContext* context_; | 862 const ExpressionContext* context_; |
938 ZoneList<BailoutEntry> bailout_entries_; | 863 ZoneList<BailoutEntry> bailout_entries_; |
939 ZoneList<BackEdgeEntry> back_edges_; | 864 ZoneList<BackEdgeEntry> back_edges_; |
940 ZoneVector<HandlerTableEntry> handler_table_; | |
941 SourcePositionTableBuilder source_position_table_builder_; | 865 SourcePositionTableBuilder source_position_table_builder_; |
942 int ic_total_count_; | 866 int ic_total_count_; |
943 Handle<Cell> profiling_counter_; | 867 Handle<Cell> profiling_counter_; |
944 | 868 |
945 friend class NestedStatement; | 869 friend class NestedStatement; |
946 | 870 |
947 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 871 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
948 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); | 872 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator); |
949 }; | 873 }; |
950 | 874 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 Address start_; | 942 Address start_; |
1019 Address instruction_start_; | 943 Address instruction_start_; |
1020 uint32_t length_; | 944 uint32_t length_; |
1021 }; | 945 }; |
1022 | 946 |
1023 | 947 |
1024 } // namespace internal | 948 } // namespace internal |
1025 } // namespace v8 | 949 } // namespace v8 |
1026 | 950 |
1027 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 951 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
OLD | NEW |