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 |