LCOV - code coverage report
Current view: top level - src/interpreter - bytecodes.h (source / functions) Hit Total Coverage
Test: app.info Lines: 81 85 95.3 %
Date: 2017-04-26 Functions: 13 13 100.0 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_INTERPRETER_BYTECODES_H_
       6             : #define V8_INTERPRETER_BYTECODES_H_
       7             : 
       8             : #include <cstdint>
       9             : #include <iosfwd>
      10             : #include <string>
      11             : 
      12             : #include "src/globals.h"
      13             : #include "src/interpreter/bytecode-operands.h"
      14             : 
      15             : // This interface and it's implementation are independent of the
      16             : // libv8_base library as they are used by the interpreter and the
      17             : // standalone mkpeephole table generator program.
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : namespace interpreter {
      22             : 
      23             : // The list of bytecodes which are interpreted by the interpreter.
      24             : // Format is V(<bytecode>, <accumulator_use>, <operands>).
      25             : #define BYTECODE_LIST(V)                                                       \
      26             :   /* Extended width operands */                                                \
      27             :   V(Wide, AccumulatorUse::kNone)                                               \
      28             :   V(ExtraWide, AccumulatorUse::kNone)                                          \
      29             :                                                                                \
      30             :   /* Loading the accumulator */                                                \
      31             :   V(LdaZero, AccumulatorUse::kWrite)                                           \
      32             :   V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm)                         \
      33             :   V(LdaUndefined, AccumulatorUse::kWrite)                                      \
      34             :   V(LdaNull, AccumulatorUse::kWrite)                                           \
      35             :   V(LdaTheHole, AccumulatorUse::kWrite)                                        \
      36             :   V(LdaTrue, AccumulatorUse::kWrite)                                           \
      37             :   V(LdaFalse, AccumulatorUse::kWrite)                                          \
      38             :   V(LdaConstant, AccumulatorUse::kWrite, OperandType::kIdx)                    \
      39             :                                                                                \
      40             :   /* Globals */                                                                \
      41             :   V(LdaGlobal, AccumulatorUse::kWrite, OperandType::kIdx, OperandType::kIdx)   \
      42             :   V(LdaGlobalInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx,          \
      43             :     OperandType::kIdx)                                                         \
      44             :   V(StaGlobalSloppy, AccumulatorUse::kRead, OperandType::kIdx,                 \
      45             :     OperandType::kIdx)                                                         \
      46             :   V(StaGlobalStrict, AccumulatorUse::kRead, OperandType::kIdx,                 \
      47             :     OperandType::kIdx)                                                         \
      48             :                                                                                \
      49             :   /* Context operations */                                                     \
      50             :   V(PushContext, AccumulatorUse::kRead, OperandType::kRegOut)                  \
      51             :   V(PopContext, AccumulatorUse::kNone, OperandType::kReg)                      \
      52             :   V(LdaContextSlot, AccumulatorUse::kWrite, OperandType::kReg,                 \
      53             :     OperandType::kIdx, OperandType::kUImm)                                     \
      54             :   V(LdaImmutableContextSlot, AccumulatorUse::kWrite, OperandType::kReg,        \
      55             :     OperandType::kIdx, OperandType::kUImm)                                     \
      56             :   V(LdaCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx)          \
      57             :   V(LdaImmutableCurrentContextSlot, AccumulatorUse::kWrite, OperandType::kIdx) \
      58             :   V(StaContextSlot, AccumulatorUse::kRead, OperandType::kReg,                  \
      59             :     OperandType::kIdx, OperandType::kUImm)                                     \
      60             :   V(StaCurrentContextSlot, AccumulatorUse::kRead, OperandType::kIdx)           \
      61             :                                                                                \
      62             :   /* Load-Store lookup slots */                                                \
      63             :   V(LdaLookupSlot, AccumulatorUse::kWrite, OperandType::kIdx)                  \
      64             :   V(LdaLookupContextSlot, AccumulatorUse::kWrite, OperandType::kIdx,           \
      65             :     OperandType::kIdx, OperandType::kUImm)                                     \
      66             :   V(LdaLookupGlobalSlot, AccumulatorUse::kWrite, OperandType::kIdx,            \
      67             :     OperandType::kIdx, OperandType::kUImm)                                     \
      68             :   V(LdaLookupSlotInsideTypeof, AccumulatorUse::kWrite, OperandType::kIdx)      \
      69             :   V(LdaLookupContextSlotInsideTypeof, AccumulatorUse::kWrite,                  \
      70             :     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
      71             :   V(LdaLookupGlobalSlotInsideTypeof, AccumulatorUse::kWrite,                   \
      72             :     OperandType::kIdx, OperandType::kIdx, OperandType::kUImm)                  \
      73             :   V(StaLookupSlotSloppy, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
      74             :   V(StaLookupSlotStrict, AccumulatorUse::kReadWrite, OperandType::kIdx)        \
      75             :                                                                                \
      76             :   /* Register-accumulator transfers */                                         \
      77             :   V(Ldar, AccumulatorUse::kWrite, OperandType::kReg)                           \
      78             :   V(Star, AccumulatorUse::kRead, OperandType::kRegOut)                         \
      79             :                                                                                \
      80             :   /* Register-register transfers */                                            \
      81             :   V(Mov, AccumulatorUse::kNone, OperandType::kReg, OperandType::kRegOut)       \
      82             :                                                                                \
      83             :   /* Property loads (LoadIC) operations */                                     \
      84             :   V(LdaNamedProperty, AccumulatorUse::kWrite, OperandType::kReg,               \
      85             :     OperandType::kIdx, OperandType::kIdx)                                      \
      86             :   V(LdaKeyedProperty, AccumulatorUse::kReadWrite, OperandType::kReg,           \
      87             :     OperandType::kIdx)                                                         \
      88             :                                                                                \
      89             :   /* Operations on module variables */                                         \
      90             :   V(LdaModuleVariable, AccumulatorUse::kWrite, OperandType::kImm,              \
      91             :     OperandType::kUImm)                                                        \
      92             :   V(StaModuleVariable, AccumulatorUse::kRead, OperandType::kImm,               \
      93             :     OperandType::kUImm)                                                        \
      94             :                                                                                \
      95             :   /* Propery stores (StoreIC) operations */                                    \
      96             :   V(StaNamedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
      97             :     OperandType::kIdx, OperandType::kIdx)                                      \
      98             :   V(StaNamedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
      99             :     OperandType::kIdx, OperandType::kIdx)                                      \
     100             :   V(StaNamedOwnProperty, AccumulatorUse::kRead, OperandType::kReg,             \
     101             :     OperandType::kIdx, OperandType::kIdx)                                      \
     102             :   V(StaKeyedPropertySloppy, AccumulatorUse::kRead, OperandType::kReg,          \
     103             :     OperandType::kReg, OperandType::kIdx)                                      \
     104             :   V(StaKeyedPropertyStrict, AccumulatorUse::kRead, OperandType::kReg,          \
     105             :     OperandType::kReg, OperandType::kIdx)                                      \
     106             :   V(StaDataPropertyInLiteral, AccumulatorUse::kRead, OperandType::kReg,        \
     107             :     OperandType::kReg, OperandType::kFlag8, OperandType::kIdx)                 \
     108             :   V(CollectTypeProfile, AccumulatorUse::kRead, OperandType::kImm)              \
     109             :                                                                                \
     110             :   /* Binary Operators */                                                       \
     111             :   V(Add, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
     112             :   V(Sub, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
     113             :   V(Mul, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
     114             :   V(Div, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
     115             :   V(Mod, AccumulatorUse::kReadWrite, OperandType::kReg, OperandType::kIdx)     \
     116             :   V(BitwiseOr, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
     117             :     OperandType::kIdx)                                                         \
     118             :   V(BitwiseXor, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
     119             :     OperandType::kIdx)                                                         \
     120             :   V(BitwiseAnd, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
     121             :     OperandType::kIdx)                                                         \
     122             :   V(ShiftLeft, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
     123             :     OperandType::kIdx)                                                         \
     124             :   V(ShiftRight, AccumulatorUse::kReadWrite, OperandType::kReg,                 \
     125             :     OperandType::kIdx)                                                         \
     126             :   V(ShiftRightLogical, AccumulatorUse::kReadWrite, OperandType::kReg,          \
     127             :     OperandType::kIdx)                                                         \
     128             :                                                                                \
     129             :   /* Binary operators with immediate operands */                               \
     130             :   V(AddSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
     131             :   V(SubSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
     132             :   V(MulSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
     133             :   V(DivSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
     134             :   V(ModSmi, AccumulatorUse::kReadWrite, OperandType::kImm, OperandType::kIdx)  \
     135             :   V(BitwiseOrSmi, AccumulatorUse::kReadWrite, OperandType::kImm,               \
     136             :     OperandType::kIdx)                                                         \
     137             :   V(BitwiseXorSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
     138             :     OperandType::kIdx)                                                         \
     139             :   V(BitwiseAndSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
     140             :     OperandType::kIdx)                                                         \
     141             :   V(ShiftLeftSmi, AccumulatorUse::kReadWrite, OperandType::kImm,               \
     142             :     OperandType::kIdx)                                                         \
     143             :   V(ShiftRightSmi, AccumulatorUse::kReadWrite, OperandType::kImm,              \
     144             :     OperandType::kIdx)                                                         \
     145             :   V(ShiftRightLogicalSmi, AccumulatorUse::kReadWrite, OperandType::kImm,       \
     146             :     OperandType::kIdx)                                                         \
     147             :                                                                                \
     148             :   /* Unary Operators */                                                        \
     149             :   V(Inc, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
     150             :   V(Dec, AccumulatorUse::kReadWrite, OperandType::kIdx)                        \
     151             :   V(ToBooleanLogicalNot, AccumulatorUse::kReadWrite)                           \
     152             :   V(LogicalNot, AccumulatorUse::kReadWrite)                                    \
     153             :   V(TypeOf, AccumulatorUse::kReadWrite)                                        \
     154             :   V(DeletePropertyStrict, AccumulatorUse::kReadWrite, OperandType::kReg)       \
     155             :   V(DeletePropertySloppy, AccumulatorUse::kReadWrite, OperandType::kReg)       \
     156             :                                                                                \
     157             :   /* GetSuperConstructor operator */                                           \
     158             :   V(GetSuperConstructor, AccumulatorUse::kRead, OperandType::kRegOut)          \
     159             :                                                                                \
     160             :   /* Call operations */                                                        \
     161             :   V(CallAnyReceiver, AccumulatorUse::kWrite, OperandType::kReg,                \
     162             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
     163             :   V(CallProperty, AccumulatorUse::kWrite, OperandType::kReg,                   \
     164             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
     165             :   V(CallProperty0, AccumulatorUse::kWrite, OperandType::kReg,                  \
     166             :     OperandType::kReg, OperandType::kIdx)                                      \
     167             :   V(CallProperty1, AccumulatorUse::kWrite, OperandType::kReg,                  \
     168             :     OperandType::kReg, OperandType::kReg, OperandType::kIdx)                   \
     169             :   V(CallProperty2, AccumulatorUse::kWrite, OperandType::kReg,                  \
     170             :     OperandType::kReg, OperandType::kReg, OperandType::kReg,                   \
     171             :     OperandType::kIdx)                                                         \
     172             :   V(CallUndefinedReceiver, AccumulatorUse::kWrite, OperandType::kReg,          \
     173             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
     174             :   V(CallUndefinedReceiver0, AccumulatorUse::kWrite, OperandType::kReg,         \
     175             :     OperandType::kIdx)                                                         \
     176             :   V(CallUndefinedReceiver1, AccumulatorUse::kWrite, OperandType::kReg,         \
     177             :     OperandType::kReg, OperandType::kIdx)                                      \
     178             :   V(CallUndefinedReceiver2, AccumulatorUse::kWrite, OperandType::kReg,         \
     179             :     OperandType::kReg, OperandType::kReg, OperandType::kIdx)                   \
     180             :   V(CallWithSpread, AccumulatorUse::kWrite, OperandType::kReg,                 \
     181             :     OperandType::kRegList, OperandType::kRegCount)                             \
     182             :   V(TailCall, AccumulatorUse::kWrite, OperandType::kReg,                       \
     183             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
     184             :   V(CallRuntime, AccumulatorUse::kWrite, OperandType::kRuntimeId,              \
     185             :     OperandType::kRegList, OperandType::kRegCount)                             \
     186             :   V(CallRuntimeForPair, AccumulatorUse::kNone, OperandType::kRuntimeId,        \
     187             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kRegOutPair)   \
     188             :   V(CallJSRuntime, AccumulatorUse::kWrite, OperandType::kIdx,                  \
     189             :     OperandType::kRegList, OperandType::kRegCount)                             \
     190             :                                                                                \
     191             :   /* Intrinsics */                                                             \
     192             :   V(InvokeIntrinsic, AccumulatorUse::kWrite, OperandType::kIntrinsicId,        \
     193             :     OperandType::kRegList, OperandType::kRegCount)                             \
     194             :                                                                                \
     195             :   /* Construct operators */                                                    \
     196             :   V(Construct, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
     197             :     OperandType::kRegList, OperandType::kRegCount, OperandType::kIdx)          \
     198             :   V(ConstructWithSpread, AccumulatorUse::kReadWrite, OperandType::kReg,        \
     199             :     OperandType::kRegList, OperandType::kRegCount)                             \
     200             :                                                                                \
     201             :   /* Test Operators */                                                         \
     202             :   V(TestEqual, AccumulatorUse::kReadWrite, OperandType::kReg,                  \
     203             :     OperandType::kIdx)                                                         \
     204             :   V(TestEqualStrict, AccumulatorUse::kReadWrite, OperandType::kReg,            \
     205             :     OperandType::kIdx)                                                         \
     206             :   V(TestLessThan, AccumulatorUse::kReadWrite, OperandType::kReg,               \
     207             :     OperandType::kIdx)                                                         \
     208             :   V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg,            \
     209             :     OperandType::kIdx)                                                         \
     210             :   V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,        \
     211             :     OperandType::kIdx)                                                         \
     212             :   V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg,     \
     213             :     OperandType::kIdx)                                                         \
     214             :   V(TestEqualStrictNoFeedback, AccumulatorUse::kReadWrite, OperandType::kReg)  \
     215             :   V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg)             \
     216             :   V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg)                     \
     217             :   V(TestUndetectable, AccumulatorUse::kReadWrite)                              \
     218             :   V(TestNull, AccumulatorUse::kReadWrite)                                      \
     219             :   V(TestUndefined, AccumulatorUse::kReadWrite)                                 \
     220             :   V(TestTypeOf, AccumulatorUse::kReadWrite, OperandType::kFlag8)               \
     221             :                                                                                \
     222             :   /* Cast operators */                                                         \
     223             :   V(ToName, AccumulatorUse::kRead, OperandType::kRegOut)                       \
     224             :   V(ToNumber, AccumulatorUse::kRead, OperandType::kRegOut, OperandType::kIdx)  \
     225             :   V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut)                     \
     226             :                                                                                \
     227             :   /* Literals */                                                               \
     228             :   V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx,            \
     229             :     OperandType::kIdx, OperandType::kFlag8)                                    \
     230             :   V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx,             \
     231             :     OperandType::kIdx, OperandType::kFlag8)                                    \
     232             :   V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx,             \
     233             :     OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut)              \
     234             :                                                                                \
     235             :   /* Closure allocation */                                                     \
     236             :   V(CreateClosure, AccumulatorUse::kWrite, OperandType::kIdx,                  \
     237             :     OperandType::kIdx, OperandType::kFlag8)                                    \
     238             :                                                                                \
     239             :   /* Context allocation */                                                     \
     240             :   V(CreateBlockContext, AccumulatorUse::kReadWrite, OperandType::kIdx)         \
     241             :   V(CreateCatchContext, AccumulatorUse::kReadWrite, OperandType::kReg,         \
     242             :     OperandType::kIdx, OperandType::kIdx)                                      \
     243             :   V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm)         \
     244             :   V(CreateEvalContext, AccumulatorUse::kWrite, OperandType::kUImm)             \
     245             :   V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg,          \
     246             :     OperandType::kIdx)                                                         \
     247             :                                                                                \
     248             :   /* Arguments allocation */                                                   \
     249             :   V(CreateMappedArguments, AccumulatorUse::kWrite)                             \
     250             :   V(CreateUnmappedArguments, AccumulatorUse::kWrite)                           \
     251             :   V(CreateRestParameter, AccumulatorUse::kWrite)                               \
     252             :                                                                                \
     253             :   /* Control Flow -- carefully ordered for efficient checks */                 \
     254             :   /* - [Unconditional jumps] */                                                \
     255             :   V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm)    \
     256             :   /* - [Forward jumps] */                                                      \
     257             :   V(Jump, AccumulatorUse::kNone, OperandType::kUImm)                           \
     258             :   /* - [Start constant jumps] */                                               \
     259             :   V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx)                    \
     260             :   /* - [Conditional jumps] */                                                  \
     261             :   /* - [Conditional constant jumps] */                                         \
     262             :   V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
     263             :   V(JumpIfNotNullConstant, AccumulatorUse::kRead, OperandType::kIdx)           \
     264             :   V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)         \
     265             :   V(JumpIfNotUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx)      \
     266             :   V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)              \
     267             :   V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)             \
     268             :   V(JumpIfJSReceiverConstant, AccumulatorUse::kRead, OperandType::kIdx)        \
     269             :   V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx)           \
     270             :   /* - [Start ToBoolean jumps] */                                              \
     271             :   V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx)     \
     272             :   V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx)    \
     273             :   /* - [End constant jumps] */                                                 \
     274             :   /* - [Conditional immediate jumps] */                                        \
     275             :   V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm)            \
     276             :   V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm)           \
     277             :   /* - [End ToBoolean jumps] */                                                \
     278             :   V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm)                     \
     279             :   V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm)                    \
     280             :   V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm)                     \
     281             :   V(JumpIfNotNull, AccumulatorUse::kRead, OperandType::kUImm)                  \
     282             :   V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm)                \
     283             :   V(JumpIfNotUndefined, AccumulatorUse::kRead, OperandType::kUImm)             \
     284             :   V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm)               \
     285             :   V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kUImm)                  \
     286             :                                                                                \
     287             :   /* Complex flow control For..in */                                           \
     288             :   V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg,                    \
     289             :     OperandType::kRegOutTriple)                                                \
     290             :   V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg,                  \
     291             :     OperandType::kReg)                                                         \
     292             :   V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg,   \
     293             :     OperandType::kRegPair, OperandType::kIdx)                                  \
     294             :   V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg)                      \
     295             :                                                                                \
     296             :   /* Perform a stack guard check */                                            \
     297             :   V(StackCheck, AccumulatorUse::kNone)                                         \
     298             :                                                                                \
     299             :   /* Update the pending message */                                             \
     300             :   V(SetPendingMessage, AccumulatorUse::kReadWrite)                             \
     301             :                                                                                \
     302             :   /* Non-local flow control */                                                 \
     303             :   V(Throw, AccumulatorUse::kRead)                                              \
     304             :   V(ReThrow, AccumulatorUse::kRead)                                            \
     305             :   V(Return, AccumulatorUse::kRead)                                             \
     306             :                                                                                \
     307             :   /* Generators */                                                             \
     308             :   V(SuspendGenerator, AccumulatorUse::kRead, OperandType::kReg,                \
     309             :     OperandType::kFlag8)                                                       \
     310             :   V(ResumeGenerator, AccumulatorUse::kWrite, OperandType::kReg)                \
     311             :                                                                                \
     312             :   /* Debugger */                                                               \
     313             :   V(Debugger, AccumulatorUse::kNone)                                           \
     314             :                                                                                \
     315             :   /* Debug Breakpoints - one for each possible size of unscaled bytecodes */   \
     316             :   /* and one for each operand widening prefix bytecode                    */   \
     317             :   V(DebugBreak0, AccumulatorUse::kRead)                                        \
     318             :   V(DebugBreak1, AccumulatorUse::kRead, OperandType::kReg)                     \
     319             :   V(DebugBreak2, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg)  \
     320             :   V(DebugBreak3, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg,  \
     321             :     OperandType::kReg)                                                         \
     322             :   V(DebugBreak4, AccumulatorUse::kRead, OperandType::kReg, OperandType::kReg,  \
     323             :     OperandType::kReg, OperandType::kReg)                                      \
     324             :   V(DebugBreak5, AccumulatorUse::kRead, OperandType::kRuntimeId,               \
     325             :     OperandType::kReg, OperandType::kReg)                                      \
     326             :   V(DebugBreak6, AccumulatorUse::kRead, OperandType::kRuntimeId,               \
     327             :     OperandType::kReg, OperandType::kReg, OperandType::kReg)                   \
     328             :   V(DebugBreakWide, AccumulatorUse::kRead)                                     \
     329             :   V(DebugBreakExtraWide, AccumulatorUse::kRead)                                \
     330             :                                                                                \
     331             :   /* Illegal bytecode (terminates execution) */                                \
     332             :   V(Illegal, AccumulatorUse::kNone)                                            \
     333             :                                                                                \
     334             :   /* No operation (used to maintain source positions for peephole */           \
     335             :   /* eliminated bytecodes). */                                                 \
     336             :   V(Nop, AccumulatorUse::kNone)
     337             : 
     338             : // List of debug break bytecodes.
     339             : #define DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
     340             :   V(DebugBreak0)                           \
     341             :   V(DebugBreak1)                           \
     342             :   V(DebugBreak2)                           \
     343             :   V(DebugBreak3)                           \
     344             :   V(DebugBreak4)                           \
     345             :   V(DebugBreak5)                           \
     346             :   V(DebugBreak6)
     347             : 
     348             : #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \
     349             :   V(DebugBreakWide)                         \
     350             :   V(DebugBreakExtraWide)
     351             : 
     352             : #define DEBUG_BREAK_BYTECODE_LIST(V) \
     353             :   DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \
     354             :   DEBUG_BREAK_PREFIX_BYTECODE_LIST(V)
     355             : 
     356             : // Lists of jump bytecodes.
     357             : 
     358             : #define JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     359             :   V(JumpLoop)                                         \
     360             :   V(Jump)
     361             : 
     362             : #define JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) V(JumpConstant)
     363             : 
     364             : #define JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     365             :   V(JumpIfToBooleanTrue)                                      \
     366             :   V(JumpIfToBooleanFalse)
     367             : 
     368             : #define JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
     369             :   V(JumpIfToBooleanTrueConstant)                             \
     370             :   V(JumpIfToBooleanFalseConstant)
     371             : 
     372             : #define JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V)     \
     373             :   JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     374             :   V(JumpIfTrue)                                         \
     375             :   V(JumpIfFalse)                                        \
     376             :   V(JumpIfNull)                                         \
     377             :   V(JumpIfNotNull)                                      \
     378             :   V(JumpIfUndefined)                                    \
     379             :   V(JumpIfNotUndefined)                                 \
     380             :   V(JumpIfJSReceiver)                                   \
     381             :   V(JumpIfNotHole)
     382             : 
     383             : #define JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)     \
     384             :   JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
     385             :   V(JumpIfNullConstant)                                \
     386             :   V(JumpIfNotNullConstant)                             \
     387             :   V(JumpIfUndefinedConstant)                           \
     388             :   V(JumpIfNotUndefinedConstant)                        \
     389             :   V(JumpIfTrueConstant)                                \
     390             :   V(JumpIfFalseConstant)                               \
     391             :   V(JumpIfJSReceiverConstant)                          \
     392             :   V(JumpIfNotHoleConstant)
     393             : 
     394             : #define JUMP_CONSTANT_BYTECODE_LIST(V)         \
     395             :   JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) \
     396             :   JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
     397             : 
     398             : #define JUMP_IMMEDIATE_BYTECODE_LIST(V)         \
     399             :   JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     400             :   JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V)
     401             : 
     402             : #define JUMP_TO_BOOLEAN_BYTECODE_LIST(V)                \
     403             :   JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     404             :   JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
     405             : 
     406             : #define JUMP_UNCONDITIONAL_BYTECODE_LIST(V)     \
     407             :   JUMP_UNCONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     408             :   JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V)
     409             : 
     410             : #define JUMP_CONDITIONAL_BYTECODE_LIST(V)     \
     411             :   JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \
     412             :   JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V)
     413             : 
     414             : #define JUMP_FORWARD_BYTECODE_LIST(V) \
     415             :   V(Jump)                             \
     416             :   V(JumpConstant)                     \
     417             :   JUMP_CONDITIONAL_BYTECODE_LIST(V)
     418             : 
     419             : #define JUMP_BYTECODE_LIST(V)   \
     420             :   JUMP_FORWARD_BYTECODE_LIST(V) \
     421             :   V(JumpLoop)
     422             : 
     423             : // Enumeration of interpreter bytecodes.
     424             : enum class Bytecode : uint8_t {
     425             : #define DECLARE_BYTECODE(Name, ...) k##Name,
     426             :   BYTECODE_LIST(DECLARE_BYTECODE)
     427             : #undef DECLARE_BYTECODE
     428             : #define COUNT_BYTECODE(x, ...) +1
     429             :   // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will
     430             :   // evaluate to the same value as the last real bytecode.
     431             :   kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
     432             : #undef COUNT_BYTECODE
     433             : };
     434             : 
     435             : class V8_EXPORT_PRIVATE Bytecodes final {
     436             :  public:
     437             :   // The maximum number of operands a bytecode may have.
     438             :   static const int kMaxOperands = 5;
     439             : 
     440             :   // Returns string representation of |bytecode|.
     441             :   static const char* ToString(Bytecode bytecode);
     442             : 
     443             :   // Returns string representation of |bytecode|.
     444             :   static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
     445             : 
     446             :   // Returns byte value of bytecode.
     447             :   static uint8_t ToByte(Bytecode bytecode) {
     448             :     DCHECK_LE(bytecode, Bytecode::kLast);
     449             :     return static_cast<uint8_t>(bytecode);
     450             :   }
     451             : 
     452             :   // Returns bytecode for |value|.
     453       65553 :   static Bytecode FromByte(uint8_t value) {
     454             :     Bytecode bytecode = static_cast<Bytecode>(value);
     455             :     DCHECK(bytecode <= Bytecode::kLast);
     456       65553 :     return bytecode;
     457             :   }
     458             : 
     459             :   // Returns the prefix bytecode representing an operand scale to be
     460             :   // applied to a a bytecode.
     461    11192124 :   static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale) {
     462    11192124 :     switch (operand_scale) {
     463             :       case OperandScale::kQuadruple:
     464             :         return Bytecode::kExtraWide;
     465             :       case OperandScale::kDouble:
     466    11009160 :         return Bytecode::kWide;
     467             :       default:
     468           0 :         UNREACHABLE();
     469             :         return Bytecode::kIllegal;
     470             :     }
     471             :   }
     472             : 
     473             :   // Returns true if the operand scale requires a prefix bytecode.
     474             :   static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale) {
     475             :     return operand_scale != OperandScale::kSingle;
     476             :   }
     477             : 
     478             :   // Returns the scaling applied to scalable operands if bytecode is
     479             :   // is a scaling prefix.
     480     5831353 :   static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode) {
     481     5831353 :     switch (bytecode) {
     482             :       case Bytecode::kExtraWide:
     483             :       case Bytecode::kDebugBreakExtraWide:
     484             :         return OperandScale::kQuadruple;
     485             :       case Bytecode::kWide:
     486             :       case Bytecode::kDebugBreakWide:
     487     5742861 :         return OperandScale::kDouble;
     488             :       default:
     489           0 :         UNREACHABLE();
     490             :         return OperandScale::kSingle;
     491             :     }
     492             :   }
     493             : 
     494             :   // Returns how accumulator is used by |bytecode|.
     495             :   static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
     496             :     DCHECK(bytecode <= Bytecode::kLast);
     497    50206774 :     return kAccumulatorUse[static_cast<size_t>(bytecode)];
     498             :   }
     499             : 
     500             :   // Returns true if |bytecode| reads the accumulator.
     501             :   static bool ReadsAccumulator(Bytecode bytecode) {
     502             :     return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
     503             :   }
     504             : 
     505             :   // Returns true if |bytecode| writes the accumulator.
     506             :   static bool WritesAccumulator(Bytecode bytecode) {
     507             :     return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
     508             :   }
     509             : 
     510             :   // Return true if |bytecode| is an accumulator load without effects,
     511             :   // e.g. LdaConstant, LdaTrue, Ldar.
     512   114616446 :   static constexpr bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
     513   114616446 :     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
     514   105927412 :            bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
     515    99260343 :            bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
     516   197501358 :            bytecode == Bytecode::kLdaUndefined ||
     517    98750679 :            bytecode == Bytecode::kLdaTheHole ||
     518   193859368 :            bytecode == Bytecode::kLdaConstant ||
     519    96929684 :            bytecode == Bytecode::kLdaContextSlot ||
     520    92624346 :            bytecode == Bytecode::kLdaCurrentContextSlot ||
     521   206035160 :            bytecode == Bytecode::kLdaImmutableContextSlot ||
     522   114616446 :            bytecode == Bytecode::kLdaImmutableCurrentContextSlot;
     523             :   }
     524             : 
     525             :   // Returns true if |bytecode| is a compare operation without external effects
     526             :   // (e.g., Type cooersion).
     527             :   static constexpr bool IsCompareWithoutEffects(Bytecode bytecode) {
     528             :     return bytecode == Bytecode::kTestUndetectable ||
     529             :            bytecode == Bytecode::kTestNull ||
     530    23039329 :            bytecode == Bytecode::kTestUndefined ||
     531             :            bytecode == Bytecode::kTestTypeOf;
     532             :   }
     533             : 
     534             :   // Return true if |bytecode| is a register load without effects,
     535             :   // e.g. Mov, Star.
     536             :   static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
     537    33009306 :     return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
     538    33009306 :            bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
     539             :   }
     540             : 
     541             :   // Returns true if the bytecode is a conditional jump taking
     542             :   // an immediate byte operand (OperandType::kImm).
     543             :   static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) {
     544     1417527 :     return bytecode >= Bytecode::kJumpIfToBooleanTrue &&
     545             :            bytecode <= Bytecode::kJumpIfNotHole;
     546             :   }
     547             : 
     548             :   // Returns true if the bytecode is a conditional jump taking
     549             :   // a constant pool entry (OperandType::kIdx).
     550             :   static constexpr bool IsConditionalJumpConstant(Bytecode bytecode) {
     551             :     return bytecode >= Bytecode::kJumpIfNullConstant &&
     552             :            bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
     553             :   }
     554             : 
     555             :   // Returns true if the bytecode is a conditional jump taking
     556             :   // any kind of operand.
     557             :   static constexpr bool IsConditionalJump(Bytecode bytecode) {
     558             :     return bytecode >= Bytecode::kJumpIfNullConstant &&
     559             :            bytecode <= Bytecode::kJumpIfNotHole;
     560             :   }
     561             : 
     562             :   // Returns true if the bytecode is an unconditional jump.
     563             :   static constexpr bool IsUnconditionalJump(Bytecode bytecode) {
     564    16059127 :     return bytecode >= Bytecode::kJumpLoop &&
     565             :            bytecode <= Bytecode::kJumpConstant;
     566             :   }
     567             : 
     568             :   // Returns true if the bytecode is a jump or a conditional jump taking
     569             :   // an immediate byte operand (OperandType::kImm).
     570             :   static constexpr bool IsJumpImmediate(Bytecode bytecode) {
     571     3299458 :     return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
     572             :            IsConditionalJumpImmediate(bytecode);
     573             :   }
     574             : 
     575             :   // Returns true if the bytecode is a jump or conditional jump taking a
     576             :   // constant pool entry (OperandType::kIdx).
     577             :   static constexpr bool IsJumpConstant(Bytecode bytecode) {
     578       53366 :     return bytecode >= Bytecode::kJumpConstant &&
     579             :            bytecode <= Bytecode::kJumpIfToBooleanFalseConstant;
     580             :   }
     581             : 
     582             :   // Returns true if the bytecode is a jump that internally coerces the
     583             :   // accumulator to a boolean.
     584             :   static constexpr bool IsJumpIfToBoolean(Bytecode bytecode) {
     585     1611051 :     return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant &&
     586             :            bytecode <= Bytecode::kJumpIfToBooleanFalse;
     587             :   }
     588             : 
     589             :   // Returns true if the bytecode is a jump or conditional jump taking
     590             :   // any kind of operand.
     591    47514399 :   static constexpr bool IsJump(Bytecode bytecode) {
     592    70141399 :     return bytecode >= Bytecode::kJumpLoop &&
     593    47514399 :            bytecode <= Bytecode::kJumpIfNotHole;
     594             :   }
     595             : 
     596             :   // Returns true if the bytecode is a forward jump or conditional jump taking
     597             :   // any kind of operand.
     598             :   static constexpr bool IsForwardJump(Bytecode bytecode) {
     599    16487052 :     return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole;
     600             :   }
     601             : 
     602             :   // Returns true if the bytecode is a conditional jump, a jump, or a return.
     603             :   static constexpr bool IsJumpOrReturn(Bytecode bytecode) {
     604             :     return bytecode == Bytecode::kReturn || IsJump(bytecode);
     605             :   }
     606             : 
     607             :   // Return true if |bytecode| is a jump without effects,
     608             :   // e.g.  any jump excluding those that include type coercion like
     609             :   // JumpIfTrueToBoolean.
     610             :   static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) {
     611    24206847 :     return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
     612             :   }
     613             : 
     614             :   // Returns true if |bytecode| has no effects. These bytecodes only manipulate
     615             :   // interpreter frame state and will never throw.
     616    41893899 :   static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {
     617    74903205 :     return (IsAccumulatorLoadWithoutEffects(bytecode) ||
     618    23039329 :             IsRegisterLoadWithoutEffects(bytecode) ||
     619    87331619 :             IsCompareWithoutEffects(bytecode) || bytecode == Bytecode::kNop ||
     620    41893894 :             IsJumpWithoutEffects(bytecode));
     621             :   }
     622             : 
     623             :   // Returns true if the bytecode is Ldar or Star.
     624             :   static constexpr bool IsLdarOrStar(Bytecode bytecode) {
     625             :     return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
     626             :   }
     627             : 
     628             :   // Returns true if the bytecode is a call or a constructor call.
     629    63186004 :   static constexpr bool IsCallOrConstruct(Bytecode bytecode) {
     630             :     return bytecode == Bytecode::kCallAnyReceiver ||
     631             :            bytecode == Bytecode::kCallProperty ||
     632             :            bytecode == Bytecode::kCallProperty0 ||
     633             :            bytecode == Bytecode::kCallProperty1 ||
     634             :            bytecode == Bytecode::kCallProperty2 ||
     635             :            bytecode == Bytecode::kCallUndefinedReceiver ||
     636             :            bytecode == Bytecode::kCallUndefinedReceiver0 ||
     637    63186004 :            bytecode == Bytecode::kCallUndefinedReceiver1 ||
     638    63186004 :            bytecode == Bytecode::kCallUndefinedReceiver2 ||
     639    63186004 :            bytecode == Bytecode::kTailCall ||
     640   120292320 :            bytecode == Bytecode::kConstruct ||
     641    60146160 :            bytecode == Bytecode::kCallWithSpread ||
     642   120173764 :            bytecode == Bytecode::kConstructWithSpread ||
     643   183259427 :            bytecode == Bytecode::kInvokeIntrinsic ||
     644    63186004 :            bytecode == Bytecode::kCallJSRuntime;
     645             :   }
     646             : 
     647             :   // Returns true if the bytecode is a call to the runtime.
     648             :   static constexpr bool IsCallRuntime(Bytecode bytecode) {
     649      337370 :     return bytecode == Bytecode::kCallRuntime ||
     650             :            bytecode == Bytecode::kCallRuntimeForPair ||
     651      337370 :            bytecode == Bytecode::kInvokeIntrinsic;
     652             :   }
     653             : 
     654             :   // Returns true if the bytecode is a scaling prefix bytecode.
     655             :   static constexpr bool IsPrefixScalingBytecode(Bytecode bytecode) {
     656   100446178 :     return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
     657   100446178 :            bytecode == Bytecode::kDebugBreakExtraWide ||
     658             :            bytecode == Bytecode::kDebugBreakWide;
     659             :   }
     660             : 
     661             :   // Returns the number of values which |bytecode| returns.
     662             :   static constexpr size_t ReturnCount(Bytecode bytecode) {
     663       18533 :     return bytecode == Bytecode::kReturn ? 1 : 0;
     664             :   }
     665             : 
     666             :   // Returns the number of operands expected by |bytecode|.
     667             :   static int NumberOfOperands(Bytecode bytecode) {
     668             :     DCHECK(bytecode <= Bytecode::kLast);
     669    32463142 :     return kOperandCount[static_cast<size_t>(bytecode)];
     670             :   }
     671             : 
     672             :   // Returns the i-th operand of |bytecode|.
     673             :   static OperandType GetOperandType(Bytecode bytecode, int i) {
     674             :     DCHECK_LE(bytecode, Bytecode::kLast);
     675             :     DCHECK_LT(i, NumberOfOperands(bytecode));
     676             :     DCHECK_GE(i, 0);
     677    27670417 :     return GetOperandTypes(bytecode)[i];
     678             :   }
     679             : 
     680             :   // Returns a pointer to an array of operand types terminated in
     681             :   // OperandType::kNone.
     682             :   static const OperandType* GetOperandTypes(Bytecode bytecode) {
     683             :     DCHECK(bytecode <= Bytecode::kLast);
     684    46375574 :     return kOperandTypes[static_cast<size_t>(bytecode)];
     685             :   }
     686             : 
     687     3069381 :   static bool OperandIsScalableSignedByte(Bytecode bytecode,
     688             :                                           int operand_index) {
     689             :     DCHECK(bytecode <= Bytecode::kLast);
     690     3088409 :     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
     691     3069381 :            OperandTypeInfo::kScalableSignedByte;
     692             :   }
     693             : 
     694     3069381 :   static bool OperandIsScalableUnsignedByte(Bytecode bytecode,
     695             :                                             int operand_index) {
     696             :     DCHECK(bytecode <= Bytecode::kLast);
     697     3069381 :     return kOperandTypeInfos[static_cast<size_t>(bytecode)][operand_index] ==
     698     3069381 :            OperandTypeInfo::kScalableUnsignedByte;
     699             :   }
     700             : 
     701             :   static bool OperandIsScalable(Bytecode bytecode, int operand_index) {
     702       19028 :     return OperandIsScalableSignedByte(bytecode, operand_index) ||
     703             :            OperandIsScalableUnsignedByte(bytecode, operand_index);
     704             :   }
     705             : 
     706             :   // Returns true if the bytecode has wider operand forms.
     707             :   static bool IsBytecodeWithScalableOperands(Bytecode bytecode);
     708             : 
     709             :   // Returns the size of the i-th operand of |bytecode|.
     710    13735049 :   static OperandSize GetOperandSize(Bytecode bytecode, int i,
     711             :                                     OperandScale operand_scale) {
     712    13735049 :     CHECK_LT(i, NumberOfOperands(bytecode));
     713    13735049 :     return GetOperandSizes(bytecode, operand_scale)[i];
     714             :   }
     715             : 
     716             :   // Returns the operand sizes of |bytecode| with scale |operand_scale|.
     717             :   static const OperandSize* GetOperandSizes(Bytecode bytecode,
     718             :                                             OperandScale operand_scale) {
     719             :     DCHECK(bytecode <= Bytecode::kLast);
     720             :     DCHECK_GE(operand_scale, OperandScale::kSingle);
     721             :     DCHECK_LE(operand_scale, OperandScale::kLast);
     722             :     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
     723             :                   OperandScale::kLast == OperandScale::kQuadruple);
     724    86457651 :     int scale_index = static_cast<int>(operand_scale) >> 1;
     725    86457651 :     return kOperandSizes[static_cast<size_t>(bytecode)][scale_index];
     726             :   }
     727             : 
     728             :   // Returns the offset of the i-th operand of |bytecode| relative to the start
     729             :   // of the bytecode.
     730             :   static int GetOperandOffset(Bytecode bytecode, int i,
     731             :                               OperandScale operand_scale);
     732             : 
     733             :   // Returns the size of the bytecode including its operands for the
     734             :   // given |operand_scale|.
     735             :   static int Size(Bytecode bytecode, OperandScale operand_scale) {
     736             :     DCHECK(bytecode <= Bytecode::kLast);
     737             :     STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
     738             :                   OperandScale::kLast == OperandScale::kQuadruple);
     739    30164070 :     int scale_index = static_cast<int>(operand_scale) >> 1;
     740    33054784 :     return kBytecodeSizes[static_cast<size_t>(bytecode)][scale_index];
     741             :   }
     742             : 
     743             :   // Returns a debug break bytecode to replace |bytecode|.
     744             :   static Bytecode GetDebugBreak(Bytecode bytecode);
     745             : 
     746             :   // Returns the equivalent jump bytecode without the accumulator coercion.
     747             :   static Bytecode GetJumpWithoutToBoolean(Bytecode bytecode);
     748             : 
     749             :   // Returns true if there is a call in the most-frequently executed path
     750             :   // through the bytecode's handler.
     751             :   static bool MakesCallAlongCriticalPath(Bytecode bytecode);
     752             : 
     753             :   // Returns the receiver mode of the given call bytecode.
     754             :   static ConvertReceiverMode GetReceiverMode(Bytecode bytecode) {
     755             :     DCHECK(IsCallOrConstruct(bytecode));
     756             :     switch (bytecode) {
     757             :       case Bytecode::kCallProperty:
     758             :       case Bytecode::kCallProperty0:
     759             :       case Bytecode::kCallProperty1:
     760             :       case Bytecode::kCallProperty2:
     761             :         return ConvertReceiverMode::kNotNullOrUndefined;
     762             :       case Bytecode::kCallUndefinedReceiver:
     763             :       case Bytecode::kCallUndefinedReceiver0:
     764             :       case Bytecode::kCallUndefinedReceiver1:
     765             :       case Bytecode::kCallUndefinedReceiver2:
     766             :         return ConvertReceiverMode::kNullOrUndefined;
     767             :       case Bytecode::kCallAnyReceiver:
     768             :       case Bytecode::kTailCall:
     769             :       case Bytecode::kConstruct:
     770             :       case Bytecode::kCallWithSpread:
     771             :       case Bytecode::kConstructWithSpread:
     772             :       case Bytecode::kInvokeIntrinsic:
     773             :       case Bytecode::kCallJSRuntime:
     774             :         return ConvertReceiverMode::kAny;
     775             :       default:
     776             :         UNREACHABLE();
     777             :         return ConvertReceiverMode::kAny;
     778             :     }
     779             :   }
     780             : 
     781             :   // Returns true if the bytecode is a debug break.
     782             :   static bool IsDebugBreak(Bytecode bytecode);
     783             : 
     784             :   // Returns true if |operand_type| is any type of register operand.
     785             :   static bool IsRegisterOperandType(OperandType operand_type);
     786             : 
     787             :   // Returns true if |operand_type| represents a register used as an input.
     788             :   static bool IsRegisterInputOperandType(OperandType operand_type);
     789             : 
     790             :   // Returns true if |operand_type| represents a register used as an output.
     791             :   static bool IsRegisterOutputOperandType(OperandType operand_type);
     792             : 
     793             :   // Returns true if the handler for |bytecode| should look ahead and inline a
     794             :   // dispatch to a Star bytecode.
     795             :   static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale);
     796             : 
     797             :   // Returns the number of registers represented by a register operand. For
     798             :   // instance, a RegPair represents two registers. Should not be called for
     799             :   // kRegList which has a variable number of registers based on the following
     800             :   // kRegCount operand.
     801          39 :   static int GetNumberOfRegistersRepresentedBy(OperandType operand_type) {
     802          39 :     switch (operand_type) {
     803             :       case OperandType::kReg:
     804             :       case OperandType::kRegOut:
     805             :         return 1;
     806             :       case OperandType::kRegPair:
     807             :       case OperandType::kRegOutPair:
     808           4 :         return 2;
     809             :       case OperandType::kRegOutTriple:
     810           3 :         return 3;
     811             :       case OperandType::kRegList:
     812           0 :         UNREACHABLE();
     813             :         return 0;
     814             :       default:
     815           0 :         return 0;
     816             :     }
     817             :     UNREACHABLE();
     818             :     return 0;
     819             :   }
     820             : 
     821             :   // Returns the size of |operand| for |operand_scale|.
     822             :   static OperandSize SizeOfOperand(OperandType operand, OperandScale scale);
     823             : 
     824             :   // Returns true if |operand_type| is a runtime-id operand (kRuntimeId).
     825             :   static bool IsRuntimeIdOperandType(OperandType operand_type);
     826             : 
     827             :   // Returns true if |operand_type| is unsigned, false if signed.
     828             :   static bool IsUnsignedOperandType(OperandType operand_type);
     829             : 
     830             :   // Returns true if a handler is generated for a bytecode at a given
     831             :   // operand scale. All bytecodes have handlers at OperandScale::kSingle,
     832             :   // but only bytecodes with scalable operands have handlers with larger
     833             :   // OperandScale values.
     834             :   static bool BytecodeHasHandler(Bytecode bytecode, OperandScale operand_scale);
     835             : 
     836             :   // Return the operand scale required to hold a signed operand with |value|.
     837    51004873 :   static OperandScale ScaleForSignedOperand(int32_t value) {
     838    51004873 :     if (value >= kMinInt8 && value <= kMaxInt8) {
     839             :       return OperandScale::kSingle;
     840     6838079 :     } else if (value >= kMinInt16 && value <= kMaxInt16) {
     841             :       return OperandScale::kDouble;
     842             :     } else {
     843      173919 :       return OperandScale::kQuadruple;
     844             :     }
     845             :   }
     846             : 
     847             :   // Return the operand scale required to hold an unsigned operand with |value|.
     848    49425053 :   static OperandScale ScaleForUnsignedOperand(uint32_t value) {
     849    52494430 :     if (value <= kMaxUInt8) {
     850             :       return OperandScale::kSingle;
     851     5257861 :     } else if (value <= kMaxUInt16) {
     852             :       return OperandScale::kDouble;
     853             :     } else {
     854          16 :       return OperandScale::kQuadruple;
     855             :     }
     856             :   }
     857             : 
     858             :   // Return the operand size required to hold an unsigned operand with |value|.
     859             :   static OperandSize SizeForUnsignedOperand(uint32_t value) {
     860             :     if (value <= kMaxUInt8) {
     861             :       return OperandSize::kByte;
     862             :     } else if (value <= kMaxUInt16) {
     863             :       return OperandSize::kShort;
     864             :     } else {
     865             :       return OperandSize::kQuad;
     866             :     }
     867             :   }
     868             : 
     869             :  private:
     870             :   static const OperandType* const kOperandTypes[];
     871             :   static const OperandTypeInfo* const kOperandTypeInfos[];
     872             :   static const int kOperandCount[];
     873             :   static const int kNumberOfRegisterOperands[];
     874             :   static const AccumulatorUse kAccumulatorUse[];
     875             :   static const bool kIsScalable[];
     876             :   static const int kBytecodeSizes[][3];
     877             :   static const OperandSize* const kOperandSizes[][3];
     878             : };
     879             : 
     880             : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
     881             :                                            const Bytecode& bytecode);
     882             : 
     883             : }  // namespace interpreter
     884             : }  // namespace internal
     885             : }  // namespace v8
     886             : 
     887             : #endif  // V8_INTERPRETER_BYTECODES_H_

Generated by: LCOV version 1.10