| 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 <iosfwd> | 8 #include <iosfwd> |
| 9 | 9 |
| 10 // Clients of this interface shouldn't depend on lots of interpreter internals. | 10 // Clients of this interface shouldn't depend on lots of interpreter internals. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 /* Globals */ \ | 91 /* Globals */ \ |
| 92 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx) \ | 92 V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx) \ |
| 93 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx, \ | 93 V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx, \ |
| 94 OperandType::kIdx) \ | 94 OperandType::kIdx) \ |
| 95 V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \ | 95 V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx, \ |
| 96 OperandType::kIdx) \ | 96 OperandType::kIdx) \ |
| 97 V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx, \ | 97 V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx, \ |
| 98 OperandType::kIdx) \ | 98 OperandType::kIdx) \ |
| 99 \ | 99 \ |
| 100 /* Context operations */ \ | 100 /* Context operations */ \ |
| 101 V(PushContext, AccumulatorUse::kRead, OperandType::kReg) \ | 101 V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut) \ |
| 102 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \ | 102 V(PopContext, AccumulatorUse::kNone, OperandType::kReg) \ |
| 103 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \ | 103 V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg, \ |
| 104 OperandType::kIdx) \ | 104 OperandType::kIdx) \ |
| 105 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \ | 105 V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg, \ |
| 106 OperandType::kIdx) \ | 106 OperandType::kIdx) \ |
| 107 \ | 107 \ |
| 108 /* Load-Store lookup slots */ \ | 108 /* Load-Store lookup slots */ \ |
| 109 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \ | 109 V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx) \ |
| 110 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \ | 110 V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx) \ |
| 111 V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx) \ | 111 V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx) \ |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 \ | 243 \ |
| 244 /* Generators */ \ | 244 /* Generators */ \ |
| 245 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ | 245 V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg) \ |
| 246 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ | 246 V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg) \ |
| 247 \ | 247 \ |
| 248 /* Debugger */ \ | 248 /* Debugger */ \ |
| 249 V(Debugger, AccumulatorUse::kNone) \ | 249 V(Debugger, AccumulatorUse::kNone) \ |
| 250 DEBUG_BREAK_BYTECODE_LIST(V) \ | 250 DEBUG_BREAK_BYTECODE_LIST(V) \ |
| 251 \ | 251 \ |
| 252 /* Illegal bytecode (terminates execution) */ \ | 252 /* Illegal bytecode (terminates execution) */ \ |
| 253 V(Illegal, AccumulatorUse::kNone) | 253 V(Illegal, AccumulatorUse::kNone) \ |
| 254 \ |
| 255 /* No operation (used to maintain source positions for peephole */ \ |
| 256 /* eliminated bytecodes). */ \ |
| 257 V(Nop, AccumulatorUse::kNone) |
| 254 | 258 |
| 255 enum class AccumulatorUse : uint8_t { | 259 enum class AccumulatorUse : uint8_t { |
| 256 kNone = 0, | 260 kNone = 0, |
| 257 kRead = 1 << 0, | 261 kRead = 1 << 0, |
| 258 kWrite = 1 << 1, | 262 kWrite = 1 << 1, |
| 259 kReadWrite = kRead | kWrite | 263 kReadWrite = kRead | kWrite |
| 260 }; | 264 }; |
| 261 | 265 |
| 262 V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { | 266 V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { |
| 263 int result = static_cast<int>(lhs) & static_cast<int>(rhs); | 267 int result = static_cast<int>(lhs) & static_cast<int>(rhs); |
| 264 return static_cast<AccumulatorUse>(result); | 268 return static_cast<AccumulatorUse>(result); |
| 265 } | 269 } |
| 266 | 270 |
| 267 V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { | 271 V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { |
| 268 int result = static_cast<int>(lhs) | static_cast<int>(rhs); | 272 int result = static_cast<int>(lhs) | static_cast<int>(rhs); |
| 269 return static_cast<AccumulatorUse>(result); | 273 return static_cast<AccumulatorUse>(result); |
| 270 } | 274 } |
| 271 | 275 |
| 272 // Enumeration of scaling factors applicable to scalable operands. Code | 276 // Enumeration of scaling factors applicable to scalable operands. Code |
| 273 // relies on being able to cast values to integer scaling values. | 277 // relies on being able to cast values to integer scaling values. |
| 278 #define OPERAND_SCALE_LIST(V) \ |
| 279 V(Single, 1) \ |
| 280 V(Double, 2) \ |
| 281 V(Quadruple, 4) |
| 282 |
| 274 enum class OperandScale : uint8_t { | 283 enum class OperandScale : uint8_t { |
| 275 kSingle = 1, | 284 #define DECLARE_OPERAND_SCALE(Name, Scale) k##Name = Scale, |
| 276 kDouble = 2, | 285 OPERAND_SCALE_LIST(DECLARE_OPERAND_SCALE) |
| 277 kQuadruple = 4, | 286 #undef DECLARE_OPERAND_SCALE |
| 278 kMaxValid = kQuadruple, | 287 kLast = kQuadruple |
| 279 kInvalid = 8, | |
| 280 }; | 288 }; |
| 281 | 289 |
| 282 // Enumeration of the size classes of operand types used by | 290 // Enumeration of the size classes of operand types used by |
| 283 // bytecodes. Code relies on being able to cast values to integer | 291 // bytecodes. Code relies on being able to cast values to integer |
| 284 // types to get the size in bytes. | 292 // types to get the size in bytes. |
| 285 enum class OperandSize : uint8_t { | 293 enum class OperandSize : uint8_t { |
| 286 kNone = 0, | 294 kNone = 0, |
| 287 kByte = 1, | 295 kByte = 1, |
| 288 kShort = 2, | 296 kShort = 2, |
| 289 kQuad = 4, | 297 kQuad = 4, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 #define COUNT_BYTECODE(x, ...) +1 | 334 #define COUNT_BYTECODE(x, ...) +1 |
| 327 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will | 335 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will |
| 328 // evaluate to the same value as the last real bytecode. | 336 // evaluate to the same value as the last real bytecode. |
| 329 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) | 337 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) |
| 330 #undef COUNT_BYTECODE | 338 #undef COUNT_BYTECODE |
| 331 }; | 339 }; |
| 332 | 340 |
| 333 | 341 |
| 334 // An interpreter Register which is located in the function's Register file | 342 // An interpreter Register which is located in the function's Register file |
| 335 // in its stack-frame. Register hold parameters, this, and expression values. | 343 // in its stack-frame. Register hold parameters, this, and expression values. |
| 336 class Register { | 344 class Register final { |
| 337 public: | 345 public: |
| 338 explicit Register(int index = kInvalidIndex) : index_(index) {} | 346 explicit Register(int index = kInvalidIndex) : index_(index) {} |
| 339 | 347 |
| 340 int index() const { return index_; } | 348 int index() const { return index_; } |
| 341 bool is_parameter() const { return index() < 0; } | 349 bool is_parameter() const { return index() < 0; } |
| 342 bool is_valid() const { return index_ != kInvalidIndex; } | 350 bool is_valid() const { return index_ != kInvalidIndex; } |
| 343 | 351 |
| 344 static Register FromParameterIndex(int index, int parameter_count); | 352 static Register FromParameterIndex(int index, int parameter_count); |
| 345 int ToParameterIndex(int parameter_count) const; | 353 int ToParameterIndex(int parameter_count) const; |
| 346 | 354 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 | 465 |
| 458 // Returns how accumulator is used by |bytecode|. | 466 // Returns how accumulator is used by |bytecode|. |
| 459 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode); | 467 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode); |
| 460 | 468 |
| 461 // Returns true if |bytecode| reads the accumulator. | 469 // Returns true if |bytecode| reads the accumulator. |
| 462 static bool ReadsAccumulator(Bytecode bytecode); | 470 static bool ReadsAccumulator(Bytecode bytecode); |
| 463 | 471 |
| 464 // Returns true if |bytecode| writes the accumulator. | 472 // Returns true if |bytecode| writes the accumulator. |
| 465 static bool WritesAccumulator(Bytecode bytecode); | 473 static bool WritesAccumulator(Bytecode bytecode); |
| 466 | 474 |
| 475 // Return true if |bytecode| writes the accumulator with a boolean value. |
| 476 static bool WritesBooleanToAccumulator(Bytecode bytecode); |
| 477 |
| 478 // Return true if |bytecode| is an accumulator load bytecode, |
| 479 // e.g. LdaConstant, LdaTrue, Ldar. |
| 480 static bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode); |
| 481 |
| 467 // Returns the i-th operand of |bytecode|. | 482 // Returns the i-th operand of |bytecode|. |
| 468 static OperandType GetOperandType(Bytecode bytecode, int i); | 483 static OperandType GetOperandType(Bytecode bytecode, int i); |
| 469 | 484 |
| 485 // Returns a pointer to an array of operand types terminated in |
| 486 // OperandType::kNone. |
| 487 static const OperandType* GetOperandTypes(Bytecode bytecode); |
| 488 |
| 470 // Returns the size of the i-th operand of |bytecode|. | 489 // Returns the size of the i-th operand of |bytecode|. |
| 471 static OperandSize GetOperandSize(Bytecode bytecode, int i, | 490 static OperandSize GetOperandSize(Bytecode bytecode, int i, |
| 472 OperandScale operand_scale); | 491 OperandScale operand_scale); |
| 473 | 492 |
| 474 // Returns the offset of the i-th operand of |bytecode| relative to the start | 493 // Returns the offset of the i-th operand of |bytecode| relative to the start |
| 475 // of the bytecode. | 494 // of the bytecode. |
| 476 static int GetOperandOffset(Bytecode bytecode, int i, | 495 static int GetOperandOffset(Bytecode bytecode, int i, |
| 477 OperandScale operand_scale); | 496 OperandScale operand_scale); |
| 478 | 497 |
| 479 // Returns a zero-based bitmap of the register operand positions of | 498 // Returns a zero-based bitmap of the register operand positions of |
| (...skipping 27 matching lines...) Expand all Loading... |
| 507 static bool IsJumpImmediate(Bytecode bytecode); | 526 static bool IsJumpImmediate(Bytecode bytecode); |
| 508 | 527 |
| 509 // Returns true if the bytecode is a jump or conditional jump taking a | 528 // Returns true if the bytecode is a jump or conditional jump taking a |
| 510 // constant pool entry (OperandType::kIdx). | 529 // constant pool entry (OperandType::kIdx). |
| 511 static bool IsJumpConstant(Bytecode bytecode); | 530 static bool IsJumpConstant(Bytecode bytecode); |
| 512 | 531 |
| 513 // Returns true if the bytecode is a jump or conditional jump taking | 532 // Returns true if the bytecode is a jump or conditional jump taking |
| 514 // any kind of operand. | 533 // any kind of operand. |
| 515 static bool IsJump(Bytecode bytecode); | 534 static bool IsJump(Bytecode bytecode); |
| 516 | 535 |
| 536 // Returns true if the bytecode is a jump that internally coerces the |
| 537 // accumulator to a boolean. |
| 538 static bool IsJumpIfToBoolean(Bytecode bytecode); |
| 539 |
| 540 // Returns the equivalent jump bytecode without the accumulator coercion. |
| 541 static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode); |
| 542 |
| 517 // Returns true if the bytecode is a conditional jump, a jump, or a return. | 543 // Returns true if the bytecode is a conditional jump, a jump, or a return. |
| 518 static bool IsJumpOrReturn(Bytecode bytecode); | 544 static bool IsJumpOrReturn(Bytecode bytecode); |
| 519 | 545 |
| 520 // Returns true if the bytecode is a call or a constructor call. | 546 // Returns true if the bytecode is a call or a constructor call. |
| 521 static bool IsCallOrNew(Bytecode bytecode); | 547 static bool IsCallOrNew(Bytecode bytecode); |
| 522 | 548 |
| 523 // Returns true if the bytecode is a call to the runtime. | 549 // Returns true if the bytecode is a call to the runtime. |
| 524 static bool IsCallRuntime(Bytecode bytecode); | 550 static bool IsCallRuntime(Bytecode bytecode); |
| 525 | 551 |
| 526 // Returns true if the bytecode is a debug break. | 552 // Returns true if the bytecode is a debug break. |
| 527 static bool IsDebugBreak(Bytecode bytecode); | 553 static bool IsDebugBreak(Bytecode bytecode); |
| 528 | 554 |
| 555 // Returns true if the bytecode is Ldar or Star. |
| 556 static bool IsLdarOrStar(Bytecode bytecode); |
| 557 |
| 529 // Returns true if the bytecode has wider operand forms. | 558 // Returns true if the bytecode has wider operand forms. |
| 530 static bool IsBytecodeWithScalableOperands(Bytecode bytecode); | 559 static bool IsBytecodeWithScalableOperands(Bytecode bytecode); |
| 531 | 560 |
| 532 // Returns true if the bytecode is a scaling prefix bytecode. | 561 // Returns true if the bytecode is a scaling prefix bytecode. |
| 533 static bool IsPrefixScalingBytecode(Bytecode bytecode); | 562 static bool IsPrefixScalingBytecode(Bytecode bytecode); |
| 534 | 563 |
| 535 // Returns true if |operand_type| is any type of register operand. | 564 // Returns true if |operand_type| is any type of register operand. |
| 536 static bool IsRegisterOperandType(OperandType operand_type); | 565 static bool IsRegisterOperandType(OperandType operand_type); |
| 537 | 566 |
| 538 // Returns true if |operand_type| represents a register used as an input. | 567 // Returns true if |operand_type| represents a register used as an input. |
| 539 static bool IsRegisterInputOperandType(OperandType operand_type); | 568 static bool IsRegisterInputOperandType(OperandType operand_type); |
| 540 | 569 |
| 541 // Returns true if |operand_type| represents a register used as an output. | 570 // Returns true if |operand_type| represents a register used as an output. |
| 542 static bool IsRegisterOutputOperandType(OperandType operand_type); | 571 static bool IsRegisterOutputOperandType(OperandType operand_type); |
| 543 | 572 |
| 573 // Returns the number of registers represented by a register operand. For |
| 574 // instance, a RegPair represents two registers. |
| 575 static int GetNumberOfRegistersRepresentedBy(OperandType operand_type); |
| 576 |
| 544 // Returns true if |operand_type| is a maybe register operand | 577 // Returns true if |operand_type| is a maybe register operand |
| 545 // (kMaybeReg). | 578 // (kMaybeReg). |
| 546 static bool IsMaybeRegisterOperandType(OperandType operand_type); | 579 static bool IsMaybeRegisterOperandType(OperandType operand_type); |
| 547 | 580 |
| 548 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). | 581 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). |
| 549 static bool IsRuntimeIdOperandType(OperandType operand_type); | 582 static bool IsRuntimeIdOperandType(OperandType operand_type); |
| 550 | 583 |
| 551 // Returns true if |operand_type| is unsigned, false if signed. | 584 // Returns true if |operand_type| is unsigned, false if signed. |
| 552 static bool IsUnsignedOperandType(OperandType operand_type); | 585 static bool IsUnsignedOperandType(OperandType operand_type); |
| 553 | 586 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 569 // Decode a single bytecode and operands to |os|. | 602 // Decode a single bytecode and operands to |os|. |
| 570 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start, | 603 static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start, |
| 571 int number_of_parameters); | 604 int number_of_parameters); |
| 572 | 605 |
| 573 // Returns true if a handler is generated for a bytecode at a given | 606 // Returns true if a handler is generated for a bytecode at a given |
| 574 // operand scale. All bytecodes have handlers at OperandScale::kSingle, | 607 // operand scale. All bytecodes have handlers at OperandScale::kSingle, |
| 575 // but only bytecodes with scalable operands have handlers with larger | 608 // but only bytecodes with scalable operands have handlers with larger |
| 576 // OperandScale values. | 609 // OperandScale values. |
| 577 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); | 610 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); |
| 578 | 611 |
| 579 // Return the next larger operand scale. | 612 // Return the operand size required to hold a signed operand. |
| 580 static OperandScale NextOperandScale(OperandScale operand_scale); | 613 static OperandSize SizeForSignedOperand(int value); |
| 614 |
| 615 // Return the operand size required to hold an unsigned operand. |
| 616 static OperandSize SizeForUnsignedOperand(int value); |
| 617 |
| 618 // Return the operand size required to hold an unsigned operand. |
| 619 static OperandSize SizeForUnsignedOperand(size_t value); |
| 620 |
| 621 // Return the OperandScale required for bytecode emission of |
| 622 // operand sizes. |
| 623 static OperandScale OperandSizesToScale( |
| 624 OperandSize size0, OperandSize size1 = OperandSize::kByte, |
| 625 OperandSize size2 = OperandSize::kByte, |
| 626 OperandSize size3 = OperandSize::kByte); |
| 581 | 627 |
| 582 private: | 628 private: |
| 583 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes); | 629 DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecodes); |
| 584 }; | 630 }; |
| 585 | 631 |
| 586 class CreateObjectLiteralFlags { | 632 class CreateObjectLiteralFlags { |
| 587 public: | 633 public: |
| 588 class FlagsBits : public BitField8<int, 0, 3> {}; | 634 class FlagsBits : public BitField8<int, 0, 3> {}; |
| 589 class FastClonePropertiesCountBits | 635 class FastClonePropertiesCountBits |
| 590 : public BitField8<int, FlagsBits::kNext, 3> {}; | 636 : public BitField8<int, FlagsBits::kNext, 3> {}; |
| 591 STATIC_ASSERT((FlagsBits::kMask & FastClonePropertiesCountBits::kMask) == 0); | 637 STATIC_ASSERT((FlagsBits::kMask & FastClonePropertiesCountBits::kMask) == 0); |
| 592 }; | 638 }; |
| 593 | 639 |
| 594 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); | 640 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); |
| 595 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); | 641 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); |
| 596 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); | 642 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); |
| 597 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); | 643 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); |
| 598 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); | 644 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); |
| 599 | 645 |
| 600 } // namespace interpreter | 646 } // namespace interpreter |
| 601 } // namespace internal | 647 } // namespace internal |
| 602 } // namespace v8 | 648 } // namespace v8 |
| 603 | 649 |
| 604 #endif // V8_INTERPRETER_BYTECODES_H_ | 650 #endif // V8_INTERPRETER_BYTECODES_H_ |
| OLD | NEW |