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