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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 | 64 |
65 | 65 |
66 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) | 66 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) |
67 : isolate_(isolate), | 67 : isolate_(isolate), |
68 zone_(zone), | 68 zone_(zone), |
69 bytecodes_(zone), | 69 bytecodes_(zone), |
70 bytecode_generated_(false), | 70 bytecode_generated_(false), |
71 last_block_end_(0), | 71 last_block_end_(0), |
72 last_bytecode_start_(~0), | 72 last_bytecode_start_(~0), |
73 exit_seen_in_block_(false), | 73 exit_seen_in_block_(false), |
| 74 unbound_jumps_(0), |
74 constants_map_(isolate->heap(), zone), | 75 constants_map_(isolate->heap(), zone), |
75 constants_(zone), | 76 constants_(zone), |
76 parameter_count_(-1), | 77 parameter_count_(-1), |
77 local_register_count_(-1), | 78 local_register_count_(-1), |
78 context_register_count_(-1), | 79 context_register_count_(-1), |
79 temporary_register_count_(0), | 80 temporary_register_count_(0), |
80 free_temporaries_(zone) {} | 81 free_temporaries_(zone) {} |
81 | 82 |
82 | 83 |
| 84 BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); } |
| 85 |
| 86 |
83 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { | 87 void BytecodeArrayBuilder::set_locals_count(int number_of_locals) { |
84 local_register_count_ = number_of_locals; | 88 local_register_count_ = number_of_locals; |
85 DCHECK_LE(context_register_count_, 0); | 89 DCHECK_LE(context_register_count_, 0); |
86 } | 90 } |
87 | 91 |
88 | 92 |
89 void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) { | 93 void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) { |
90 parameter_count_ = number_of_parameters; | 94 parameter_count_ = number_of_parameters; |
91 } | 95 } |
92 | 96 |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 // TODO(oth): OutputJump should reserve a constant pool entry | 779 // TODO(oth): OutputJump should reserve a constant pool entry |
776 // when jump is written. The reservation should be used here if | 780 // when jump is written. The reservation should be used here if |
777 // needed, or cancelled if not. This is due to the patch needing | 781 // needed, or cancelled if not. This is due to the patch needing |
778 // to match the size of the code it's replacing. In future, | 782 // to match the size of the code it's replacing. In future, |
779 // there will probably be a jump with 32-bit operand for cases | 783 // there will probably be a jump with 32-bit operand for cases |
780 // when constant pool is full, but that needs to be emitted in | 784 // when constant pool is full, but that needs to be emitted in |
781 // OutputJump too. | 785 // OutputJump too. |
782 UNIMPLEMENTED(); | 786 UNIMPLEMENTED(); |
783 } | 787 } |
784 } | 788 } |
| 789 unbound_jumps_--; |
785 } | 790 } |
786 | 791 |
787 | 792 |
788 // static | 793 // static |
789 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { | 794 Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) { |
790 switch (jump_bytecode) { | 795 switch (jump_bytecode) { |
791 case Bytecode::kJump: | 796 case Bytecode::kJump: |
792 case Bytecode::kJumpIfNull: | 797 case Bytecode::kJumpIfNull: |
793 case Bytecode::kJumpIfUndefined: | 798 case Bytecode::kJumpIfUndefined: |
794 return jump_bytecode; | 799 return jump_bytecode; |
(...skipping 24 matching lines...) Expand all Loading... |
819 // Label has been bound already so this is a backwards jump. | 824 // Label has been bound already so this is a backwards jump. |
820 CHECK_GE(bytecodes()->size(), label->offset()); | 825 CHECK_GE(bytecodes()->size(), label->offset()); |
821 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); | 826 CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt)); |
822 size_t abs_delta = bytecodes()->size() - label->offset(); | 827 size_t abs_delta = bytecodes()->size() - label->offset(); |
823 delta = -static_cast<int>(abs_delta); | 828 delta = -static_cast<int>(abs_delta); |
824 } else { | 829 } else { |
825 // Label has not yet been bound so this is a forward reference | 830 // Label has not yet been bound so this is a forward reference |
826 // that will be patched when the label is bound. | 831 // that will be patched when the label is bound. |
827 label->set_referrer(bytecodes()->size()); | 832 label->set_referrer(bytecodes()->size()); |
828 delta = 0; | 833 delta = 0; |
| 834 unbound_jumps_++; |
829 } | 835 } |
830 | 836 |
831 if (FitsInImm8Operand(delta)) { | 837 if (FitsInImm8Operand(delta)) { |
832 Output(jump_bytecode, static_cast<uint8_t>(delta)); | 838 Output(jump_bytecode, static_cast<uint8_t>(delta)); |
833 } else { | 839 } else { |
834 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); | 840 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); |
835 if (FitsInIdx8Operand(entry)) { | 841 if (FitsInIdx8Operand(entry)) { |
836 Output(GetJumpWithConstantOperand(jump_bytecode), | 842 Output(GetJumpWithConstantOperand(jump_bytecode), |
837 static_cast<uint8_t>(entry)); | 843 static_cast<uint8_t>(entry)); |
838 } else { | 844 } else { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 } | 883 } |
878 | 884 |
879 | 885 |
880 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | 886 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
881 Output(Bytecode::kReturn); | 887 Output(Bytecode::kReturn); |
882 exit_seen_in_block_ = true; | 888 exit_seen_in_block_ = true; |
883 return *this; | 889 return *this; |
884 } | 890 } |
885 | 891 |
886 | 892 |
887 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(Register receiver) { | 893 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( |
888 Output(Bytecode::kForInPrepare, receiver.ToOperand()); | 894 Register cache_type, Register cache_array, Register cache_length) { |
| 895 Output(Bytecode::kForInPrepare, cache_type.ToOperand(), |
| 896 cache_array.ToOperand(), cache_length.ToOperand()); |
889 return *this; | 897 return *this; |
890 } | 898 } |
891 | 899 |
892 | 900 |
893 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(Register for_in_state, | 901 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index, |
894 Register index) { | 902 Register cache_length) { |
895 Output(Bytecode::kForInNext, for_in_state.ToOperand(), index.ToOperand()); | 903 Output(Bytecode::kForInDone, index.ToOperand(), cache_length.ToOperand()); |
896 return *this; | 904 return *this; |
897 } | 905 } |
898 | 906 |
899 | 907 |
900 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register for_in_state) { | 908 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(Register receiver, |
901 Output(Bytecode::kForInDone, for_in_state.ToOperand()); | 909 Register cache_type, |
| 910 Register cache_array, |
| 911 Register index) { |
| 912 Output(Bytecode::kForInNext, receiver.ToOperand(), cache_type.ToOperand(), |
| 913 cache_array.ToOperand(), index.ToOperand()); |
902 return *this; | 914 return *this; |
903 } | 915 } |
904 | 916 |
| 917 |
| 918 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) { |
| 919 Output(Bytecode::kForInStep, index.ToOperand()); |
| 920 return *this; |
| 921 } |
| 922 |
905 | 923 |
906 void BytecodeArrayBuilder::LeaveBasicBlock() { | 924 void BytecodeArrayBuilder::LeaveBasicBlock() { |
907 last_block_end_ = bytecodes()->size(); | 925 last_block_end_ = bytecodes()->size(); |
908 exit_seen_in_block_ = false; | 926 exit_seen_in_block_ = false; |
909 } | 927 } |
910 | 928 |
911 | 929 |
912 void BytecodeArrayBuilder::EnsureReturn() { | 930 void BytecodeArrayBuilder::EnsureReturn() { |
913 if (!exit_seen_in_block_) { | 931 if (!exit_seen_in_block_) { |
914 LoadUndefined(); | 932 LoadUndefined(); |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 DCHECK_GT(next_consecutive_count_, 0); | 1491 DCHECK_GT(next_consecutive_count_, 0); |
1474 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1492 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
1475 allocated_.push_back(next_consecutive_register_); | 1493 allocated_.push_back(next_consecutive_register_); |
1476 next_consecutive_count_--; | 1494 next_consecutive_count_--; |
1477 return Register(next_consecutive_register_++); | 1495 return Register(next_consecutive_register_++); |
1478 } | 1496 } |
1479 | 1497 |
1480 } // namespace interpreter | 1498 } // namespace interpreter |
1481 } // namespace internal | 1499 } // namespace internal |
1482 } // namespace v8 | 1500 } // namespace v8 |
OLD | NEW |