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_BYTECODES_H_ | 5 #ifndef V8_INTERPRETER_BYTECODES_H_ |
6 #define V8_INTERPRETER_BYTECODES_H_ | 6 #define V8_INTERPRETER_BYTECODES_H_ |
7 | 7 |
| 8 #include <cstdint> |
8 #include <iosfwd> | 9 #include <iosfwd> |
| 10 #include <string> |
9 | 11 |
10 // Clients of this interface shouldn't depend on lots of interpreter internals. | 12 // This interface and it's implementation are independent of the |
11 // Do not include anything from src/interpreter here! | 13 // libv8_base library as they are used by the interpreter and the |
12 #include "src/frames.h" | 14 // standalone mkpeephole table generator program. |
13 #include "src/utils.h" | |
14 | 15 |
15 namespace v8 { | 16 namespace v8 { |
16 namespace internal { | 17 namespace internal { |
17 namespace interpreter { | 18 namespace interpreter { |
18 | 19 |
19 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) | 20 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) |
20 | 21 |
21 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ | 22 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ |
22 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \ | 23 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \ |
23 V(Reg, OperandTypeInfo::kScalableSignedByte) \ | 24 V(Reg, OperandTypeInfo::kScalableSignedByte) \ |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 /* eliminated bytecodes). */ \ | 280 /* eliminated bytecodes). */ \ |
280 V(Nop, AccumulatorUse::kNone) | 281 V(Nop, AccumulatorUse::kNone) |
281 | 282 |
282 enum class AccumulatorUse : uint8_t { | 283 enum class AccumulatorUse : uint8_t { |
283 kNone = 0, | 284 kNone = 0, |
284 kRead = 1 << 0, | 285 kRead = 1 << 0, |
285 kWrite = 1 << 1, | 286 kWrite = 1 << 1, |
286 kReadWrite = kRead | kWrite | 287 kReadWrite = kRead | kWrite |
287 }; | 288 }; |
288 | 289 |
289 V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { | 290 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { |
290 int result = static_cast<int>(lhs) & static_cast<int>(rhs); | 291 int result = static_cast<int>(lhs) & static_cast<int>(rhs); |
291 return static_cast<AccumulatorUse>(result); | 292 return static_cast<AccumulatorUse>(result); |
292 } | 293 } |
293 | 294 |
294 V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { | 295 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { |
295 int result = static_cast<int>(lhs) | static_cast<int>(rhs); | 296 int result = static_cast<int>(lhs) | static_cast<int>(rhs); |
296 return static_cast<AccumulatorUse>(result); | 297 return static_cast<AccumulatorUse>(result); |
297 } | 298 } |
298 | 299 |
299 // Enumeration of scaling factors applicable to scalable operands. Code | 300 // Enumeration of scaling factors applicable to scalable operands. Code |
300 // relies on being able to cast values to integer scaling values. | 301 // relies on being able to cast values to integer scaling values. |
301 #define OPERAND_SCALE_LIST(V) \ | 302 #define OPERAND_SCALE_LIST(V) \ |
302 V(Single, 1) \ | 303 V(Single, 1) \ |
303 V(Double, 2) \ | 304 V(Double, 2) \ |
304 V(Quadruple, 4) | 305 V(Quadruple, 4) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 #define DECLARE_OPERAND_TYPE(Name, _) k##Name, | 342 #define DECLARE_OPERAND_TYPE(Name, _) k##Name, |
342 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) | 343 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) |
343 #undef DECLARE_OPERAND_TYPE | 344 #undef DECLARE_OPERAND_TYPE |
344 #define COUNT_OPERAND_TYPES(x, _) +1 | 345 #define COUNT_OPERAND_TYPES(x, _) +1 |
345 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will | 346 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will |
346 // evaluate to the same value as the last operand. | 347 // evaluate to the same value as the last operand. |
347 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) | 348 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) |
348 #undef COUNT_OPERAND_TYPES | 349 #undef COUNT_OPERAND_TYPES |
349 }; | 350 }; |
350 | 351 |
351 | |
352 // Enumeration of interpreter bytecodes. | 352 // Enumeration of interpreter bytecodes. |
353 enum class Bytecode : uint8_t { | 353 enum class Bytecode : uint8_t { |
354 #define DECLARE_BYTECODE(Name, ...) k##Name, | 354 #define DECLARE_BYTECODE(Name, ...) k##Name, |
355 BYTECODE_LIST(DECLARE_BYTECODE) | 355 BYTECODE_LIST(DECLARE_BYTECODE) |
356 #undef DECLARE_BYTECODE | 356 #undef DECLARE_BYTECODE |
357 #define COUNT_BYTECODE(x, ...) +1 | 357 #define COUNT_BYTECODE(x, ...) +1 |
358 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will | 358 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will |
359 // evaluate to the same value as the last real bytecode. | 359 // evaluate to the same value as the last real bytecode. |
360 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) | 360 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) |
361 #undef COUNT_BYTECODE | 361 #undef COUNT_BYTECODE |
362 }; | 362 }; |
363 | 363 |
364 | 364 class Bytecodes final { |
365 // An interpreter Register which is located in the function's Register file | |
366 // in its stack-frame. Register hold parameters, this, and expression values. | |
367 class Register final { | |
368 public: | |
369 explicit Register(int index = kInvalidIndex) : index_(index) {} | |
370 | |
371 int index() const { return index_; } | |
372 bool is_parameter() const { return index() < 0; } | |
373 bool is_valid() const { return index_ != kInvalidIndex; } | |
374 | |
375 static Register FromParameterIndex(int index, int parameter_count); | |
376 int ToParameterIndex(int parameter_count) const; | |
377 | |
378 // Returns an invalid register. | |
379 static Register invalid_value() { return Register(); } | |
380 | |
381 // Returns the register for the function's closure object. | |
382 static Register function_closure(); | |
383 bool is_function_closure() const; | |
384 | |
385 // Returns the register which holds the current context object. | |
386 static Register current_context(); | |
387 bool is_current_context() const; | |
388 | |
389 // Returns the register for the incoming new target value. | |
390 static Register new_target(); | |
391 bool is_new_target() const; | |
392 | |
393 // Returns the register for the bytecode array. | |
394 static Register bytecode_array(); | |
395 bool is_bytecode_array() const; | |
396 | |
397 // Returns the register for the saved bytecode offset. | |
398 static Register bytecode_offset(); | |
399 bool is_bytecode_offset() const; | |
400 | |
401 // Returns a register that can be used to represent the accumulator | |
402 // within code in the interpreter, but should never be emitted in | |
403 // bytecode. | |
404 static Register virtual_accumulator(); | |
405 | |
406 OperandSize SizeOfOperand() const; | |
407 | |
408 int32_t ToOperand() const { return kRegisterFileStartOffset - index_; } | |
409 static Register FromOperand(int32_t operand) { | |
410 return Register(kRegisterFileStartOffset - operand); | |
411 } | |
412 | |
413 static bool AreContiguous(Register reg1, Register reg2, | |
414 Register reg3 = Register(), | |
415 Register reg4 = Register(), | |
416 Register reg5 = Register()); | |
417 | |
418 std::string ToString(int parameter_count); | |
419 | |
420 bool operator==(const Register& other) const { | |
421 return index() == other.index(); | |
422 } | |
423 bool operator!=(const Register& other) const { | |
424 return index() != other.index(); | |
425 } | |
426 bool operator<(const Register& other) const { | |
427 return index() < other.index(); | |
428 } | |
429 bool operator<=(const Register& other) const { | |
430 return index() <= other.index(); | |
431 } | |
432 bool operator>(const Register& other) const { | |
433 return index() > other.index(); | |
434 } | |
435 bool operator>=(const Register& other) const { | |
436 return index() >= other.index(); | |
437 } | |
438 | |
439 private: | |
440 static const int kInvalidIndex = kMaxInt; | |
441 static const int kRegisterFileStartOffset = | |
442 InterpreterFrameConstants::kRegisterFileFromFp / kPointerSize; | |
443 | |
444 void* operator new(size_t size); | |
445 void operator delete(void* p); | |
446 | |
447 int index_; | |
448 }; | |
449 | |
450 | |
451 class Bytecodes { | |
452 public: | 365 public: |
453 // The maximum number of operands a bytecode may have. | 366 // The maximum number of operands a bytecode may have. |
454 static const int kMaxOperands = 4; | 367 static const int kMaxOperands = 4; |
455 | 368 |
456 // Returns string representation of |bytecode|. | 369 // Returns string representation of |bytecode|. |
457 static const char* ToString(Bytecode bytecode); | 370 static const char* ToString(Bytecode bytecode); |
458 | 371 |
459 // Returns string representation of |bytecode|. | 372 // Returns string representation of |bytecode|. |
460 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); | 373 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); |
461 | 374 |
462 // Returns string representation of |accumulator_use|. | 375 // Returns string representation of |accumulator_use|. |
463 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use); | 376 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use); |
464 | 377 |
465 // Returns string representation of |operand_type|. | 378 // Returns string representation of |operand_type|. |
466 static const char* OperandTypeToString(OperandType operand_type); | 379 static const char* OperandTypeToString(OperandType operand_type); |
467 | 380 |
468 // Returns string representation of |operand_scale|. | 381 // Returns string representation of |operand_scale|. |
469 static const char* OperandScaleToString(OperandScale operand_scale); | 382 static const char* OperandScaleToString(OperandScale operand_scale); |
470 | 383 |
471 // Returns string representation of |operand_size|. | 384 // Returns string representation of |operand_size|. |
472 static const char* OperandSizeToString(OperandSize operand_size); | 385 static const char* OperandSizeToString(OperandSize operand_size); |
473 | 386 |
474 // Returns byte value of bytecode. | 387 // Returns byte value of bytecode. |
475 static uint8_t ToByte(Bytecode bytecode) { | 388 static uint8_t ToByte(Bytecode bytecode); |
476 DCHECK_LE(bytecode, Bytecode::kLast); | |
477 return static_cast<uint8_t>(bytecode); | |
478 } | |
479 | 389 |
480 // Returns bytecode for |value|. | 390 // Returns bytecode for |value|. |
481 static Bytecode FromByte(uint8_t value); | 391 static Bytecode FromByte(uint8_t value); |
482 | 392 |
483 // Returns the number of operands expected by |bytecode|. | 393 // Returns the number of operands expected by |bytecode|. |
484 static int NumberOfOperands(Bytecode bytecode); | 394 static int NumberOfOperands(Bytecode bytecode); |
485 | 395 |
486 // Returns the number of register operands expected by |bytecode|. | 396 // Returns the number of register operands expected by |bytecode|. |
487 static int NumberOfRegisterOperands(Bytecode bytecode); | 397 static int NumberOfRegisterOperands(Bytecode bytecode); |
488 | 398 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 // Returns true if |operand_type| is a maybe register operand | 539 // Returns true if |operand_type| is a maybe register operand |
630 // (kMaybeReg). | 540 // (kMaybeReg). |
631 static bool IsMaybeRegisterOperandType(OperandType operand_type); | 541 static bool IsMaybeRegisterOperandType(OperandType operand_type); |
632 | 542 |
633 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). | 543 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). |
634 static bool IsRuntimeIdOperandType(OperandType operand_type); | 544 static bool IsRuntimeIdOperandType(OperandType operand_type); |
635 | 545 |
636 // Returns true if |operand_type| is unsigned, false if signed. | 546 // Returns true if |operand_type| is unsigned, false if signed. |
637 static bool IsUnsignedOperandType(OperandType operand_type); | 547 static bool IsUnsignedOperandType(OperandType operand_type); |
638 | 548 |
639 // Decodes a register operand in a byte array. | |
640 static Register DecodeRegisterOperand(const uint8_t* operand_start, | |
641 OperandType operand_type, | |
642 OperandScale operand_scale); | |
643 | |
644 // Decodes a signed operand in a byte array. | |
645 static int32_t DecodeSignedOperand(const uint8_t* operand_start, | |
646 OperandType operand_type, | |
647 OperandScale operand_scale); | |
648 | |
649 // Decodes an unsigned operand in a byte array. | |
650 static uint32_t DecodeUnsignedOperand(const uint8_t* operand_start, | |
651 OperandType operand_type, | |
652 OperandScale operand_scale); | |
653 | |
654 // Decode a single bytecode and operands to |os|. | |
655 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start, | |
656 int number_of_parameters); | |
657 | |
658 // Returns true if a handler is generated for a bytecode at a given | 549 // Returns true if a handler is generated for a bytecode at a given |
659 // operand scale. All bytecodes have handlers at OperandScale::kSingle, | 550 // operand scale. All bytecodes have handlers at OperandScale::kSingle, |
660 // but only bytecodes with scalable operands have handlers with larger | 551 // but only bytecodes with scalable operands have handlers with larger |
661 // OperandScale values. | 552 // OperandScale values. |
662 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); | 553 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); |
663 | 554 |
664 // Return the operand size required to hold a signed operand. | 555 // Return the operand size required to hold a signed operand. |
665 static OperandSize SizeForSignedOperand(int value); | 556 static OperandSize SizeForSignedOperand(int value); |
666 | 557 |
667 // Return the operand size required to hold an unsigned operand. | 558 // Return the operand size required to hold an unsigned operand. |
668 static OperandSize SizeForUnsignedOperand(uint32_t value); | 559 static OperandSize SizeForUnsignedOperand(uint32_t value); |
669 | |
670 private: | |
671 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes); | |
672 }; | |
673 | |
674 class CreateObjectLiteralFlags { | |
675 public: | |
676 class FlagsBits : public BitField8<int, 0, 3> {}; | |
677 class FastClonePropertiesCountBits | |
678 : public BitField8<int, FlagsBits::kNext, 3> {}; | |
679 | |
680 static uint8_t Encode(bool fast_clone_supported, int properties_count, | |
681 int runtime_flags); | |
682 | |
683 private: | |
684 DISALLOW_IMPLICIT_CONSTRUCTORS(CreateObjectLiteralFlags); | |
685 }; | |
686 | |
687 class CreateClosureFlags { | |
688 public: | |
689 class PretenuredBit : public BitField8<bool, 0, 1> {}; | |
690 class FastNewClosureBit : public BitField8<bool, PretenuredBit::kNext, 1> {}; | |
691 | |
692 static uint8_t Encode(bool pretenure, bool is_function_scope); | |
693 | |
694 private: | |
695 DISALLOW_IMPLICIT_CONSTRUCTORS(CreateClosureFlags); | |
696 }; | 560 }; |
697 | 561 |
698 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); | 562 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); |
699 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); | 563 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); |
700 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); | 564 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); |
701 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); | 565 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); |
702 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); | 566 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); |
703 | 567 |
704 } // namespace interpreter | 568 } // namespace interpreter |
705 } // namespace internal | 569 } // namespace internal |
706 } // namespace v8 | 570 } // namespace v8 |
707 | 571 |
708 #endif // V8_INTERPRETER_BYTECODES_H_ | 572 #endif // V8_INTERPRETER_BYTECODES_H_ |
OLD | NEW |