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 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace interpreter { | 9 namespace interpreter { |
10 | 10 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 Handle<BytecodeArray> output = | 103 Handle<BytecodeArray> output = |
104 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, | 104 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, |
105 parameter_count(), constant_pool); | 105 parameter_count(), constant_pool); |
106 bytecode_generated_ = true; | 106 bytecode_generated_ = true; |
107 return output; | 107 return output; |
108 } | 108 } |
109 | 109 |
110 | 110 |
111 template <size_t N> | 111 template <size_t N> |
112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { | 112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
| 113 // Don't output dead code. |
| 114 if (exit_seen_in_block_) return; |
| 115 |
113 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); | 116 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); |
114 last_bytecode_start_ = bytecodes()->size(); | 117 last_bytecode_start_ = bytecodes()->size(); |
115 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 118 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
116 for (int i = 0; i < static_cast<int>(N); i++) { | 119 for (int i = 0; i < static_cast<int>(N); i++) { |
117 DCHECK(OperandIsValid(bytecode, i, operands[i])); | 120 DCHECK(OperandIsValid(bytecode, i, operands[i])); |
118 switch (Bytecodes::GetOperandSize(bytecode, i)) { | 121 switch (Bytecodes::GetOperandSize(bytecode, i)) { |
119 case OperandSize::kNone: | 122 case OperandSize::kNone: |
120 UNREACHABLE(); | 123 UNREACHABLE(); |
121 case OperandSize::kByte: | 124 case OperandSize::kByte: |
122 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 125 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); |
(...skipping 24 matching lines...) Expand all Loading... |
147 } | 150 } |
148 | 151 |
149 | 152 |
150 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | 153 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
151 uint32_t operands[] = {operand0}; | 154 uint32_t operands[] = {operand0}; |
152 Output(bytecode, operands); | 155 Output(bytecode, operands); |
153 } | 156 } |
154 | 157 |
155 | 158 |
156 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 159 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 160 // Don't output dead code. |
| 161 if (exit_seen_in_block_) return; |
| 162 |
157 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 163 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
158 last_bytecode_start_ = bytecodes()->size(); | 164 last_bytecode_start_ = bytecodes()->size(); |
159 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 165 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
160 } | 166 } |
161 | 167 |
162 | 168 |
163 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 169 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
164 Register reg, | 170 Register reg, |
165 Strength strength) { | 171 Strength strength) { |
166 if (is_strong(strength)) { | 172 if (is_strong(strength)) { |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 } | 547 } |
542 | 548 |
543 | 549 |
544 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { | 550 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { |
545 if (label->is_forward_target()) { | 551 if (label->is_forward_target()) { |
546 // An earlier jump instruction refers to this label. Update it's location. | 552 // An earlier jump instruction refers to this label. Update it's location. |
547 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); | 553 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); |
548 // Now treat as if the label will only be back referred to. | 554 // Now treat as if the label will only be back referred to. |
549 } | 555 } |
550 label->bind_to(bytecodes()->size()); | 556 label->bind_to(bytecodes()->size()); |
| 557 LeaveBasicBlock(); |
551 return *this; | 558 return *this; |
552 } | 559 } |
553 | 560 |
554 | 561 |
555 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, | 562 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, |
556 BytecodeLabel* label) { | 563 BytecodeLabel* label) { |
557 DCHECK_EQ(label->is_bound(), false); | 564 DCHECK(!label->is_bound()); |
558 DCHECK_EQ(target.is_bound(), true); | 565 DCHECK(target.is_bound()); |
559 PatchJump(bytecodes()->begin() + target.offset(), | 566 PatchJump(bytecodes()->begin() + target.offset(), |
560 bytecodes()->begin() + label->offset()); | 567 bytecodes()->begin() + label->offset()); |
561 label->bind_to(target.offset()); | 568 label->bind_to(target.offset()); |
| 569 LeaveBasicBlock(); |
562 return *this; | 570 return *this; |
563 } | 571 } |
564 | 572 |
565 | 573 |
566 // static | 574 // static |
567 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( | 575 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( |
568 Bytecode jump_bytecode) { | 576 Bytecode jump_bytecode) { |
569 switch (jump_bytecode) { | 577 switch (jump_bytecode) { |
570 case Bytecode::kJump: | 578 case Bytecode::kJump: |
571 return Bytecode::kJumpConstant; | 579 return Bytecode::kJumpConstant; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 return Bytecode::kJumpIfToBooleanFalse; | 644 return Bytecode::kJumpIfToBooleanFalse; |
637 default: | 645 default: |
638 UNREACHABLE(); | 646 UNREACHABLE(); |
639 } | 647 } |
640 return static_cast<Bytecode>(-1); | 648 return static_cast<Bytecode>(-1); |
641 } | 649 } |
642 | 650 |
643 | 651 |
644 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 652 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
645 BytecodeLabel* label) { | 653 BytecodeLabel* label) { |
| 654 // Don't emit dead code. |
| 655 if (exit_seen_in_block_) return *this; |
| 656 |
646 // Check if the value in accumulator is boolean, if not choose an | 657 // Check if the value in accumulator is boolean, if not choose an |
647 // appropriate JumpIfToBoolean bytecode. | 658 // appropriate JumpIfToBoolean bytecode. |
648 if (NeedToBooleanCast()) { | 659 if (NeedToBooleanCast()) { |
649 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | 660 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
650 } | 661 } |
651 | 662 |
652 int delta; | 663 int delta; |
653 if (label->is_bound()) { | 664 if (label->is_bound()) { |
654 // Label has been bound already so this is a backwards jump. | 665 // Label has been bound already so this is a backwards jump. |
655 CHECK_GE(bytecodes()->size(), label->offset()); | 666 CHECK_GE(bytecodes()->size(), label->offset()); |
(...skipping 11 matching lines...) Expand all Loading... |
667 Output(jump_bytecode, static_cast<uint8_t>(delta)); | 678 Output(jump_bytecode, static_cast<uint8_t>(delta)); |
668 } else { | 679 } else { |
669 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); | 680 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); |
670 if (FitsInIdx8Operand(entry)) { | 681 if (FitsInIdx8Operand(entry)) { |
671 Output(GetJumpWithConstantOperand(jump_bytecode), | 682 Output(GetJumpWithConstantOperand(jump_bytecode), |
672 static_cast<uint8_t>(entry)); | 683 static_cast<uint8_t>(entry)); |
673 } else { | 684 } else { |
674 UNIMPLEMENTED(); | 685 UNIMPLEMENTED(); |
675 } | 686 } |
676 } | 687 } |
| 688 LeaveBasicBlock(); |
677 return *this; | 689 return *this; |
678 } | 690 } |
679 | 691 |
680 | 692 |
681 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { | 693 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { |
682 return OutputJump(Bytecode::kJump, label); | 694 return OutputJump(Bytecode::kJump, label); |
683 } | 695 } |
684 | 696 |
685 | 697 |
686 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { | 698 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 return *this; | 742 return *this; |
731 } | 743 } |
732 | 744 |
733 | 745 |
734 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register for_in_state) { | 746 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register for_in_state) { |
735 Output(Bytecode::kForInDone, for_in_state.ToOperand()); | 747 Output(Bytecode::kForInDone, for_in_state.ToOperand()); |
736 return *this; | 748 return *this; |
737 } | 749 } |
738 | 750 |
739 | 751 |
740 BytecodeArrayBuilder& BytecodeArrayBuilder::EnterBlock() { return *this; } | 752 void BytecodeArrayBuilder::LeaveBasicBlock() { |
741 | |
742 | |
743 BytecodeArrayBuilder& BytecodeArrayBuilder::LeaveBlock() { | |
744 last_block_end_ = bytecodes()->size(); | 753 last_block_end_ = bytecodes()->size(); |
745 exit_seen_in_block_ = false; | 754 exit_seen_in_block_ = false; |
746 return *this; | |
747 } | 755 } |
748 | 756 |
749 | 757 |
750 void BytecodeArrayBuilder::EnsureReturn() { | 758 void BytecodeArrayBuilder::EnsureReturn() { |
751 if (!exit_seen_in_block_) { | 759 if (!exit_seen_in_block_) { |
752 LoadUndefined(); | 760 LoadUndefined(); |
753 Return(); | 761 Return(); |
754 } | 762 } |
755 } | 763 } |
756 | 764 |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 DCHECK_GT(next_consecutive_count_, 0); | 1247 DCHECK_GT(next_consecutive_count_, 0); |
1240 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1248 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
1241 allocated_.push_back(next_consecutive_register_); | 1249 allocated_.push_back(next_consecutive_register_); |
1242 next_consecutive_count_--; | 1250 next_consecutive_count_--; |
1243 return Register(next_consecutive_register_++); | 1251 return Register(next_consecutive_register_++); |
1244 } | 1252 } |
1245 | 1253 |
1246 } // namespace interpreter | 1254 } // namespace interpreter |
1247 } // namespace internal | 1255 } // namespace internal |
1248 } // namespace v8 | 1256 } // namespace v8 |
OLD | NEW |