LCOV - code coverage report
Current view: top level - src/interpreter - bytecodes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 44 57 77.2 %
Date: 2017-10-20 Functions: 12 15 80.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             : #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      158886 : const char* Bytecodes::ToString(Bytecode bytecode) {
      99      158886 :   switch (bytecode) {
     100             : #define CASE(Name, ...)   \
     101             :   case Bytecode::k##Name: \
     102             :     return #Name;
     103        7402 :     BYTECODE_LIST(CASE)
     104             : #undef CASE
     105             :   }
     106           0 :   UNREACHABLE();
     107             : }
     108             : 
     109             : // static
     110       23491 : std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
     111             :   static const char kSeparator = '.';
     112             : 
     113       23491 :   std::string value(ToString(bytecode));
     114       23491 :   if (operand_scale > OperandScale::kSingle) {
     115       14548 :     Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
     116       14548 :     std::string suffix = ToString(prefix_bytecode);
     117       14548 :     return value.append(1, kSeparator).append(suffix);
     118             :   } else {
     119             :     return value;
     120             :   }
     121             : }
     122             : 
     123             : // static
     124     3677185 : Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
     125             :   DCHECK(!IsDebugBreak(bytecode));
     126     3677185 :   if (bytecode == Bytecode::kWide) {
     127             :     return Bytecode::kDebugBreakWide;
     128             :   }
     129     2831007 :   if (bytecode == Bytecode::kExtraWide) {
     130             :     return Bytecode::kDebugBreakExtraWide;
     131             :   }
     132             :   int bytecode_size = Size(bytecode, OperandScale::kSingle);
     133             : #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name)                         \
     134             :   if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
     135             :     return Bytecode::k##Name;                                            \
     136             :   }
     137     2820566 :   DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
     138             : #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
     139           0 :   UNREACHABLE();
     140             : }
     141             : 
     142             : // static
     143    34017338 : int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
     144             :                                 OperandScale operand_scale) {
     145             :   DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
     146             :   // TODO(oth): restore this to a statically determined constant.
     147             :   int offset = 1;
     148    49324722 :   for (int operand_index = 0; operand_index < i; ++operand_index) {
     149             :     OperandSize operand_size =
     150    15307400 :         GetOperandSize(bytecode, operand_index, operand_scale);
     151    15307384 :     offset += static_cast<int>(operand_size);
     152             :   }
     153    34017322 :   return offset;
     154             : }
     155             : 
     156             : // static
     157           0 : Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
     158           0 :   switch (bytecode) {
     159             :     case Bytecode::kJumpIfToBooleanTrue:
     160             :       return Bytecode::kJumpIfTrue;
     161             :     case Bytecode::kJumpIfToBooleanFalse:
     162           0 :       return Bytecode::kJumpIfFalse;
     163             :     case Bytecode::kJumpIfToBooleanTrueConstant:
     164           0 :       return Bytecode::kJumpIfTrueConstant;
     165             :     case Bytecode::kJumpIfToBooleanFalseConstant:
     166           0 :       return Bytecode::kJumpIfFalseConstant;
     167             :     default:
     168             :       break;
     169             :   }
     170           0 :   UNREACHABLE();
     171             : }
     172             : 
     173             : // static
     174     3704745 : bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
     175     3704745 :   switch (bytecode) {
     176             : #define CASE(Name, ...) case Bytecode::k##Name:
     177             :     DEBUG_BREAK_BYTECODE_LIST(CASE);
     178             : #undef CASE
     179             :     return true;
     180             :     default:
     181             :       break;
     182             :   }
     183     3677417 :   return false;
     184             : }
     185             : 
     186             : // static
     187      121256 : bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
     188      121256 :   switch (operand_type) {
     189             : #define CASE(Name, _)        \
     190             :   case OperandType::k##Name: \
     191             :     return true;
     192             :     REGISTER_OPERAND_TYPE_LIST(CASE)
     193             : #undef CASE
     194             : #define CASE(Name, _)        \
     195             :   case OperandType::k##Name: \
     196             :     break;
     197             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     198             : #undef CASE
     199             :   }
     200       63504 :   return false;
     201             : }
     202             : 
     203      261131 : bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) {
     204      505515 :   if (IsCallOrConstruct(bytecode) || IsCallRuntime(bytecode)) return true;
     205             :   switch (bytecode) {
     206             :     case Bytecode::kCreateWithContext:
     207             :     case Bytecode::kCreateBlockContext:
     208             :     case Bytecode::kCreateCatchContext:
     209             :     case Bytecode::kCreateRegExpLiteral:
     210             :       return true;
     211             :     default:
     212      229994 :       return false;
     213             :   }
     214             : }
     215             : 
     216             : // static
     217           4 : bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
     218           4 :   switch (operand_type) {
     219             : #define CASE(Name, _)        \
     220             :   case OperandType::k##Name: \
     221             :     return true;
     222             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     223             : #undef CASE
     224             : #define CASE(Name, _)        \
     225             :   case OperandType::k##Name: \
     226             :     break;
     227             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     228             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     229             : #undef CASE
     230             :   }
     231           1 :   return false;
     232             : }
     233             : 
     234             : // static
     235           3 : bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
     236           3 :   switch (operand_type) {
     237             : #define CASE(Name, _)        \
     238             :   case OperandType::k##Name: \
     239             :     return true;
     240             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     241             : #undef CASE
     242             : #define CASE(Name, _)        \
     243             :   case OperandType::k##Name: \
     244             :     break;
     245             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     246             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     247             : #undef CASE
     248             :   }
     249           1 :   return false;
     250             : }
     251             : 
     252             : // static
     253       13764 : bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
     254       13764 :   if (operand_scale == OperandScale::kSingle) {
     255        5084 :     switch (bytecode) {
     256             :       case Bytecode::kLdaZero:
     257             :       case Bytecode::kLdaSmi:
     258             :       case Bytecode::kLdaNull:
     259             :       case Bytecode::kLdaTheHole:
     260             :       case Bytecode::kLdaConstant:
     261             :       case Bytecode::kLdaUndefined:
     262             :       case Bytecode::kLdaGlobal:
     263             :       case Bytecode::kLdaNamedProperty:
     264             :       case Bytecode::kLdaKeyedProperty:
     265             :       case Bytecode::kLdaContextSlot:
     266             :       case Bytecode::kLdaCurrentContextSlot:
     267             :       case Bytecode::kAdd:
     268             :       case Bytecode::kSub:
     269             :       case Bytecode::kMul:
     270             :       case Bytecode::kAddSmi:
     271             :       case Bytecode::kSubSmi:
     272             :       case Bytecode::kInc:
     273             :       case Bytecode::kDec:
     274             :       case Bytecode::kTypeOf:
     275             :       case Bytecode::kCallAnyReceiver:
     276             :       case Bytecode::kCallProperty:
     277             :       case Bytecode::kCallProperty0:
     278             :       case Bytecode::kCallProperty1:
     279             :       case Bytecode::kCallProperty2:
     280             :       case Bytecode::kCallUndefinedReceiver:
     281             :       case Bytecode::kCallUndefinedReceiver0:
     282             :       case Bytecode::kCallUndefinedReceiver1:
     283             :       case Bytecode::kCallUndefinedReceiver2:
     284             :       case Bytecode::kConstruct:
     285             :       case Bytecode::kConstructWithSpread:
     286             :         return true;
     287             :       default:
     288        4402 :         return false;
     289             :     }
     290             :   }
     291             :   return false;
     292             : }
     293             : 
     294             : // static
     295           0 : bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
     296       19136 :   for (int i = 0; i < NumberOfOperands(bytecode); i++) {
     297       15288 :     if (OperandIsScalable(bytecode, i)) return true;
     298             :   }
     299             :   return false;
     300             : }
     301             : 
     302             : // static
     303           0 : bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
     304           0 :   switch (operand_type) {
     305             : #define CASE(Name, _)        \
     306             :   case OperandType::k##Name: \
     307             :     return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
     308           0 :     OPERAND_TYPE_LIST(CASE)
     309             : #undef CASE
     310             :   }
     311           0 :   UNREACHABLE();
     312             : }
     313             : 
     314             : // static
     315       26832 : bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
     316             :                                    OperandScale operand_scale) {
     317       44720 :   return operand_scale == OperandScale::kSingle ||
     318       26832 :          Bytecodes::IsBytecodeWithScalableOperands(bytecode);
     319             : }
     320             : 
     321        1723 : std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
     322        1723 :   return os << Bytecodes::ToString(bytecode);
     323             : }
     324             : 
     325             : }  // namespace interpreter
     326             : }  // namespace internal
     327             : }  // namespace v8

Generated by: LCOV version 1.10