| 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 static const int kCodeSizeMultiplier = 149; | 92 static const int kCodeSizeMultiplier = 149; |
| 93 #elif V8_TARGET_ARCH_MIPS64 | 93 #elif V8_TARGET_ARCH_MIPS64 |
| 94 static const int kCodeSizeMultiplier = 149; | 94 static const int kCodeSizeMultiplier = 149; |
| 95 #else | 95 #else |
| 96 #error Unsupported target architecture. | 96 #error Unsupported target architecture. |
| 97 #endif | 97 #endif |
| 98 | 98 |
| 99 private: | 99 private: |
| 100 class Breakable; | 100 class Breakable; |
| 101 class Iteration; | 101 class Iteration; |
| 102 class TryFinally; |
| 102 | 103 |
| 103 class TestContext; | 104 class TestContext; |
| 104 | 105 |
| 105 class NestedStatement BASE_EMBEDDED { | 106 class NestedStatement BASE_EMBEDDED { |
| 106 public: | 107 public: |
| 107 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { | 108 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) { |
| 108 // Link into codegen's nesting stack. | 109 // Link into codegen's nesting stack. |
| 109 previous_ = codegen->nesting_stack_; | 110 previous_ = codegen->nesting_stack_; |
| 110 codegen->nesting_stack_ = this; | 111 codegen->nesting_stack_ = this; |
| 111 } | 112 } |
| 112 virtual ~NestedStatement() { | 113 virtual ~NestedStatement() { |
| 113 // Unlink from codegen's nesting stack. | 114 // Unlink from codegen's nesting stack. |
| 114 DCHECK_EQ(this, codegen_->nesting_stack_); | 115 DCHECK_EQ(this, codegen_->nesting_stack_); |
| 115 codegen_->nesting_stack_ = previous_; | 116 codegen_->nesting_stack_ = previous_; |
| 116 } | 117 } |
| 117 | 118 |
| 118 virtual Breakable* AsBreakable() { return NULL; } | 119 virtual Breakable* AsBreakable() { return nullptr; } |
| 119 virtual Iteration* AsIteration() { return NULL; } | 120 virtual Iteration* AsIteration() { return nullptr; } |
| 121 virtual TryFinally* AsTryFinally() { return nullptr; } |
| 120 | 122 |
| 121 virtual bool IsContinueTarget(Statement* target) { return false; } | 123 virtual bool IsContinueTarget(Statement* target) { return false; } |
| 122 virtual bool IsBreakTarget(Statement* target) { return false; } | 124 virtual bool IsBreakTarget(Statement* target) { return false; } |
| 125 virtual bool IsTryFinally() { return false; } |
| 123 | 126 |
| 124 // Notify the statement that we are exiting it via break, continue, or | 127 // Notify the statement that we are exiting it via break, continue, or |
| 125 // return and give it a chance to generate cleanup code. Return the | 128 // return and give it a chance to generate cleanup code. Return the |
| 126 // next outer statement in the nesting stack. We accumulate in | 129 // next outer statement in the nesting stack. We accumulate in |
| 127 // *stack_depth the amount to drop the stack and in *context_length the | 130 // *stack_depth the amount to drop the stack and in *context_length the |
| 128 // number of context chain links to unwind as we traverse the nesting | 131 // number of context chain links to unwind as we traverse the nesting |
| 129 // stack from an exit to its target. | 132 // stack from an exit to its target. |
| 130 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { | 133 virtual NestedStatement* Exit(int* stack_depth, int* context_length) { |
| 131 return previous_; | 134 return previous_; |
| 132 } | 135 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 213 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| 211 *stack_depth += kElementCount; | 214 *stack_depth += kElementCount; |
| 212 return previous_; | 215 return previous_; |
| 213 } | 216 } |
| 214 NestedStatement* AccumulateDepth(int* stack_depth) override { | 217 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 215 *stack_depth += kElementCount; | 218 *stack_depth += kElementCount; |
| 216 return previous_; | 219 return previous_; |
| 217 } | 220 } |
| 218 }; | 221 }; |
| 219 | 222 |
| 223 class DeferredCommands { |
| 224 public: |
| 225 enum Command { kReturn, kThrow, kBreak, kContinue }; |
| 226 typedef int TokenId; |
| 227 struct DeferredCommand { |
| 228 Command command; |
| 229 TokenId token; |
| 230 Statement* target; |
| 231 }; |
| 232 |
| 233 DeferredCommands(FullCodeGenerator* codegen, Label* finally_entry) |
| 234 : codegen_(codegen), |
| 235 commands_(codegen->zone()), |
| 236 return_token_(TokenDispenserForFinally::kInvalidToken), |
| 237 throw_token_(TokenDispenserForFinally::kInvalidToken), |
| 238 finally_entry_(finally_entry) {} |
| 239 |
| 240 void EmitCommands(); |
| 241 |
| 242 void RecordBreak(Statement* target); |
| 243 void RecordContinue(Statement* target); |
| 244 void RecordReturn(); |
| 245 void RecordThrow(); |
| 246 void EmitFallThrough(); |
| 247 |
| 248 private: |
| 249 MacroAssembler* masm() { return codegen_->masm(); } |
| 250 void EmitJumpToFinally(TokenId token); |
| 251 |
| 252 FullCodeGenerator* codegen_; |
| 253 ZoneVector<DeferredCommand> commands_; |
| 254 TokenDispenserForFinally dispenser_; |
| 255 TokenId return_token_; |
| 256 TokenId throw_token_; |
| 257 Label* finally_entry_; |
| 258 }; |
| 259 |
| 220 // The try block of a try/finally statement. | 260 // The try block of a try/finally statement. |
| 221 class TryFinally : public NestedStatement { | 261 class TryFinally : public NestedStatement { |
| 222 public: | 262 public: |
| 223 static const int kElementCount = TryBlockConstant::kElementCount; | 263 static const int kElementCount = TryBlockConstant::kElementCount; |
| 224 | 264 |
| 225 TryFinally(FullCodeGenerator* codegen, Label* finally_entry) | 265 TryFinally(FullCodeGenerator* codegen, DeferredCommands* commands) |
| 226 : NestedStatement(codegen), finally_entry_(finally_entry) { | 266 : NestedStatement(codegen), deferred_commands_(commands) {} |
| 227 } | |
| 228 | 267 |
| 229 NestedStatement* Exit(int* stack_depth, int* context_length) override; | 268 NestedStatement* Exit(int* stack_depth, int* context_length) override; |
| 230 NestedStatement* AccumulateDepth(int* stack_depth) override { | 269 NestedStatement* AccumulateDepth(int* stack_depth) override { |
| 231 *stack_depth += kElementCount; | 270 *stack_depth += kElementCount; |
| 232 return previous_; | 271 return previous_; |
| 233 } | 272 } |
| 234 | 273 |
| 274 bool IsTryFinally() override { return true; } |
| 275 TryFinally* AsTryFinally() override { return this; } |
| 276 |
| 277 DeferredCommands* deferred_commands() { return deferred_commands_; } |
| 278 |
| 235 private: | 279 private: |
| 236 Label* finally_entry_; | 280 DeferredCommands* deferred_commands_; |
| 237 }; | 281 }; |
| 238 | 282 |
| 239 // The finally block of a try/finally statement. | 283 // The finally block of a try/finally statement. |
| 240 class Finally : public NestedStatement { | 284 class Finally : public NestedStatement { |
| 241 public: | 285 public: |
| 242 static const int kElementCount = 3; | 286 static const int kElementCount = 3; |
| 243 | 287 |
| 244 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} | 288 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) {} |
| 245 | 289 |
| 246 NestedStatement* Exit(int* stack_depth, int* context_length) override { | 290 NestedStatement* Exit(int* stack_depth, int* context_length) override { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 void RecordBackEdge(BailoutId osr_ast_id); | 492 void RecordBackEdge(BailoutId osr_ast_id); |
| 449 // Emit a table of back edge ids, pcs and loop depths into the code stream. | 493 // Emit a table of back edge ids, pcs and loop depths into the code stream. |
| 450 // Return the offset of the start of the table. | 494 // Return the offset of the start of the table. |
| 451 unsigned EmitBackEdgeTable(); | 495 unsigned EmitBackEdgeTable(); |
| 452 | 496 |
| 453 void EmitProfilingCounterDecrement(int delta); | 497 void EmitProfilingCounterDecrement(int delta); |
| 454 void EmitProfilingCounterReset(); | 498 void EmitProfilingCounterReset(); |
| 455 | 499 |
| 456 // Emit code to pop values from the stack associated with nested statements | 500 // Emit code to pop values from the stack associated with nested statements |
| 457 // like try/catch, try/finally, etc, running the finallies and unwinding the | 501 // like try/catch, try/finally, etc, running the finallies and unwinding the |
| 458 // handlers as needed. | 502 // handlers as needed. Also emits the return sequence if necessary (i.e., |
| 459 void EmitUnwindBeforeReturn(); | 503 // if the return is not delayed by a finally block). |
| 504 void EmitUnwindAndReturn(); |
| 460 | 505 |
| 461 // Platform-specific return sequence | 506 // Platform-specific return sequence |
| 462 void EmitReturnSequence(); | 507 void EmitReturnSequence(); |
| 463 | 508 |
| 464 // Platform-specific code sequences for calls | 509 // Platform-specific code sequences for calls |
| 465 void EmitCall(Call* expr, ConvertReceiverMode = ConvertReceiverMode::kAny); | 510 void EmitCall(Call* expr, ConvertReceiverMode = ConvertReceiverMode::kAny); |
| 466 void EmitSuperConstructorCall(Call* expr); | 511 void EmitSuperConstructorCall(Call* expr); |
| 467 void EmitCallWithLoadIC(Call* expr); | 512 void EmitCallWithLoadIC(Call* expr); |
| 468 void EmitSuperCallWithLoadIC(Call* expr); | 513 void EmitSuperCallWithLoadIC(Call* expr); |
| 469 void EmitKeyedCallWithLoadIC(Call* expr, Expression* key); | 514 void EmitKeyedCallWithLoadIC(Call* expr, Expression* key); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 SetCallPosition(expr); | 707 SetCallPosition(expr); |
| 663 } | 708 } |
| 664 | 709 |
| 665 // Non-local control flow support. | 710 // Non-local control flow support. |
| 666 void EnterTryBlock(int handler_index, Label* handler); | 711 void EnterTryBlock(int handler_index, Label* handler); |
| 667 void ExitTryBlock(int handler_index); | 712 void ExitTryBlock(int handler_index); |
| 668 void EnterFinallyBlock(); | 713 void EnterFinallyBlock(); |
| 669 void ExitFinallyBlock(); | 714 void ExitFinallyBlock(); |
| 670 void ClearPendingMessage(); | 715 void ClearPendingMessage(); |
| 671 | 716 |
| 717 void EmitContinue(Statement* target); |
| 718 void EmitBreak(Statement* target); |
| 719 |
| 672 // Loop nesting counter. | 720 // Loop nesting counter. |
| 673 int loop_depth() { return loop_depth_; } | 721 int loop_depth() { return loop_depth_; } |
| 674 void increment_loop_depth() { loop_depth_++; } | 722 void increment_loop_depth() { loop_depth_++; } |
| 675 void decrement_loop_depth() { | 723 void decrement_loop_depth() { |
| 676 DCHECK(loop_depth_ > 0); | 724 DCHECK(loop_depth_ > 0); |
| 677 loop_depth_--; | 725 loop_depth_--; |
| 678 } | 726 } |
| 679 | 727 |
| 680 MacroAssembler* masm() const { return masm_; } | 728 MacroAssembler* masm() const { return masm_; } |
| 681 | 729 |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 Address start_; | 1091 Address start_; |
| 1044 Address instruction_start_; | 1092 Address instruction_start_; |
| 1045 uint32_t length_; | 1093 uint32_t length_; |
| 1046 }; | 1094 }; |
| 1047 | 1095 |
| 1048 | 1096 |
| 1049 } // namespace internal | 1097 } // namespace internal |
| 1050 } // namespace v8 | 1098 } // namespace v8 |
| 1051 | 1099 |
| 1052 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ | 1100 #endif // V8_FULL_CODEGEN_FULL_CODEGEN_H_ |
| OLD | NEW |