Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/interpreter/bytecode-flags.h" | 10 #include "src/interpreter/bytecode-flags.h" |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 // Scoped class for enabling 'break' and 'continue' in iteration | 259 // Scoped class for enabling 'break' and 'continue' in iteration |
| 260 // constructs, e.g. do...while, while..., for... | 260 // constructs, e.g. do...while, while..., for... |
| 261 class BytecodeGenerator::ControlScopeForIteration final | 261 class BytecodeGenerator::ControlScopeForIteration final |
| 262 : public BytecodeGenerator::ControlScope { | 262 : public BytecodeGenerator::ControlScope { |
| 263 public: | 263 public: |
| 264 ControlScopeForIteration(BytecodeGenerator* generator, | 264 ControlScopeForIteration(BytecodeGenerator* generator, |
| 265 IterationStatement* statement, | 265 IterationStatement* statement, |
| 266 LoopBuilder* loop_builder) | 266 LoopBuilder* loop_builder) |
| 267 : ControlScope(generator), | 267 : ControlScope(generator), |
| 268 statement_(statement), | 268 statement_(statement), |
| 269 loop_builder_(loop_builder) {} | 269 loop_builder_(loop_builder) { |
| 270 generator->loop_depth_++; // Increment tracked loop depth. | |
| 271 } | |
| 272 ~ControlScopeForIteration() { | |
| 273 generator()->loop_depth_--; // Decrement tracked loop depth. | |
|
rmcilroy
2016/07/26 09:28:52
Not sure the comments are necessary, pretty self e
Michael Starzinger
2016/07/26 09:46:02
Done. I mostly do this to trick clang-format into
| |
| 274 } | |
| 270 | 275 |
| 271 protected: | 276 protected: |
| 272 bool Execute(Command command, Statement* statement) override { | 277 bool Execute(Command command, Statement* statement) override { |
| 273 if (statement != statement_) return false; | 278 if (statement != statement_) return false; |
| 274 switch (command) { | 279 switch (command) { |
| 275 case CMD_BREAK: | 280 case CMD_BREAK: |
| 276 loop_builder_->Break(); | 281 loop_builder_->Break(); |
| 277 return true; | 282 return true; |
| 278 case CMD_CONTINUE: | 283 case CMD_CONTINUE: |
| 279 loop_builder_->Continue(); | 284 loop_builder_->Continue(); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 info->scope()->num_stack_slots(), info->literal(), | 546 info->scope()->num_stack_slots(), info->literal(), |
| 542 info->SourcePositionRecordingMode())), | 547 info->SourcePositionRecordingMode())), |
| 543 info_(info), | 548 info_(info), |
| 544 scope_(info->scope()), | 549 scope_(info->scope()), |
| 545 globals_(0, info->zone()), | 550 globals_(0, info->zone()), |
| 546 execution_control_(nullptr), | 551 execution_control_(nullptr), |
| 547 execution_context_(nullptr), | 552 execution_context_(nullptr), |
| 548 execution_result_(nullptr), | 553 execution_result_(nullptr), |
| 549 register_allocator_(nullptr), | 554 register_allocator_(nullptr), |
| 550 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 555 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
| 551 generator_state_() { | 556 generator_state_(), |
| 557 loop_depth_(0) { | |
| 552 InitializeAstVisitor(isolate()->stack_guard()->real_climit()); | 558 InitializeAstVisitor(isolate()->stack_guard()->real_climit()); |
| 553 } | 559 } |
| 554 | 560 |
| 555 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { | 561 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode() { |
| 556 // Initialize the incoming context. | 562 // Initialize the incoming context. |
| 557 ContextScope incoming_context(this, scope(), false); | 563 ContextScope incoming_context(this, scope(), false); |
| 558 | 564 |
| 559 // Initialize control scope. | 565 // Initialize control scope. |
| 560 ControlScopeForTopLevel control(this); | 566 ControlScopeForTopLevel control(this); |
| 561 | 567 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 663 BuildIndexedJump(generator_state_, first_yield, | 669 BuildIndexedJump(generator_state_, first_yield, |
| 664 stmt->yield_count(), generator_resume_points_); | 670 stmt->yield_count(), generator_resume_points_); |
| 665 builder()->Bind(¬_resuming); | 671 builder()->Bind(¬_resuming); |
| 666 } | 672 } |
| 667 | 673 |
| 668 // Insert an explicit {OsrPoll} right after the loop header, to trigger | 674 // Insert an explicit {OsrPoll} right after the loop header, to trigger |
| 669 // on-stack replacement when armed for the given loop nesting depth. | 675 // on-stack replacement when armed for the given loop nesting depth. |
| 670 if (FLAG_ignition_osr) { | 676 if (FLAG_ignition_osr) { |
| 671 // TODO(4764): Merge this with another bytecode (e.g. {Jump} back edge). | 677 // TODO(4764): Merge this with another bytecode (e.g. {Jump} back edge). |
| 672 // TODO(4764): Investigate interaction with generators. | 678 // TODO(4764): Investigate interaction with generators. |
| 673 // TODO(4764): Track and pass correct loop depth. | |
| 674 DCHECK_EQ(0, stmt->yield_count()); | 679 DCHECK_EQ(0, stmt->yield_count()); |
| 675 builder()->OsrPoll(0); | 680 int level = Min(loop_depth_, AbstractCode::kMaxLoopNestingMarker - 1); |
| 681 builder()->OsrPoll(level); | |
| 676 } | 682 } |
| 677 } | 683 } |
| 678 | 684 |
| 679 void BytecodeGenerator::VisitGeneratorPrologue() { | 685 void BytecodeGenerator::VisitGeneratorPrologue() { |
| 680 // The generator resume trampoline abuses the new.target register both to | 686 // The generator resume trampoline abuses the new.target register both to |
| 681 // indicate that this is a resume call and to pass in the generator object. | 687 // indicate that this is a resume call and to pass in the generator object. |
| 682 // In ordinary calls, new.target is always undefined because generator | 688 // In ordinary calls, new.target is always undefined because generator |
| 683 // functions are non-constructable. | 689 // functions are non-constructable. |
| 684 Register generator_object = Register::new_target(); | 690 Register generator_object = Register::new_target(); |
| 685 BytecodeLabel regular_call; | 691 BytecodeLabel regular_call; |
| (...skipping 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3189 return execution_context()->scope()->language_mode(); | 3195 return execution_context()->scope()->language_mode(); |
| 3190 } | 3196 } |
| 3191 | 3197 |
| 3192 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3198 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 3193 return TypeFeedbackVector::GetIndex(slot); | 3199 return TypeFeedbackVector::GetIndex(slot); |
| 3194 } | 3200 } |
| 3195 | 3201 |
| 3196 } // namespace interpreter | 3202 } // namespace interpreter |
| 3197 } // namespace internal | 3203 } // namespace internal |
| 3198 } // namespace v8 | 3204 } // namespace v8 |
| OLD | NEW |