LCOV - code coverage report
Current view: top level - src/interpreter - bytecodes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 43 59 72.9 %
Date: 2019-04-19 Functions: 13 17 76.5 %

          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             : #include "src/interpreter/bytecodes.h"
       6             : 
       7             : #include <iomanip>
       8             : 
       9             : #include "src/base/bits.h"
      10             : #include "src/interpreter/bytecode-traits.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace interpreter {
      15             : 
      16             : // clang-format off
      17             : const OperandType* const Bytecodes::kOperandTypes[] = {
      18             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypes,
      19             :   BYTECODE_LIST(ENTRY)
      20             : #undef ENTRY
      21             : };
      22             : 
      23             : const OperandTypeInfo* const Bytecodes::kOperandTypeInfos[] = {
      24             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandTypeInfos,
      25             :   BYTECODE_LIST(ENTRY)
      26             : #undef ENTRY
      27             : };
      28             : 
      29             : const int Bytecodes::kOperandCount[] = {
      30             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kOperandCount,
      31             :   BYTECODE_LIST(ENTRY)
      32             : #undef ENTRY
      33             : };
      34             : 
      35             : const AccumulatorUse Bytecodes::kAccumulatorUse[] = {
      36             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kAccumulatorUse,
      37             :   BYTECODE_LIST(ENTRY)
      38             : #undef ENTRY
      39             : };
      40             : 
      41             : const int Bytecodes::kBytecodeSizes[3][kBytecodeCount] = {
      42             :   {
      43             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kSingleScaleSize,
      44             :   BYTECODE_LIST(ENTRY)
      45             : #undef ENTRY
      46             :   }, {
      47             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize,
      48             :   BYTECODE_LIST(ENTRY)
      49             : #undef ENTRY
      50             :   }, {
      51             : #define ENTRY(Name, ...) BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize,
      52             :   BYTECODE_LIST(ENTRY)
      53             : #undef ENTRY
      54             :   }
      55             : };
      56             : 
      57             : const OperandSize* const Bytecodes::kOperandSizes[3][kBytecodeCount] = {
      58             :   {
      59             : #define ENTRY(Name, ...)  \
      60             :     BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes,
      61             :   BYTECODE_LIST(ENTRY)
      62             : #undef ENTRY
      63             :   }, {
      64             : #define ENTRY(Name, ...)  \
      65             :     BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes,
      66             :   BYTECODE_LIST(ENTRY)
      67             : #undef ENTRY
      68             :   }, {
      69             : #define ENTRY(Name, ...)  \
      70             :     BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes,
      71             :   BYTECODE_LIST(ENTRY)
      72             : #undef ENTRY
      73             :   }
      74             : };
      75             : 
      76             : const OperandSize
      77             : Bytecodes::kOperandKindSizes[3][BytecodeOperands::kOperandTypeCount] = {
      78             :   {
      79             : #define ENTRY(Name, ...)  \
      80             :     OperandScaler<OperandType::k##Name, OperandScale::kSingle>::kOperandSize,
      81             :   OPERAND_TYPE_LIST(ENTRY)
      82             : #undef ENTRY
      83             :   }, {
      84             : #define ENTRY(Name, ...)  \
      85             :     OperandScaler<OperandType::k##Name, OperandScale::kDouble>::kOperandSize,
      86             :   OPERAND_TYPE_LIST(ENTRY)
      87             : #undef ENTRY
      88             :   }, {
      89             : #define ENTRY(Name, ...)  \
      90             :     OperandScaler<OperandType::k##Name, OperandScale::kQuadruple>::kOperandSize,
      91             :   OPERAND_TYPE_LIST(ENTRY)
      92             : #undef ENTRY
      93             :   }
      94             : };
      95             : // clang-format on
      96             : 
      97             : // static
      98      147368 : const char* Bytecodes::ToString(Bytecode bytecode) {
      99      147368 :   switch (bytecode) {
     100             : #define CASE(Name, ...)   \
     101             :   case Bytecode::k##Name: \
     102             :     return #Name;
     103        8535 :     BYTECODE_LIST(CASE)
     104             : #undef CASE
     105             :   }
     106           0 :   UNREACHABLE();
     107             : }
     108             : 
     109             : // static
     110       27095 : std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale,
     111             :                                 const char* separator) {
     112       27095 :   std::string value(ToString(bytecode));
     113       27095 :   if (operand_scale > OperandScale::kSingle) {
     114             :     Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
     115       16766 :     std::string suffix = ToString(prefix_bytecode);
     116       16766 :     return value.append(separator).append(suffix);
     117             :   } else {
     118             :     return value;
     119             :   }
     120             : }
     121             : 
     122             : // static
     123     3776688 : Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
     124             :   DCHECK(!IsDebugBreak(bytecode));
     125     3776688 :   if (bytecode == Bytecode::kWide) {
     126             :     return Bytecode::kDebugBreakWide;
     127             :   }
     128     2914237 :   if (bytecode == Bytecode::kExtraWide) {
     129             :     return Bytecode::kDebugBreakExtraWide;
     130             :   }
     131             :   int bytecode_size = Size(bytecode, OperandScale::kSingle);
     132             : #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name)                         \
     133             :   if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
     134             :     return Bytecode::k##Name;                                            \
     135             :   }
     136     2903796 :   DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
     137             : #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
     138           0 :   UNREACHABLE();
     139             : }
     140             : 
     141             : // static
     142    30999034 : int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
     143             :                                 OperandScale operand_scale) {
     144             :   DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
     145             :   // TODO(oth): restore this to a statically determined constant.
     146             :   int offset = 1;
     147    57757244 :   for (int operand_index = 0; operand_index < i; ++operand_index) {
     148             :     OperandSize operand_size =
     149             :         GetOperandSize(bytecode, operand_index, operand_scale);
     150    13379105 :     offset += static_cast<int>(operand_size);
     151             :   }
     152    30999034 :   return offset;
     153             : }
     154             : 
     155             : // static
     156           0 : Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
     157           0 :   switch (bytecode) {
     158             :     case Bytecode::kJumpIfToBooleanTrue:
     159             :       return Bytecode::kJumpIfTrue;
     160             :     case Bytecode::kJumpIfToBooleanFalse:
     161           0 :       return Bytecode::kJumpIfFalse;
     162             :     case Bytecode::kJumpIfToBooleanTrueConstant:
     163           0 :       return Bytecode::kJumpIfTrueConstant;
     164             :     case Bytecode::kJumpIfToBooleanFalseConstant:
     165           0 :       return Bytecode::kJumpIfFalseConstant;
     166             :     default:
     167             :       break;
     168             :   }
     169           0 :   UNREACHABLE();
     170             : }
     171             : 
     172             : // static
     173     3807859 : bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
     174     3807859 :   switch (bytecode) {
     175             : #define CASE(Name, ...) case Bytecode::k##Name:
     176             :     DEBUG_BREAK_BYTECODE_LIST(CASE);
     177             : #undef CASE
     178             :     return true;
     179             :     default:
     180             :       break;
     181             :   }
     182     3776936 :   return false;
     183             : }
     184             : 
     185             : // static
     186       82587 : bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
     187       82587 :   switch (operand_type) {
     188             : #define CASE(Name, _)        \
     189             :   case OperandType::k##Name: \
     190             :     return true;
     191             :     REGISTER_OPERAND_TYPE_LIST(CASE)
     192             : #undef CASE
     193             : #define CASE(Name, _)        \
     194             :   case OperandType::k##Name: \
     195             :     break;
     196             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     197             : #undef CASE
     198             :   }
     199       40695 :   return false;
     200             : }
     201             : 
     202             : // static
     203           0 : bool Bytecodes::IsRegisterListOperandType(OperandType operand_type) {
     204           0 :   switch (operand_type) {
     205             :     case OperandType::kRegList:
     206             :     case OperandType::kRegOutList:
     207             :       return true;
     208             :     default:
     209           0 :       return false;
     210             :   }
     211             : }
     212             : 
     213      522381 : bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) {
     214     1017345 :   if (IsCallOrConstruct(bytecode) || IsCallRuntime(bytecode)) return true;
     215             :   switch (bytecode) {
     216             :     case Bytecode::kCreateWithContext:
     217             :     case Bytecode::kCreateBlockContext:
     218             :     case Bytecode::kCreateCatchContext:
     219             :     case Bytecode::kCreateRegExpLiteral:
     220             :       return true;
     221             :     default:
     222      474455 :       return false;
     223             :   }
     224             : }
     225             : 
     226             : // static
     227           4 : bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
     228           4 :   switch (operand_type) {
     229             : #define CASE(Name, _)        \
     230             :   case OperandType::k##Name: \
     231             :     return true;
     232             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     233             : #undef CASE
     234             : #define CASE(Name, _)        \
     235             :   case OperandType::k##Name: \
     236             :     break;
     237             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     238             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     239             : #undef CASE
     240             :   }
     241           1 :   return false;
     242             : }
     243             : 
     244             : // static
     245           3 : bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
     246           3 :   switch (operand_type) {
     247             : #define CASE(Name, _)        \
     248             :   case OperandType::k##Name: \
     249             :     return true;
     250             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     251             : #undef CASE
     252             : #define CASE(Name, _)        \
     253             :   case OperandType::k##Name: \
     254             :     break;
     255             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     256             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     257             : #undef CASE
     258             :   }
     259           1 :   return false;
     260             : }
     261             : 
     262             : // static
     263       38360 : bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
     264       38360 :   if (operand_scale == OperandScale::kSingle) {
     265       13720 :     switch (bytecode) {
     266             :       case Bytecode::kLdaZero:
     267             :       case Bytecode::kLdaSmi:
     268             :       case Bytecode::kLdaNull:
     269             :       case Bytecode::kLdaTheHole:
     270             :       case Bytecode::kLdaConstant:
     271             :       case Bytecode::kLdaUndefined:
     272             :       case Bytecode::kLdaGlobal:
     273             :       case Bytecode::kLdaNamedProperty:
     274             :       case Bytecode::kLdaKeyedProperty:
     275             :       case Bytecode::kLdaContextSlot:
     276             :       case Bytecode::kLdaCurrentContextSlot:
     277             :       case Bytecode::kAdd:
     278             :       case Bytecode::kSub:
     279             :       case Bytecode::kMul:
     280             :       case Bytecode::kAddSmi:
     281             :       case Bytecode::kSubSmi:
     282             :       case Bytecode::kInc:
     283             :       case Bytecode::kDec:
     284             :       case Bytecode::kTypeOf:
     285             :       case Bytecode::kCallAnyReceiver:
     286             :       case Bytecode::kCallNoFeedback:
     287             :       case Bytecode::kCallProperty:
     288             :       case Bytecode::kCallProperty0:
     289             :       case Bytecode::kCallProperty1:
     290             :       case Bytecode::kCallProperty2:
     291             :       case Bytecode::kCallUndefinedReceiver:
     292             :       case Bytecode::kCallUndefinedReceiver0:
     293             :       case Bytecode::kCallUndefinedReceiver1:
     294             :       case Bytecode::kCallUndefinedReceiver2:
     295             :       case Bytecode::kConstruct:
     296             :       case Bytecode::kConstructWithSpread:
     297             :         return true;
     298             :       default:
     299       11480 :         return false;
     300             :     }
     301             :   }
     302             :   return false;
     303             : }
     304             : 
     305             : // static
     306           0 : bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
     307    23977601 :   for (int i = 0; i < NumberOfOperands(bytecode); i++) {
     308    19107193 :     if (OperandIsScalable(bytecode, i)) return true;
     309             :   }
     310             :   return false;
     311             : }
     312             : 
     313             : // static
     314           0 : bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
     315           0 :   switch (operand_type) {
     316             : #define CASE(Name, _)        \
     317             :   case OperandType::k##Name: \
     318             :     return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
     319           0 :     OPERAND_TYPE_LIST(CASE)
     320             : #undef CASE
     321             :   }
     322           0 :   UNREACHABLE();
     323             : }
     324             : 
     325             : // static
     326    33718178 : bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
     327             :                                    OperandScale operand_scale) {
     328    56197149 :   return operand_scale == OperandScale::kSingle ||
     329    33718178 :          Bytecodes::IsBytecodeWithScalableOperands(bytecode);
     330             : }
     331             : 
     332        1263 : std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
     333        1263 :   return os << Bytecodes::ToString(bytecode);
     334             : }
     335             : 
     336             : }  // namespace interpreter
     337             : }  // namespace internal
     338      122038 : }  // namespace v8

Generated by: LCOV version 1.10