| 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 |