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 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
7 | 7 |
8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" |
9 #include "src/globals.h" | 9 #include "src/globals.h" |
10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 operand_count_(4), | 184 operand_count_(4), |
185 operand_scale_(OperandScale::kSingle), | 185 operand_scale_(OperandScale::kSingle), |
186 source_info_(source_info) { | 186 source_info_(source_info) { |
187 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); | 187 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); |
188 SetOperand(0, operand0); | 188 SetOperand(0, operand0); |
189 SetOperand(1, operand1); | 189 SetOperand(1, operand1); |
190 SetOperand(2, operand2); | 190 SetOperand(2, operand2); |
191 SetOperand(3, operand3); | 191 SetOperand(3, operand3); |
192 } | 192 } |
193 | 193 |
| 194 #define DEFINE_BYTECODE_NODE_CREATOR(Name, ...) \ |
| 195 template <typename... Operands> \ |
| 196 INLINE(static BytecodeNode Name(BytecodeSourceInfo source_info, \ |
| 197 Operands... operands)) { \ |
| 198 return Create<Bytecode::k##Name, __VA_ARGS__>(source_info, operands...); \ |
| 199 } |
| 200 BYTECODE_LIST(DEFINE_BYTECODE_NODE_CREATOR) |
| 201 #undef DEFINE_BYTECODE_NODE_CREATOR |
| 202 |
194 // Replace the bytecode of this node with |bytecode| and keep the operands. | 203 // Replace the bytecode of this node with |bytecode| and keep the operands. |
195 void replace_bytecode(Bytecode bytecode) { | 204 void replace_bytecode(Bytecode bytecode) { |
196 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), | 205 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), |
197 Bytecodes::NumberOfOperands(bytecode)); | 206 Bytecodes::NumberOfOperands(bytecode)); |
198 bytecode_ = bytecode; | 207 bytecode_ = bytecode; |
199 } | 208 } |
200 | 209 |
201 void set_bytecode(Bytecode bytecode) { | 210 void update_operand0(uint32_t operand0) { SetOperand(0, operand0); } |
202 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | |
203 bytecode_ = bytecode; | |
204 operand_count_ = 0; | |
205 operand_scale_ = OperandScale::kSingle; | |
206 } | |
207 | |
208 void set_bytecode(Bytecode bytecode, uint32_t operand0) { | |
209 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); | |
210 bytecode_ = bytecode; | |
211 operand_count_ = 1; | |
212 operand_scale_ = OperandScale::kSingle; | |
213 SetOperand(0, operand0); | |
214 } | |
215 | |
216 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { | |
217 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); | |
218 bytecode_ = bytecode; | |
219 operand_count_ = 2; | |
220 operand_scale_ = OperandScale::kSingle; | |
221 SetOperand(0, operand0); | |
222 SetOperand(1, operand1); | |
223 } | |
224 | |
225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, | |
226 uint32_t operand2) { | |
227 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); | |
228 bytecode_ = bytecode; | |
229 operand_count_ = 3; | |
230 operand_scale_ = OperandScale::kSingle; | |
231 SetOperand(0, operand0); | |
232 SetOperand(1, operand1); | |
233 SetOperand(2, operand2); | |
234 } | |
235 | 211 |
236 // Print to stream |os|. | 212 // Print to stream |os|. |
237 void Print(std::ostream& os) const; | 213 void Print(std::ostream& os) const; |
238 | 214 |
239 // Transform to a node representing |new_bytecode| which has one | 215 // Transform to a node representing |new_bytecode| which has one |
240 // operand more than the current bytecode. | 216 // operand more than the current bytecode. |
241 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { | 217 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { |
242 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), | 218 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), |
243 Bytecodes::NumberOfOperands(bytecode()) + 1); | 219 Bytecodes::NumberOfOperands(bytecode()) + 1); |
244 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || | 220 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || |
(...skipping 25 matching lines...) Expand all Loading... |
270 | 246 |
271 const BytecodeSourceInfo& source_info() const { return source_info_; } | 247 const BytecodeSourceInfo& source_info() const { return source_info_; } |
272 void set_source_info(BytecodeSourceInfo source_info) { | 248 void set_source_info(BytecodeSourceInfo source_info) { |
273 source_info_ = source_info; | 249 source_info_ = source_info; |
274 } | 250 } |
275 | 251 |
276 bool operator==(const BytecodeNode& other) const; | 252 bool operator==(const BytecodeNode& other) const; |
277 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } | 253 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } |
278 | 254 |
279 private: | 255 private: |
| 256 template <Bytecode bytecode, AccumulatorUse accumulator_use, |
| 257 OperandType... operand_types> |
| 258 friend class BytecodeNodeBuilder; |
| 259 |
| 260 INLINE(BytecodeNode(Bytecode bytecode, int operand_count, |
| 261 OperandScale operand_scale, |
| 262 BytecodeSourceInfo source_info, uint32_t operand0 = 0, |
| 263 uint32_t operand1 = 0, uint32_t operand2 = 0, |
| 264 uint32_t operand3 = 0)) |
| 265 : bytecode_(bytecode), |
| 266 operand_count_(operand_count), |
| 267 operand_scale_(operand_scale), |
| 268 source_info_(source_info) { |
| 269 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); |
| 270 operands_[0] = operand0; |
| 271 operands_[1] = operand1; |
| 272 operands_[2] = operand2; |
| 273 operands_[3] = operand3; |
| 274 } |
| 275 |
| 276 template <Bytecode bytecode, AccumulatorUse accum_use> |
| 277 INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info)) { |
| 278 return BytecodeNode(bytecode, 0, OperandScale::kSingle, source_info); |
| 279 } |
| 280 |
| 281 template <Bytecode bytecode, AccumulatorUse accum_use, |
| 282 OperandType operand0_type> |
| 283 INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info, |
| 284 uint32_t operand0)) { |
| 285 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type); |
| 286 OperandScale scale = OperandScale::kSingle; |
| 287 scale = std::max(scale, ScaleForOperand<operand0_type>(operand0)); |
| 288 return BytecodeNode(bytecode, 1, scale, source_info, operand0); |
| 289 } |
| 290 |
| 291 template <Bytecode bytecode, AccumulatorUse accum_use, |
| 292 OperandType operand0_type, OperandType operand1_type> |
| 293 INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info, |
| 294 uint32_t operand0, uint32_t operand1)) { |
| 295 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type); |
| 296 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type); |
| 297 OperandScale scale = OperandScale::kSingle; |
| 298 scale = std::max(scale, ScaleForOperand<operand0_type>(operand0)); |
| 299 scale = std::max(scale, ScaleForOperand<operand1_type>(operand1)); |
| 300 return BytecodeNode(bytecode, 2, scale, source_info, operand0, operand1); |
| 301 } |
| 302 |
| 303 template <Bytecode bytecode, AccumulatorUse accum_use, |
| 304 OperandType operand0_type, OperandType operand1_type, |
| 305 OperandType operand2_type> |
| 306 INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info, |
| 307 uint32_t operand0, uint32_t operand1, |
| 308 uint32_t operand2)) { |
| 309 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type); |
| 310 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type); |
| 311 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type); |
| 312 OperandScale scale = OperandScale::kSingle; |
| 313 scale = std::max(scale, ScaleForOperand<operand0_type>(operand0)); |
| 314 scale = std::max(scale, ScaleForOperand<operand1_type>(operand1)); |
| 315 scale = std::max(scale, ScaleForOperand<operand2_type>(operand2)); |
| 316 return BytecodeNode(bytecode, 3, scale, source_info, operand0, operand1, |
| 317 operand2); |
| 318 } |
| 319 |
| 320 template <Bytecode bytecode, AccumulatorUse accum_use, |
| 321 OperandType operand0_type, OperandType operand1_type, |
| 322 OperandType operand2_type, OperandType operand3_type> |
| 323 INLINE(static BytecodeNode Create(BytecodeSourceInfo source_info, |
| 324 uint32_t operand0, uint32_t operand1, |
| 325 uint32_t operand2, uint32_t operand3)) { |
| 326 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 0), operand0_type); |
| 327 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 1), operand1_type); |
| 328 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 2), operand2_type); |
| 329 DCHECK_EQ(Bytecodes::GetOperandType(bytecode, 3), operand3_type); |
| 330 OperandScale scale = OperandScale::kSingle; |
| 331 scale = std::max(scale, ScaleForOperand<operand0_type>(operand0)); |
| 332 scale = std::max(scale, ScaleForOperand<operand1_type>(operand1)); |
| 333 scale = std::max(scale, ScaleForOperand<operand2_type>(operand2)); |
| 334 scale = std::max(scale, ScaleForOperand<operand3_type>(operand3)); |
| 335 return BytecodeNode(bytecode, 4, scale, source_info, operand0, operand1, |
| 336 operand2, operand3); |
| 337 } |
| 338 |
| 339 template <OperandType operand_type> |
| 340 INLINE(static OperandScale ScaleForOperand(uint32_t operand)) { |
| 341 if (BytecodeOperands::IsScalableUnsignedByte(operand_type)) { |
| 342 return Bytecodes::ScaleForUnsignedOperand(operand); |
| 343 } else if (BytecodeOperands::IsScalableSignedByte(operand_type)) { |
| 344 return Bytecodes::ScaleForSignedOperand(operand); |
| 345 } else { |
| 346 return OperandScale::kSingle; |
| 347 } |
| 348 } |
| 349 |
280 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { | 350 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { |
281 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { | 351 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { |
282 operand_scale_ = | 352 operand_scale_ = |
283 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); | 353 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); |
284 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), | 354 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), |
285 operand_index)) { | 355 operand_index)) { |
286 operand_scale_ = | 356 operand_scale_ = |
287 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); | 357 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); |
288 } | 358 } |
289 } | 359 } |
(...skipping 13 matching lines...) Expand all Loading... |
303 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 373 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
304 const BytecodeSourceInfo& info); | 374 const BytecodeSourceInfo& info); |
305 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 375 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
306 const BytecodeNode& node); | 376 const BytecodeNode& node); |
307 | 377 |
308 } // namespace interpreter | 378 } // namespace interpreter |
309 } // namespace internal | 379 } // namespace internal |
310 } // namespace v8 | 380 } // namespace v8 |
311 | 381 |
312 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ | 382 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ |
OLD | NEW |