| 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 102 |
| 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 RegisterValidityCheck reg_check) { |
| 113 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); | 114 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); |
| 114 last_bytecode_start_ = bytecodes()->size(); | 115 last_bytecode_start_ = bytecodes()->size(); |
| 115 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 116 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 116 for (int i = 0; i < static_cast<int>(N); i++) { | 117 for (int i = 0; i < static_cast<int>(N); i++) { |
| 117 DCHECK(OperandIsValid(bytecode, i, operands[i])); | 118 DCHECK(OperandIsValid(bytecode, i, operands[i], reg_check)); |
| 118 switch (Bytecodes::GetOperandSize(bytecode, i)) { | 119 switch (Bytecodes::GetOperandSize(bytecode, i)) { |
| 119 case OperandSize::kNone: | 120 case OperandSize::kNone: |
| 120 UNREACHABLE(); | 121 UNREACHABLE(); |
| 121 case OperandSize::kByte: | 122 case OperandSize::kByte: |
| 122 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 123 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); |
| 123 break; | 124 break; |
| 124 case OperandSize::kShort: { | 125 case OperandSize::kShort: { |
| 125 uint8_t operand_bytes[2]; | 126 uint8_t operand_bytes[2]; |
| 126 Bytecodes::ShortOperandToBytes(operands[i], operand_bytes); | 127 Bytecodes::ShortOperandToBytes(operands[i], operand_bytes); |
| 127 bytecodes()->insert(bytecodes()->end(), operand_bytes, | 128 bytecodes()->insert(bytecodes()->end(), operand_bytes, |
| 128 operand_bytes + 2); | 129 operand_bytes + 2); |
| 129 break; | 130 break; |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 } | 134 } |
| 134 | 135 |
| 135 | 136 |
| 136 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 137 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 137 uint32_t operand1, uint32_t operand2) { | 138 uint32_t operand1, uint32_t operand2, |
| 139 RegisterValidityCheck reg_check) { |
| 138 uint32_t operands[] = {operand0, operand1, operand2}; | 140 uint32_t operands[] = {operand0, operand1, operand2}; |
| 139 Output(bytecode, operands); | 141 Output(bytecode, operands, reg_check); |
| 140 } | 142 } |
| 141 | 143 |
| 142 | 144 |
| 143 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, | 145 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 144 uint32_t operand1) { | 146 uint32_t operand1, |
| 147 RegisterValidityCheck reg_check) { |
| 145 uint32_t operands[] = {operand0, operand1}; | 148 uint32_t operands[] = {operand0, operand1}; |
| 146 Output(bytecode, operands); | 149 Output(bytecode, operands, reg_check); |
| 147 } | 150 } |
| 148 | 151 |
| 149 | 152 |
| 150 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | 153 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0, |
| 154 RegisterValidityCheck reg_check) { |
| 151 uint32_t operands[] = {operand0}; | 155 uint32_t operands[] = {operand0}; |
| 152 Output(bytecode, operands); | 156 Output(bytecode, operands, reg_check); |
| 153 } | 157 } |
| 154 | 158 |
| 155 | 159 |
| 156 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 160 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 157 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 161 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
| 158 last_bytecode_start_ = bytecodes()->size(); | 162 last_bytecode_start_ = bytecodes()->size(); |
| 159 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 163 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 160 } | 164 } |
| 161 | 165 |
| 162 | 166 |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 } else { | 768 } else { |
| 765 UNIMPLEMENTED(); | 769 UNIMPLEMENTED(); |
| 766 } | 770 } |
| 767 return *this; | 771 return *this; |
| 768 } | 772 } |
| 769 | 773 |
| 770 | 774 |
| 771 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, | 775 BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor, |
| 772 Register first_arg, | 776 Register first_arg, |
| 773 size_t arg_count) { | 777 size_t arg_count) { |
| 778 RegisterValidityCheck reg_check = RegisterValidityCheck::kCheckRegisters; |
| 779 if (arg_count == 0) { |
| 780 first_arg = Register(0); |
| 781 reg_check = RegisterValidityCheck::kDontCheckRegisters; |
| 782 } |
| 774 DCHECK(FitsInIdx8Operand(arg_count)); | 783 DCHECK(FitsInIdx8Operand(arg_count)); |
| 775 Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(), | 784 Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(), |
| 776 static_cast<uint8_t>(arg_count)); | 785 static_cast<uint8_t>(arg_count), reg_check); |
| 777 return *this; | 786 return *this; |
| 778 } | 787 } |
| 779 | 788 |
| 780 | 789 |
| 781 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 790 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
| 782 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 791 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
| 783 DCHECK(FitsInIdx16Operand(function_id)); | 792 DCHECK(FitsInIdx16Operand(function_id)); |
| 784 DCHECK(FitsInIdx8Operand(arg_count)); | 793 DCHECK(FitsInIdx8Operand(arg_count)); |
| 794 RegisterValidityCheck reg_check = RegisterValidityCheck::kCheckRegisters; |
| 795 if (arg_count == 0) { |
| 796 first_arg = Register(0); |
| 797 reg_check = RegisterValidityCheck::kDontCheckRegisters; |
| 798 } |
| 785 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), | 799 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), |
| 786 first_arg.ToOperand(), static_cast<uint8_t>(arg_count)); | 800 first_arg.ToOperand(), static_cast<uint8_t>(arg_count), reg_check); |
| 787 return *this; | 801 return *this; |
| 788 } | 802 } |
| 789 | 803 |
| 804 |
| 805 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, |
| 806 Register receiver, |
| 807 size_t arg_count) { |
| 808 DCHECK(FitsInIdx16Operand(context_index)); |
| 809 DCHECK(FitsInIdx8Operand(arg_count)); |
| 810 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), |
| 811 receiver.ToOperand(), static_cast<uint8_t>(arg_count)); |
| 812 return *this; |
| 813 } |
| 814 |
| 790 | 815 |
| 791 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, | 816 BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object, |
| 792 LanguageMode language_mode) { | 817 LanguageMode language_mode) { |
| 793 Output(BytecodeForDelete(language_mode), object.ToOperand()); | 818 Output(BytecodeForDelete(language_mode), object.ToOperand()); |
| 794 return *this; | 819 return *this; |
| 795 } | 820 } |
| 796 | 821 |
| 797 | 822 |
| 798 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 823 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| 799 // These constants shouldn't be added to the constant pool, the should use | 824 // These constants shouldn't be added to the constant pool, the should use |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 if (temporary_register_count_ > 0) { | 905 if (temporary_register_count_ > 0) { |
| 881 DCHECK(reg.index() >= first_temporary_register().index() && | 906 DCHECK(reg.index() >= first_temporary_register().index() && |
| 882 reg.index() <= last_temporary_register().index()); | 907 reg.index() <= last_temporary_register().index()); |
| 883 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); | 908 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); |
| 884 } else { | 909 } else { |
| 885 return false; | 910 return false; |
| 886 } | 911 } |
| 887 } | 912 } |
| 888 | 913 |
| 889 | 914 |
| 890 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 915 bool BytecodeArrayBuilder::OperandIsValid( |
| 891 uint32_t operand_value) const { | 916 Bytecode bytecode, int operand_index, uint32_t operand_value, |
| 917 RegisterValidityCheck reg_check) const { |
| 892 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 918 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
| 893 switch (operand_type) { | 919 switch (operand_type) { |
| 894 case OperandType::kNone: | 920 case OperandType::kNone: |
| 895 return false; | 921 return false; |
| 896 case OperandType::kIdx16: | 922 case OperandType::kIdx16: |
| 897 return static_cast<uint16_t>(operand_value) == operand_value; | 923 return static_cast<uint16_t>(operand_value) == operand_value; |
| 898 case OperandType::kCount8: | 924 case OperandType::kCount8: |
| 899 case OperandType::kImm8: | 925 case OperandType::kImm8: |
| 900 case OperandType::kIdx8: | 926 case OperandType::kIdx8: |
| 901 return static_cast<uint8_t>(operand_value) == operand_value; | 927 return static_cast<uint8_t>(operand_value) == operand_value; |
| 902 case OperandType::kReg8: { | 928 case OperandType::kReg8: { |
| 903 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); | 929 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); |
| 904 if (reg.is_function_context() || reg.is_function_closure()) { | 930 if (reg_check == RegisterValidityCheck::kDontCheckRegisters) { |
| 931 return true; |
| 932 } else if (reg.is_function_context() || reg.is_function_closure()) { |
| 905 return true; | 933 return true; |
| 906 } else if (reg.is_parameter()) { | 934 } else if (reg.is_parameter()) { |
| 907 int parameter_index = reg.ToParameterIndex(parameter_count_); | 935 int parameter_index = reg.ToParameterIndex(parameter_count_); |
| 908 return parameter_index >= 0 && parameter_index < parameter_count_; | 936 return parameter_index >= 0 && parameter_index < parameter_count_; |
| 909 } else if (reg.index() < fixed_register_count()) { | 937 } else if (reg.index() < fixed_register_count()) { |
| 910 return true; | 938 return true; |
| 911 } else { | 939 } else { |
| 912 return TemporaryRegisterIsLive(reg); | 940 return TemporaryRegisterIsLive(reg); |
| 913 } | 941 } |
| 914 } | 942 } |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 DCHECK_GT(next_consecutive_count_, 0); | 1267 DCHECK_GT(next_consecutive_count_, 0); |
| 1240 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1268 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
| 1241 allocated_.push_back(next_consecutive_register_); | 1269 allocated_.push_back(next_consecutive_register_); |
| 1242 next_consecutive_count_--; | 1270 next_consecutive_count_--; |
| 1243 return Register(next_consecutive_register_++); | 1271 return Register(next_consecutive_register_++); |
| 1244 } | 1272 } |
| 1245 | 1273 |
| 1246 } // namespace interpreter | 1274 } // namespace interpreter |
| 1247 } // namespace internal | 1275 } // namespace internal |
| 1248 } // namespace v8 | 1276 } // namespace v8 |
| OLD | NEW |