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

Generated by: LCOV version 1.10