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-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/bytecode-array-writer.h" | 8 #include "src/interpreter/bytecode-array-writer.h" |
9 #include "src/interpreter/bytecode-label.h" | 9 #include "src/interpreter/bytecode-label.h" |
10 #include "src/interpreter/bytecode-peephole-optimizer.h" | 10 #include "src/interpreter/bytecode-peephole-optimizer.h" |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 } // namespace | 92 } // namespace |
93 | 93 |
94 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { | 94 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { |
95 if (latest_source_info_.is_valid()) { | 95 if (latest_source_info_.is_valid()) { |
96 // Statement positions need to be emitted immediately. Expression | 96 // Statement positions need to be emitted immediately. Expression |
97 // positions can be pushed back until a bytecode is found that can | 97 // positions can be pushed back until a bytecode is found that can |
98 // throw. Hence we only invalidate the existing source position | 98 // throw. Hence we only invalidate the existing source position |
99 // information if it is used. | 99 // information if it is used. |
100 if (latest_source_info_.is_statement() || | 100 if (latest_source_info_.is_statement() || |
101 ExpressionPositionIsNeeded(node->bytecode())) { | 101 ExpressionPositionIsNeeded(node->bytecode())) { |
102 node->source_info() = latest_source_info_; | 102 node->source_info().Clone(latest_source_info_); |
103 latest_source_info_.set_invalid(); | 103 latest_source_info_.set_invalid(); |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 108 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
109 uint32_t operand1, uint32_t operand2, | 109 uint32_t operand1, uint32_t operand2, |
110 uint32_t operand3) { | 110 uint32_t operand3) { |
111 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); | 111 DCHECK(OperandsAreValid(bytecode, 4, operand0, operand1, operand2, operand3)); |
112 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); | 112 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3); |
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 return OutputJump(Bytecode::kJumpIfUndefined, label); | 433 return OutputJump(Bytecode::kJumpIfUndefined, label); |
434 } | 434 } |
435 | 435 |
436 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 436 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
437 BytecodeLabel* label) { | 437 BytecodeLabel* label) { |
438 return OutputJump(Bytecode::kJumpIfNotHole, label); | 438 return OutputJump(Bytecode::kJumpIfNotHole, label); |
439 } | 439 } |
440 | 440 |
441 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 441 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
442 if (position != RelocInfo::kNoPosition) { | 442 if (position != RelocInfo::kNoPosition) { |
443 // We need to attach a non-breakable source position to a stack check, | 443 // We need to attach a non-breakable source position to a stack |
444 // so we simply add it as expression position. | 444 // check, so we simply add it as expression position. There can be |
445 latest_source_info_ = {position, false}; | 445 // a prior statement position from constructs like: |
| 446 // |
| 447 // do var x; while (false); |
| 448 // |
| 449 // A Nop could be inserted for empty statements, but since no code |
| 450 // is associated with these positions, instead we force the stack |
| 451 // check's expression position which eliminates the empty |
| 452 // statement's position. |
| 453 latest_source_info_.ForceExpressionPosition(position); |
446 } | 454 } |
447 Output(Bytecode::kStackCheck); | 455 Output(Bytecode::kStackCheck); |
448 return *this; | 456 return *this; |
449 } | 457 } |
450 | 458 |
451 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { | 459 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { |
452 Output(Bytecode::kThrow); | 460 Output(Bytecode::kThrow); |
453 return *this; | 461 return *this; |
454 } | 462 } |
455 | 463 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); | 616 Output(BytecodeForDelete(language_mode), RegisterOperand(object)); |
609 return *this; | 617 return *this; |
610 } | 618 } |
611 | 619 |
612 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 620 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
613 return constant_array_builder()->Insert(object); | 621 return constant_array_builder()->Insert(object); |
614 } | 622 } |
615 | 623 |
616 void BytecodeArrayBuilder::SetReturnPosition() { | 624 void BytecodeArrayBuilder::SetReturnPosition() { |
617 if (return_position_ == RelocInfo::kNoPosition) return; | 625 if (return_position_ == RelocInfo::kNoPosition) return; |
618 latest_source_info_.Update({return_position_, true}); | 626 latest_source_info_.MakeStatementPosition(return_position_); |
619 } | 627 } |
620 | 628 |
621 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 629 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
622 if (stmt->position() == RelocInfo::kNoPosition) return; | 630 if (stmt->position() == RelocInfo::kNoPosition) return; |
623 latest_source_info_.Update({stmt->position(), true}); | 631 latest_source_info_.MakeStatementPosition(stmt->position()); |
624 } | 632 } |
625 | 633 |
626 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 634 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
627 if (expr->position() == RelocInfo::kNoPosition) return; | 635 if (expr->position() == RelocInfo::kNoPosition) return; |
628 if (latest_source_info_.is_expression()) { | 636 if (!latest_source_info_.is_statement()) { |
629 // Ensure the current expression position is overwritten with the | 637 // Ensure the current expression position is overwritten with the |
630 // latest value. | 638 // latest value. |
631 // | 639 latest_source_info_.MakeExpressionPosition(expr->position()); |
632 // TODO(oth): Clean-up BytecodeSourceInfo to have three states and | |
633 // simplify the update logic, taking care to ensure position | |
634 // information is not lost. | |
635 latest_source_info_.set_invalid(); | |
636 } | 640 } |
637 latest_source_info_.Update({expr->position(), false}); | |
638 } | 641 } |
639 | 642 |
640 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | 643 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
641 if (expr->position() == RelocInfo::kNoPosition) return; | 644 if (expr->position() == RelocInfo::kNoPosition) return; |
642 latest_source_info_.Update({expr->position(), true}); | 645 latest_source_info_.MakeStatementPosition(expr->position()); |
643 } | 646 } |
644 | 647 |
645 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 648 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
646 return temporary_register_allocator()->RegisterIsLive(reg); | 649 return temporary_register_allocator()->RegisterIsLive(reg); |
647 } | 650 } |
648 | 651 |
649 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { | 652 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { |
650 if (!reg.is_valid()) { | 653 if (!reg.is_valid()) { |
651 return false; | 654 return false; |
652 } | 655 } |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 return Bytecode::kTailCall; | 920 return Bytecode::kTailCall; |
918 default: | 921 default: |
919 UNREACHABLE(); | 922 UNREACHABLE(); |
920 } | 923 } |
921 return Bytecode::kIllegal; | 924 return Bytecode::kIllegal; |
922 } | 925 } |
923 | 926 |
924 } // namespace interpreter | 927 } // namespace interpreter |
925 } // namespace internal | 928 } // namespace internal |
926 } // namespace v8 | 929 } // namespace v8 |
OLD | NEW |