LCOV - code coverage report
Current view: top level - src/interpreter - bytecodes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 46 59 78.0 %
Date: 2017-04-26 Functions: 13 16 81.2 %

          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] = {
      42             : #define ENTRY(Name, ...)                            \
      43             :   { BytecodeTraits<__VA_ARGS__>::kSingleScaleSize,  \
      44             :     BytecodeTraits<__VA_ARGS__>::kDoubleScaleSize,  \
      45             :     BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleSize },
      46             :   BYTECODE_LIST(ENTRY)
      47             : #undef ENTRY
      48             : };
      49             : 
      50             : const OperandSize* const Bytecodes::kOperandSizes[][3] = {
      51             : #define ENTRY(Name, ...)                                    \
      52             :   { BytecodeTraits<__VA_ARGS__>::kSingleScaleOperandSizes,  \
      53             :     BytecodeTraits<__VA_ARGS__>::kDoubleScaleOperandSizes,  \
      54             :     BytecodeTraits<__VA_ARGS__>::kQuadrupleScaleOperandSizes },
      55             :   BYTECODE_LIST(ENTRY)
      56             : #undef ENTRY
      57             : };
      58             : // clang-format on
      59             : 
      60             : // static
      61      210022 : const char* Bytecodes::ToString(Bytecode bytecode) {
      62      210022 :   switch (bytecode) {
      63             : #define CASE(Name, ...)   \
      64             :   case Bytecode::k##Name: \
      65             :     return #Name;
      66        9205 :     BYTECODE_LIST(CASE)
      67             : #undef CASE
      68             :   }
      69           0 :   UNREACHABLE();
      70             :   return "";
      71             : }
      72             : 
      73             : // static
      74       29086 : std::string Bytecodes::ToString(Bytecode bytecode, OperandScale operand_scale) {
      75             :   static const char kSeparator = '.';
      76             : 
      77       29086 :   std::string value(ToString(bytecode));
      78       29086 :   if (operand_scale > OperandScale::kSingle) {
      79       18060 :     Bytecode prefix_bytecode = OperandScaleToPrefixBytecode(operand_scale);
      80       18060 :     std::string suffix = ToString(prefix_bytecode);
      81       18060 :     return value.append(1, kSeparator).append(suffix);
      82             :   } else {
      83             :     return value;
      84             :   }
      85             : }
      86             : 
      87             : // static
      88     3651854 : Bytecode Bytecodes::GetDebugBreak(Bytecode bytecode) {
      89             :   DCHECK(!IsDebugBreak(bytecode));
      90     3651854 :   if (bytecode == Bytecode::kWide) {
      91             :     return Bytecode::kDebugBreakWide;
      92             :   }
      93     2899995 :   if (bytecode == Bytecode::kExtraWide) {
      94             :     return Bytecode::kDebugBreakExtraWide;
      95             :   }
      96             :   int bytecode_size = Size(bytecode, OperandScale::kSingle);
      97             : #define RETURN_IF_DEBUG_BREAK_SIZE_MATCHES(Name)                         \
      98             :   if (bytecode_size == Size(Bytecode::k##Name, OperandScale::kSingle)) { \
      99             :     return Bytecode::k##Name;                                            \
     100             :   }
     101     2890714 :   DEBUG_BREAK_PLAIN_BYTECODE_LIST(RETURN_IF_DEBUG_BREAK_SIZE_MATCHES)
     102             : #undef RETURN_IF_DEBUG_BREAK_SIZE_MATCHES
     103           0 :   UNREACHABLE();
     104             :   return Bytecode::kIllegal;
     105             : }
     106             : 
     107             : // static
     108    32282682 : int Bytecodes::GetOperandOffset(Bytecode bytecode, int i,
     109             :                                 OperandScale operand_scale) {
     110             :   DCHECK_LT(i, Bytecodes::NumberOfOperands(bytecode));
     111             :   // TODO(oth): restore this to a statically determined constant.
     112             :   int offset = 1;
     113    45981726 :   for (int operand_index = 0; operand_index < i; ++operand_index) {
     114             :     OperandSize operand_size =
     115    13699046 :         GetOperandSize(bytecode, operand_index, operand_scale);
     116    13699044 :     offset += static_cast<int>(operand_size);
     117             :   }
     118    32282680 :   return offset;
     119             : }
     120             : 
     121             : // static
     122           0 : Bytecode Bytecodes::GetJumpWithoutToBoolean(Bytecode bytecode) {
     123           0 :   switch (bytecode) {
     124             :     case Bytecode::kJumpIfToBooleanTrue:
     125             :       return Bytecode::kJumpIfTrue;
     126             :     case Bytecode::kJumpIfToBooleanFalse:
     127           0 :       return Bytecode::kJumpIfFalse;
     128             :     case Bytecode::kJumpIfToBooleanTrueConstant:
     129           0 :       return Bytecode::kJumpIfTrueConstant;
     130             :     case Bytecode::kJumpIfToBooleanFalseConstant:
     131           0 :       return Bytecode::kJumpIfFalseConstant;
     132             :     default:
     133             :       break;
     134             :   }
     135           0 :   UNREACHABLE();
     136             :   return Bytecode::kIllegal;
     137             : }
     138             : 
     139             : // static
     140     3675325 : bool Bytecodes::IsDebugBreak(Bytecode bytecode) {
     141     3675325 :   switch (bytecode) {
     142             : #define CASE(Name, ...) case Bytecode::k##Name:
     143             :     DEBUG_BREAK_BYTECODE_LIST(CASE);
     144             : #undef CASE
     145             :     return true;
     146             :     default:
     147             :       break;
     148             :   }
     149     3652075 :   return false;
     150             : }
     151             : 
     152             : // static
     153      155948 : bool Bytecodes::IsRegisterOperandType(OperandType operand_type) {
     154      155948 :   switch (operand_type) {
     155             : #define CASE(Name, _)        \
     156             :   case OperandType::k##Name: \
     157             :     return true;
     158             :     REGISTER_OPERAND_TYPE_LIST(CASE)
     159             : #undef CASE
     160             : #define CASE(Name, _)        \
     161             :   case OperandType::k##Name: \
     162             :     break;
     163             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     164             : #undef CASE
     165             :   }
     166       80619 :   return false;
     167             : }
     168             : 
     169      268572 : bool Bytecodes::MakesCallAlongCriticalPath(Bytecode bytecode) {
     170      502802 :   if (IsCallOrConstruct(bytecode) || IsCallRuntime(bytecode)) return true;
     171             :   switch (bytecode) {
     172             :     case Bytecode::kCreateWithContext:
     173             :     case Bytecode::kCreateBlockContext:
     174             :     case Bytecode::kCreateCatchContext:
     175             :     case Bytecode::kCreateRegExpLiteral:
     176             :       return true;
     177             :     default:
     178             :       return false;
     179             :   }
     180             : }
     181             : 
     182             : // static
     183           4 : bool Bytecodes::IsRegisterInputOperandType(OperandType operand_type) {
     184           4 :   switch (operand_type) {
     185             : #define CASE(Name, _)        \
     186             :   case OperandType::k##Name: \
     187             :     return true;
     188             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     189             : #undef CASE
     190             : #define CASE(Name, _)        \
     191             :   case OperandType::k##Name: \
     192             :     break;
     193             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     194             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     195             : #undef CASE
     196             :   }
     197           1 :   return false;
     198             : }
     199             : 
     200             : // static
     201           3 : bool Bytecodes::IsRegisterOutputOperandType(OperandType operand_type) {
     202           3 :   switch (operand_type) {
     203             : #define CASE(Name, _)        \
     204             :   case OperandType::k##Name: \
     205             :     return true;
     206             :     REGISTER_OUTPUT_OPERAND_TYPE_LIST(CASE)
     207             : #undef CASE
     208             : #define CASE(Name, _)        \
     209             :   case OperandType::k##Name: \
     210             :     break;
     211             :     NON_REGISTER_OPERAND_TYPE_LIST(CASE)
     212             :     REGISTER_INPUT_OPERAND_TYPE_LIST(CASE)
     213             : #undef CASE
     214             :   }
     215           1 :   return false;
     216             : }
     217             : 
     218             : // static
     219       19651 : bool Bytecodes::IsStarLookahead(Bytecode bytecode, OperandScale operand_scale) {
     220       19651 :   if (operand_scale == OperandScale::kSingle) {
     221        7181 :     switch (bytecode) {
     222             :       case Bytecode::kLdaZero:
     223             :       case Bytecode::kLdaSmi:
     224             :       case Bytecode::kLdaNull:
     225             :       case Bytecode::kLdaTheHole:
     226             :       case Bytecode::kLdaConstant:
     227             :       case Bytecode::kLdaUndefined:
     228             :       case Bytecode::kLdaGlobal:
     229             :       case Bytecode::kLdaNamedProperty:
     230             :       case Bytecode::kLdaKeyedProperty:
     231             :       case Bytecode::kLdaContextSlot:
     232             :       case Bytecode::kLdaCurrentContextSlot:
     233             :       case Bytecode::kAdd:
     234             :       case Bytecode::kSub:
     235             :       case Bytecode::kMul:
     236             :       case Bytecode::kAddSmi:
     237             :       case Bytecode::kSubSmi:
     238             :       case Bytecode::kInc:
     239             :       case Bytecode::kDec:
     240             :       case Bytecode::kTypeOf:
     241             :       case Bytecode::kCallAnyReceiver:
     242             :       case Bytecode::kCallProperty:
     243             :       case Bytecode::kCallProperty0:
     244             :       case Bytecode::kCallProperty1:
     245             :       case Bytecode::kCallProperty2:
     246             :       case Bytecode::kCallUndefinedReceiver:
     247             :       case Bytecode::kCallUndefinedReceiver0:
     248             :       case Bytecode::kCallUndefinedReceiver1:
     249             :       case Bytecode::kCallUndefinedReceiver2:
     250             :       case Bytecode::kConstruct:
     251             :       case Bytecode::kConstructWithSpread:
     252             :         return true;
     253             :       default:
     254        5848 :         return false;
     255             :     }
     256             :   }
     257             :   return false;
     258             : }
     259             : 
     260             : // static
     261           0 : bool Bytecodes::IsBytecodeWithScalableOperands(Bytecode bytecode) {
     262       23718 :   for (int i = 0; i < NumberOfOperands(bytecode); i++) {
     263       19028 :     if (OperandIsScalable(bytecode, i)) return true;
     264             :   }
     265             :   return false;
     266             : }
     267             : 
     268             : // static
     269           0 : bool Bytecodes::IsUnsignedOperandType(OperandType operand_type) {
     270           0 :   switch (operand_type) {
     271             : #define CASE(Name, _)        \
     272             :   case OperandType::k##Name: \
     273             :     return OperandTraits<OperandType::k##Name>::TypeInfoTraits::kIsUnsigned;
     274           0 :     OPERAND_TYPE_LIST(CASE)
     275             : #undef CASE
     276             :   }
     277           0 :   UNREACHABLE();
     278             :   return false;
     279             : }
     280             : 
     281             : // static
     282    32246634 : OperandSize Bytecodes::SizeOfOperand(OperandType operand_type,
     283             :                                      OperandScale operand_scale) {
     284             :   DCHECK_LE(operand_type, OperandType::kLast);
     285             :   DCHECK_GE(operand_scale, OperandScale::kSingle);
     286             :   DCHECK_LE(operand_scale, OperandScale::kLast);
     287             :   STATIC_ASSERT(static_cast<int>(OperandScale::kQuadruple) == 4 &&
     288             :                 OperandScale::kLast == OperandScale::kQuadruple);
     289    32246634 :   int scale_index = static_cast<int>(operand_scale) >> 1;
     290             :   // clang-format off
     291             :   static const OperandSize kOperandSizes[][3] = {
     292             : #define ENTRY(Name, ...)                                \
     293             :   { OperandScaler<OperandType::k##Name,                 \
     294             :                  OperandScale::kSingle>::kOperandSize,  \
     295             :     OperandScaler<OperandType::k##Name,                 \
     296             :                  OperandScale::kDouble>::kOperandSize,  \
     297             :     OperandScaler<OperandType::k##Name,                 \
     298             :                  OperandScale::kQuadruple>::kOperandSize },
     299             :     OPERAND_TYPE_LIST(ENTRY)
     300             : #undef ENTRY
     301             :   };
     302             :   // clang-format on
     303    32246634 :   return kOperandSizes[static_cast<size_t>(operand_type)][scale_index];
     304             : }
     305             : 
     306             : // static
     307       33165 : bool Bytecodes::BytecodeHasHandler(Bytecode bytecode,
     308             :                                    OperandScale operand_scale) {
     309       55275 :   return operand_scale == OperandScale::kSingle ||
     310       33165 :          Bytecodes::IsBytecodeWithScalableOperands(bytecode);
     311             : }
     312             : 
     313        2478 : std::ostream& operator<<(std::ostream& os, const Bytecode& bytecode) {
     314        2478 :   return os << Bytecodes::ToString(bytecode);
     315             : }
     316             : 
     317             : }  // namespace interpreter
     318             : }  // namespace internal
     319             : }  // namespace v8

Generated by: LCOV version 1.10