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> | |
9 #include <iosfwd> | 8 #include <iosfwd> |
10 #include <string> | |
11 | 9 |
12 // This interface and it's implementation are independent of the | 10 // Clients of this interface shouldn't depend on lots of interpreter internals. |
13 // libv8_base library as they are used by the interpreter and the | 11 // Do not include anything from src/interpreter here! |
14 // standalone mkpeephole table generator program. | 12 #include "src/frames.h" |
| 13 #include "src/utils.h" |
15 | 14 |
16 namespace v8 { | 15 namespace v8 { |
17 namespace internal { | 16 namespace internal { |
18 namespace interpreter { | 17 namespace interpreter { |
19 | 18 |
20 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) | 19 #define INVALID_OPERAND_TYPE_LIST(V) V(None, OperandTypeInfo::kNone) |
21 | 20 |
22 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ | 21 #define REGISTER_INPUT_OPERAND_TYPE_LIST(V) \ |
23 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \ | 22 V(MaybeReg, OperandTypeInfo::kScalableSignedByte) \ |
24 V(Reg, OperandTypeInfo::kScalableSignedByte) \ | 23 V(Reg, OperandTypeInfo::kScalableSignedByte) \ |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 /* eliminated bytecodes). */ \ | 279 /* eliminated bytecodes). */ \ |
281 V(Nop, AccumulatorUse::kNone) | 280 V(Nop, AccumulatorUse::kNone) |
282 | 281 |
283 enum class AccumulatorUse : uint8_t { | 282 enum class AccumulatorUse : uint8_t { |
284 kNone = 0, | 283 kNone = 0, |
285 kRead = 1 << 0, | 284 kRead = 1 << 0, |
286 kWrite = 1 << 1, | 285 kWrite = 1 << 1, |
287 kReadWrite = kRead | kWrite | 286 kReadWrite = kRead | kWrite |
288 }; | 287 }; |
289 | 288 |
290 inline AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { | 289 V8_INLINE AccumulatorUse operator&(AccumulatorUse lhs, AccumulatorUse rhs) { |
291 int result = static_cast<int>(lhs) & static_cast<int>(rhs); | 290 int result = static_cast<int>(lhs) & static_cast<int>(rhs); |
292 return static_cast<AccumulatorUse>(result); | 291 return static_cast<AccumulatorUse>(result); |
293 } | 292 } |
294 | 293 |
295 inline AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { | 294 V8_INLINE AccumulatorUse operator|(AccumulatorUse lhs, AccumulatorUse rhs) { |
296 int result = static_cast<int>(lhs) | static_cast<int>(rhs); | 295 int result = static_cast<int>(lhs) | static_cast<int>(rhs); |
297 return static_cast<AccumulatorUse>(result); | 296 return static_cast<AccumulatorUse>(result); |
298 } | 297 } |
299 | 298 |
300 // Enumeration of scaling factors applicable to scalable operands. Code | 299 // Enumeration of scaling factors applicable to scalable operands. Code |
301 // relies on being able to cast values to integer scaling values. | 300 // relies on being able to cast values to integer scaling values. |
302 #define OPERAND_SCALE_LIST(V) \ | 301 #define OPERAND_SCALE_LIST(V) \ |
303 V(Single, 1) \ | 302 V(Single, 1) \ |
304 V(Double, 2) \ | 303 V(Double, 2) \ |
305 V(Quadruple, 4) | 304 V(Quadruple, 4) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 #define DECLARE_OPERAND_TYPE(Name, _) k##Name, | 341 #define DECLARE_OPERAND_TYPE(Name, _) k##Name, |
343 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) | 342 OPERAND_TYPE_LIST(DECLARE_OPERAND_TYPE) |
344 #undef DECLARE_OPERAND_TYPE | 343 #undef DECLARE_OPERAND_TYPE |
345 #define COUNT_OPERAND_TYPES(x, _) +1 | 344 #define COUNT_OPERAND_TYPES(x, _) +1 |
346 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will | 345 // The COUNT_OPERAND macro will turn this into kLast = -1 +1 +1... which will |
347 // evaluate to the same value as the last operand. | 346 // evaluate to the same value as the last operand. |
348 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) | 347 kLast = -1 OPERAND_TYPE_LIST(COUNT_OPERAND_TYPES) |
349 #undef COUNT_OPERAND_TYPES | 348 #undef COUNT_OPERAND_TYPES |
350 }; | 349 }; |
351 | 350 |
| 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 class Bytecodes final { | 364 |
| 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 { |
365 public: | 452 public: |
366 // The maximum number of operands a bytecode may have. | 453 // The maximum number of operands a bytecode may have. |
367 static const int kMaxOperands = 4; | 454 static const int kMaxOperands = 4; |
368 | 455 |
369 // Returns string representation of |bytecode|. | 456 // Returns string representation of |bytecode|. |
370 static const char* ToString(Bytecode bytecode); | 457 static const char* ToString(Bytecode bytecode); |
371 | 458 |
372 // Returns string representation of |bytecode|. | 459 // Returns string representation of |bytecode|. |
373 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); | 460 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); |
374 | 461 |
375 // Returns string representation of |accumulator_use|. | 462 // Returns string representation of |accumulator_use|. |
376 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use); | 463 static const char* AccumulatorUseToString(AccumulatorUse accumulator_use); |
377 | 464 |
378 // Returns string representation of |operand_type|. | 465 // Returns string representation of |operand_type|. |
379 static const char* OperandTypeToString(OperandType operand_type); | 466 static const char* OperandTypeToString(OperandType operand_type); |
380 | 467 |
381 // Returns string representation of |operand_scale|. | 468 // Returns string representation of |operand_scale|. |
382 static const char* OperandScaleToString(OperandScale operand_scale); | 469 static const char* OperandScaleToString(OperandScale operand_scale); |
383 | 470 |
384 // Returns string representation of |operand_size|. | 471 // Returns string representation of |operand_size|. |
385 static const char* OperandSizeToString(OperandSize operand_size); | 472 static const char* OperandSizeToString(OperandSize operand_size); |
386 | 473 |
387 // Returns byte value of bytecode. | 474 // Returns byte value of bytecode. |
388 static uint8_t ToByte(Bytecode bytecode); | 475 static uint8_t ToByte(Bytecode bytecode) { |
| 476 DCHECK_LE(bytecode, Bytecode::kLast); |
| 477 return static_cast<uint8_t>(bytecode); |
| 478 } |
389 | 479 |
390 // Returns bytecode for |value|. | 480 // Returns bytecode for |value|. |
391 static Bytecode FromByte(uint8_t value); | 481 static Bytecode FromByte(uint8_t value); |
392 | 482 |
393 // Returns the number of operands expected by |bytecode|. | 483 // Returns the number of operands expected by |bytecode|. |
394 static int NumberOfOperands(Bytecode bytecode); | 484 static int NumberOfOperands(Bytecode bytecode); |
395 | 485 |
396 // Returns the number of register operands expected by |bytecode|. | 486 // Returns the number of register operands expected by |bytecode|. |
397 static int NumberOfRegisterOperands(Bytecode bytecode); | 487 static int NumberOfRegisterOperands(Bytecode bytecode); |
398 | 488 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 // Returns true if |operand_type| is a maybe register operand | 629 // Returns true if |operand_type| is a maybe register operand |
540 // (kMaybeReg). | 630 // (kMaybeReg). |
541 static bool IsMaybeRegisterOperandType(OperandType operand_type); | 631 static bool IsMaybeRegisterOperandType(OperandType operand_type); |
542 | 632 |
543 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). | 633 // Returns true if |operand_type| is a runtime-id operand (kRuntimeId). |
544 static bool IsRuntimeIdOperandType(OperandType operand_type); | 634 static bool IsRuntimeIdOperandType(OperandType operand_type); |
545 | 635 |
546 // Returns true if |operand_type| is unsigned, false if signed. | 636 // Returns true if |operand_type| is unsigned, false if signed. |
547 static bool IsUnsignedOperandType(OperandType operand_type); | 637 static bool IsUnsignedOperandType(OperandType operand_type); |
548 | 638 |
| 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 |
549 // Returns true if a handler is generated for a bytecode at a given | 658 // Returns true if a handler is generated for a bytecode at a given |
550 // operand scale. All bytecodes have handlers at OperandScale::kSingle, | 659 // operand scale. All bytecodes have handlers at OperandScale::kSingle, |
551 // but only bytecodes with scalable operands have handlers with larger | 660 // but only bytecodes with scalable operands have handlers with larger |
552 // OperandScale values. | 661 // OperandScale values. |
553 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); | 662 static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale); |
554 | 663 |
555 // Return the operand size required to hold a signed operand. | 664 // Return the operand size required to hold a signed operand. |
556 static OperandSize SizeForSignedOperand(int value); | 665 static OperandSize SizeForSignedOperand(int value); |
557 | 666 |
558 // Return the operand size required to hold an unsigned operand. | 667 // Return the operand size required to hold an unsigned operand. |
559 static OperandSize SizeForUnsignedOperand(uint32_t value); | 668 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); |
560 }; | 696 }; |
561 | 697 |
562 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); | 698 std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode); |
563 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); | 699 std::ostream& operator<<(std::ostream& os, const AccumulatorUse& use); |
564 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); | 700 std::ostream& operator<<(std::ostream& os, const OperandScale& operand_scale); |
565 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); | 701 std::ostream& operator<<(std::ostream& os, const OperandSize& operand_size); |
566 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); | 702 std::ostream& operator<<(std::ostream& os, const OperandType& operand_type); |
567 | 703 |
568 } // namespace interpreter | 704 } // namespace interpreter |
569 } // namespace internal | 705 } // namespace internal |
570 } // namespace v8 | 706 } // namespace v8 |
571 | 707 |
572 #endif // V8_INTERPRETER_BYTECODES_H_ | 708 #endif // V8_INTERPRETER_BYTECODES_H_ |
OLD | NEW |