| 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 |