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