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

Generated by: LCOV version 1.10