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 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 } | 1048 } |
1049 DCHECK(FitsInIdx8Operand(arg_count)); | 1049 DCHECK(FitsInIdx8Operand(arg_count)); |
1050 Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(), | 1050 Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(), |
1051 static_cast<uint8_t>(arg_count)); | 1051 static_cast<uint8_t>(arg_count)); |
1052 return *this; | 1052 return *this; |
1053 } | 1053 } |
1054 | 1054 |
1055 | 1055 |
1056 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( | 1056 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime( |
1057 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { | 1057 Runtime::FunctionId function_id, Register first_arg, size_t arg_count) { |
| 1058 DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size); |
1058 DCHECK(FitsInIdx16Operand(function_id)); | 1059 DCHECK(FitsInIdx16Operand(function_id)); |
1059 DCHECK(FitsInIdx8Operand(arg_count)); | 1060 DCHECK(FitsInIdx8Operand(arg_count)); |
1060 if (!first_arg.is_valid()) { | 1061 if (!first_arg.is_valid()) { |
1061 DCHECK_EQ(0u, arg_count); | 1062 DCHECK_EQ(0u, arg_count); |
1062 first_arg = Register(0); | 1063 first_arg = Register(0); |
1063 } | 1064 } |
1064 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), | 1065 Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id), |
1065 first_arg.ToOperand(), static_cast<uint8_t>(arg_count)); | 1066 first_arg.ToOperand(), static_cast<uint8_t>(arg_count)); |
1066 return *this; | 1067 return *this; |
1067 } | 1068 } |
1068 | 1069 |
1069 | 1070 |
| 1071 BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair( |
| 1072 Runtime::FunctionId function_id, Register first_arg, size_t arg_count, |
| 1073 Register first_return) { |
| 1074 DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size); |
| 1075 DCHECK(FitsInIdx16Operand(function_id)); |
| 1076 DCHECK(FitsInIdx8Operand(arg_count)); |
| 1077 if (!first_arg.is_valid()) { |
| 1078 DCHECK_EQ(0u, arg_count); |
| 1079 first_arg = Register(0); |
| 1080 } |
| 1081 Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id), |
| 1082 first_arg.ToOperand(), static_cast<uint8_t>(arg_count), |
| 1083 first_return.ToOperand()); |
| 1084 return *this; |
| 1085 } |
| 1086 |
| 1087 |
1070 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, | 1088 BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index, |
1071 Register receiver, | 1089 Register receiver, |
1072 size_t arg_count) { | 1090 size_t arg_count) { |
1073 DCHECK(FitsInIdx16Operand(context_index)); | 1091 DCHECK(FitsInIdx16Operand(context_index)); |
1074 DCHECK(FitsInIdx8Operand(arg_count)); | 1092 DCHECK(FitsInIdx8Operand(arg_count)); |
1075 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), | 1093 Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index), |
1076 receiver.ToOperand(), static_cast<uint8_t>(arg_count)); | 1094 receiver.ToOperand(), static_cast<uint8_t>(arg_count)); |
1077 return *this; | 1095 return *this; |
1078 } | 1096 } |
1079 | 1097 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1189 if (temporary_register_count_ > 0) { | 1207 if (temporary_register_count_ > 0) { |
1190 DCHECK(reg.index() >= first_temporary_register().index() && | 1208 DCHECK(reg.index() >= first_temporary_register().index() && |
1191 reg.index() <= last_temporary_register().index()); | 1209 reg.index() <= last_temporary_register().index()); |
1192 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); | 1210 return free_temporaries_.find(reg.index()) == free_temporaries_.end(); |
1193 } else { | 1211 } else { |
1194 return false; | 1212 return false; |
1195 } | 1213 } |
1196 } | 1214 } |
1197 | 1215 |
1198 | 1216 |
| 1217 bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const { |
| 1218 if (reg.is_function_context() || reg.is_function_closure() || |
| 1219 reg.is_new_target()) { |
| 1220 return true; |
| 1221 } else if (reg.is_parameter()) { |
| 1222 int parameter_index = reg.ToParameterIndex(parameter_count_); |
| 1223 return parameter_index >= 0 && parameter_index < parameter_count_; |
| 1224 } else if (reg.index() < fixed_register_count()) { |
| 1225 return true; |
| 1226 } else { |
| 1227 return TemporaryRegisterIsLive(reg); |
| 1228 } |
| 1229 } |
| 1230 |
| 1231 |
1199 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 1232 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
1200 uint32_t operand_value) const { | 1233 uint32_t operand_value) const { |
1201 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 1234 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
1202 switch (operand_type) { | 1235 switch (operand_type) { |
1203 case OperandType::kNone: | 1236 case OperandType::kNone: |
1204 return false; | 1237 return false; |
1205 case OperandType::kCount16: | 1238 case OperandType::kCount16: |
1206 case OperandType::kIdx16: | 1239 case OperandType::kIdx16: |
1207 return static_cast<uint16_t>(operand_value) == operand_value; | 1240 return static_cast<uint16_t>(operand_value) == operand_value; |
1208 case OperandType::kCount8: | 1241 case OperandType::kCount8: |
1209 case OperandType::kImm8: | 1242 case OperandType::kImm8: |
1210 case OperandType::kIdx8: | 1243 case OperandType::kIdx8: |
1211 return static_cast<uint8_t>(operand_value) == operand_value; | 1244 return static_cast<uint8_t>(operand_value) == operand_value; |
1212 case OperandType::kMaybeReg8: | 1245 case OperandType::kMaybeReg8: |
1213 if (operand_value == 0) { | 1246 if (operand_value == 0) { |
1214 return true; | 1247 return true; |
1215 } | 1248 } |
1216 // Fall-through to kReg8 case. | 1249 // Fall-through to kReg8 case. |
1217 case OperandType::kReg8: { | 1250 case OperandType::kReg8: |
1218 Register reg = Register::FromOperand(static_cast<uint8_t>(operand_value)); | 1251 return RegisterIsValid( |
1219 if (reg.is_function_context() || reg.is_function_closure() || | 1252 Register::FromOperand(static_cast<uint8_t>(operand_value))); |
1220 reg.is_new_target()) { | 1253 case OperandType::kRegPair8: { |
1221 return true; | 1254 Register reg0 = |
1222 } else if (reg.is_parameter()) { | 1255 Register::FromOperand(static_cast<uint8_t>(operand_value)); |
1223 int parameter_index = reg.ToParameterIndex(parameter_count_); | 1256 Register reg1 = Register(reg0.index() + 1); |
1224 return parameter_index >= 0 && parameter_index < parameter_count_; | 1257 return RegisterIsValid(reg0) && RegisterIsValid(reg1); |
1225 } else if (reg.index() < fixed_register_count()) { | |
1226 return true; | |
1227 } else { | |
1228 return TemporaryRegisterIsLive(reg); | |
1229 } | |
1230 } | 1258 } |
1231 case OperandType::kReg16: { | 1259 case OperandType::kReg16: |
1232 if (bytecode != Bytecode::kExchange && | 1260 if (bytecode != Bytecode::kExchange && |
1233 bytecode != Bytecode::kExchangeWide) { | 1261 bytecode != Bytecode::kExchangeWide) { |
1234 return false; | 1262 return false; |
1235 } | 1263 } |
1236 Register reg = | 1264 return RegisterIsValid( |
1237 Register::FromWideOperand(static_cast<uint16_t>(operand_value)); | 1265 Register::FromWideOperand(static_cast<uint16_t>(operand_value))); |
1238 if (reg.is_function_context() || reg.is_function_closure() || | |
1239 reg.is_new_target()) { | |
1240 return false; | |
1241 } else if (reg.is_parameter()) { | |
1242 return false; | |
1243 } else if (reg.index() < fixed_register_count()) { | |
1244 return true; | |
1245 } else { | |
1246 return TemporaryRegisterIsLive(reg); | |
1247 } | |
1248 } | |
1249 } | 1266 } |
1250 UNREACHABLE(); | 1267 UNREACHABLE(); |
1251 return false; | 1268 return false; |
1252 } | 1269 } |
1253 | 1270 |
1254 | 1271 |
1255 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | 1272 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { |
1256 return last_bytecode_start_ < bytecodes()->size() && | 1273 return last_bytecode_start_ < bytecodes()->size() && |
1257 last_bytecode_start_ >= last_block_end_; | 1274 last_bytecode_start_ >= last_block_end_; |
1258 } | 1275 } |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 DCHECK_GT(next_consecutive_count_, 0); | 1663 DCHECK_GT(next_consecutive_count_, 0); |
1647 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1664 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
1648 allocated_.push_back(next_consecutive_register_); | 1665 allocated_.push_back(next_consecutive_register_); |
1649 next_consecutive_count_--; | 1666 next_consecutive_count_--; |
1650 return Register(next_consecutive_register_++); | 1667 return Register(next_consecutive_register_++); |
1651 } | 1668 } |
1652 | 1669 |
1653 } // namespace interpreter | 1670 } // namespace interpreter |
1654 } // namespace internal | 1671 } // namespace internal |
1655 } // namespace v8 | 1672 } // namespace v8 |
OLD | NEW |