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 |