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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 72 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
73 DCHECK(return_seen_in_block_); | 73 DCHECK(return_seen_in_block_); |
74 DCHECK(!bytecode_generated_); | 74 DCHECK(!bytecode_generated_); |
75 bytecode_generated_ = true; | 75 bytecode_generated_ = true; |
76 | 76 |
77 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 77 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
78 return pipeline_->ToBytecodeArray(fixed_register_count(), parameter_count(), | 78 return pipeline_->ToBytecodeArray(fixed_register_count(), parameter_count(), |
79 handler_table); | 79 handler_table); |
80 } | 80 } |
81 | 81 |
| 82 namespace { |
| 83 |
| 84 static bool ExpressionPositionIsNeeded(Bytecode bytecode) { |
| 85 // An expression position is always needed if filtering is turned |
| 86 // off. Otherwise an expression is only needed if the bytecode has |
| 87 // external side effects. |
| 88 return !FLAG_ignition_filter_expression_positions || |
| 89 !Bytecodes::IsWithoutExternalSideEffects(bytecode); |
| 90 } |
| 91 |
| 92 } // namespace |
| 93 |
82 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { | 94 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { |
83 if (latest_source_info_.is_valid()) { | 95 if (latest_source_info_.is_valid()) { |
84 node->source_info().Update(latest_source_info_); | 96 // Statement positions need to be emitted immediately. Expression |
85 latest_source_info_.set_invalid(); | 97 // positions can be pushed back until a bytecode is found that can |
| 98 // throw. Hence we only invalidate the existing source position |
| 99 // information if it is used. |
| 100 if (latest_source_info_.is_statement() || |
| 101 ExpressionPositionIsNeeded(node->bytecode())) { |
| 102 node->source_info() = latest_source_info_; |
| 103 latest_source_info_.set_invalid(); |
| 104 } |
86 } | 105 } |
87 } | 106 } |
88 | 107 |
89 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 108 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
90 BytecodeNode node(bytecode); | 109 BytecodeNode node(bytecode); |
91 AttachSourceInfo(&node); | 110 AttachSourceInfo(&node); |
92 pipeline()->Write(&node); | 111 pipeline()->Write(&node); |
93 } | 112 } |
94 | 113 |
95 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, | 114 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 | 512 |
494 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( | 513 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( |
495 BytecodeLabel* label) { | 514 BytecodeLabel* label) { |
496 return OutputJump(Bytecode::kJumpIfNotHole, label); | 515 return OutputJump(Bytecode::kJumpIfNotHole, label); |
497 } | 516 } |
498 | 517 |
499 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { | 518 BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) { |
500 if (position != RelocInfo::kNoPosition) { | 519 if (position != RelocInfo::kNoPosition) { |
501 // We need to attach a non-breakable source position to a stack check, | 520 // We need to attach a non-breakable source position to a stack check, |
502 // so we simply add it as expression position. | 521 // so we simply add it as expression position. |
503 latest_source_info_.Update({position, false}); | 522 latest_source_info_ = {position, false}; |
504 } | 523 } |
505 Output(Bytecode::kStackCheck); | 524 Output(Bytecode::kStackCheck); |
506 return *this; | 525 return *this; |
507 } | 526 } |
508 | 527 |
509 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { | 528 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { |
510 Output(Bytecode::kThrow); | 529 Output(Bytecode::kThrow); |
511 return *this; | 530 return *this; |
512 } | 531 } |
513 | 532 |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 latest_source_info_.Update({return_position_, true}); | 734 latest_source_info_.Update({return_position_, true}); |
716 } | 735 } |
717 | 736 |
718 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 737 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
719 if (stmt->position() == RelocInfo::kNoPosition) return; | 738 if (stmt->position() == RelocInfo::kNoPosition) return; |
720 latest_source_info_.Update({stmt->position(), true}); | 739 latest_source_info_.Update({stmt->position(), true}); |
721 } | 740 } |
722 | 741 |
723 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 742 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
724 if (expr->position() == RelocInfo::kNoPosition) return; | 743 if (expr->position() == RelocInfo::kNoPosition) return; |
| 744 if (latest_source_info_.is_expression()) { |
| 745 // Ensure the current expression position is overwritten with the |
| 746 // latest value. |
| 747 // |
| 748 // TODO(oth): Clean-up BytecodeSourceInfo to have three states and |
| 749 // simplify the update logic, taking care to ensure position |
| 750 // information is not lost. |
| 751 latest_source_info_.set_invalid(); |
| 752 } |
725 latest_source_info_.Update({expr->position(), false}); | 753 latest_source_info_.Update({expr->position(), false}); |
726 } | 754 } |
727 | 755 |
728 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { | 756 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { |
729 if (expr->position() == RelocInfo::kNoPosition) return; | 757 if (expr->position() == RelocInfo::kNoPosition) return; |
730 latest_source_info_.Update({expr->position(), true}); | 758 latest_source_info_.Update({expr->position(), true}); |
731 } | 759 } |
732 | 760 |
733 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 761 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
734 return temporary_register_allocator()->RegisterIsLive(reg); | 762 return temporary_register_allocator()->RegisterIsLive(reg); |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1018 } | 1046 } |
1019 | 1047 |
1020 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { | 1048 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { |
1021 DCHECK_LE(value, kMaxUInt32); | 1049 DCHECK_LE(value, kMaxUInt32); |
1022 return static_cast<uint32_t>(value); | 1050 return static_cast<uint32_t>(value); |
1023 } | 1051 } |
1024 | 1052 |
1025 } // namespace interpreter | 1053 } // namespace interpreter |
1026 } // namespace internal | 1054 } // namespace internal |
1027 } // namespace v8 | 1055 } // namespace v8 |
OLD | NEW |