LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-decoder.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 60 71 84.5 %
Date: 2017-04-26 Functions: 5 6 83.3 %

          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/bytecode-decoder.h"
       6             : 
       7             : #include <iomanip>
       8             : 
       9             : #include "src/interpreter/interpreter-intrinsics.h"
      10             : #include "src/objects-inl.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace interpreter {
      15             : 
      16             : // static
      17    20509127 : Register BytecodeDecoder::DecodeRegisterOperand(const uint8_t* operand_start,
      18             :                                                 OperandType operand_type,
      19             :                                                 OperandScale operand_scale) {
      20             :   DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
      21             :   int32_t operand =
      22    20509163 :       DecodeSignedOperand(operand_start, operand_type, operand_scale);
      23    20509123 :   return Register::FromOperand(operand);
      24             : }
      25             : 
      26             : // static
      27           0 : RegisterList BytecodeDecoder::DecodeRegisterListOperand(
      28             :     const uint8_t* operand_start, uint32_t count, OperandType operand_type,
      29             :     OperandScale operand_scale) {
      30             :   Register first_reg =
      31             :       DecodeRegisterOperand(operand_start, operand_type, operand_scale);
      32           3 :   return RegisterList(first_reg.index(), static_cast<int>(count));
      33             : }
      34             : 
      35             : // static
      36    21914948 : int32_t BytecodeDecoder::DecodeSignedOperand(const uint8_t* operand_start,
      37             :                                              OperandType operand_type,
      38             :                                              OperandScale operand_scale) {
      39             :   DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
      40    21914948 :   switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
      41             :     case OperandSize::kByte:
      42    18921892 :       return static_cast<int8_t>(*operand_start);
      43             :     case OperandSize::kShort:
      44     2964468 :       return static_cast<int16_t>(ReadUnalignedUInt16(operand_start));
      45             :     case OperandSize::kQuad:
      46       28586 :       return static_cast<int32_t>(ReadUnalignedUInt32(operand_start));
      47             :     case OperandSize::kNone:
      48           0 :       UNREACHABLE();
      49             :   }
      50             :   return 0;
      51             : }
      52             : 
      53             : // static
      54    10331023 : uint32_t BytecodeDecoder::DecodeUnsignedOperand(const uint8_t* operand_start,
      55             :                                                 OperandType operand_type,
      56             :                                                 OperandScale operand_scale) {
      57             :   DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
      58    10331023 :   switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
      59             :     case OperandSize::kByte:
      60     9808331 :       return *operand_start;
      61             :     case OperandSize::kShort:
      62      511707 :       return ReadUnalignedUInt16(operand_start);
      63             :     case OperandSize::kQuad:
      64       10990 :       return ReadUnalignedUInt32(operand_start);
      65             :     case OperandSize::kNone:
      66           0 :       UNREACHABLE();
      67             :   }
      68             :   return 0;
      69             : }
      70             : 
      71             : namespace {
      72           2 : const char* NameForRuntimeId(uint32_t idx) {
      73           2 :   switch (idx) {
      74             : #define CASE(name, nargs, ressize) \
      75             :   case Runtime::k##name:           \
      76             :     return #name;                  \
      77             :   case Runtime::kInline##name:     \
      78             :     return "_" #name;
      79           0 :     FOR_EACH_INTRINSIC(CASE)
      80             : #undef CASE
      81             :     default:
      82           0 :       UNREACHABLE();
      83             :       return nullptr;
      84             :   }
      85             : }
      86             : }  // anonymous namespace
      87             : 
      88             : // static
      89          65 : std::ostream& BytecodeDecoder::Decode(std::ostream& os,
      90             :                                       const uint8_t* bytecode_start,
      91             :                                       int parameter_count) {
      92          65 :   Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
      93             :   int prefix_offset = 0;
      94             :   OperandScale operand_scale = OperandScale::kSingle;
      95          65 :   if (Bytecodes::IsPrefixScalingBytecode(bytecode)) {
      96             :     prefix_offset = 1;
      97           8 :     operand_scale = Bytecodes::PrefixBytecodeToOperandScale(bytecode);
      98           8 :     bytecode = Bytecodes::FromByte(bytecode_start[1]);
      99             :   }
     100             : 
     101             :   // Prepare to print bytecode and operands as hex digits.
     102          65 :   std::ios saved_format(nullptr);
     103          65 :   saved_format.copyfmt(saved_format);
     104          65 :   os.fill('0');
     105          65 :   os.flags(std::ios::hex);
     106             : 
     107             :   int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
     108         230 :   for (int i = 0; i < prefix_offset + bytecode_size; i++) {
     109         165 :     os << std::setw(2) << static_cast<uint32_t>(bytecode_start[i]) << ' ';
     110             :   }
     111          65 :   os.copyfmt(saved_format);
     112             : 
     113             :   const int kBytecodeColumnSize = 6;
     114         297 :   for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
     115         232 :     os << "   ";
     116             :   }
     117             : 
     118         195 :   os << Bytecodes::ToString(bytecode, operand_scale) << " ";
     119             : 
     120             :   // Operands for the debug break are from the original instruction.
     121          65 :   if (Bytecodes::IsDebugBreak(bytecode)) return os;
     122             : 
     123             :   int number_of_operands = Bytecodes::NumberOfOperands(bytecode);
     124         133 :   for (int i = 0; i < number_of_operands; i++) {
     125             :     OperandType op_type = Bytecodes::GetOperandType(bytecode, i);
     126             :     int operand_offset =
     127          68 :         Bytecodes::GetOperandOffset(bytecode, i, operand_scale);
     128             :     const uint8_t* operand_start =
     129          68 :         &bytecode_start[prefix_offset + operand_offset];
     130          68 :     switch (op_type) {
     131             :       case interpreter::OperandType::kIdx:
     132             :       case interpreter::OperandType::kUImm:
     133          19 :         os << "["
     134          19 :            << DecodeUnsignedOperand(operand_start, op_type, operand_scale)
     135          19 :            << "]";
     136          19 :         break;
     137             :       case interpreter::OperandType::kIntrinsicId: {
     138             :         auto id = static_cast<IntrinsicsHelper::IntrinsicId>(
     139           0 :             DecodeUnsignedOperand(operand_start, op_type, operand_scale));
     140           0 :         os << "[" << NameForRuntimeId(IntrinsicsHelper::ToRuntimeId(id)) << "]";
     141           0 :         break;
     142             :       }
     143             :       case interpreter::OperandType::kRuntimeId:
     144           2 :         os << "[" << NameForRuntimeId(DecodeUnsignedOperand(
     145           4 :                          operand_start, op_type, operand_scale))
     146           2 :            << "]";
     147           2 :         break;
     148             :       case interpreter::OperandType::kImm:
     149          10 :         os << "[" << DecodeSignedOperand(operand_start, op_type, operand_scale)
     150          10 :            << "]";
     151          10 :         break;
     152             :       case interpreter::OperandType::kFlag8:
     153           1 :         os << "#"
     154           1 :            << DecodeUnsignedOperand(operand_start, op_type, operand_scale);
     155             :         break;
     156             :       case interpreter::OperandType::kReg:
     157             :       case interpreter::OperandType::kRegOut: {
     158             :         Register reg =
     159          32 :             DecodeRegisterOperand(operand_start, op_type, operand_scale);
     160          64 :         os << reg.ToString(parameter_count);
     161             :         break;
     162             :       }
     163             :       case interpreter::OperandType::kRegOutTriple: {
     164             :         RegisterList reg_list =
     165             :             DecodeRegisterListOperand(operand_start, 3, op_type, operand_scale);
     166           3 :         os << reg_list.first_register().ToString(parameter_count) << "-"
     167           2 :            << reg_list.last_register().ToString(parameter_count);
     168             :         break;
     169             :       }
     170             :       case interpreter::OperandType::kRegOutPair:
     171             :       case interpreter::OperandType::kRegPair: {
     172             :         RegisterList reg_list =
     173             :             DecodeRegisterListOperand(operand_start, 2, op_type, operand_scale);
     174           0 :         os << reg_list.first_register().ToString(parameter_count) << "-"
     175           0 :            << reg_list.last_register().ToString(parameter_count);
     176             :         break;
     177             :       }
     178             :       case interpreter::OperandType::kRegList: {
     179             :         DCHECK_LT(i, number_of_operands - 1);
     180             :         DCHECK_EQ(Bytecodes::GetOperandType(bytecode, i + 1),
     181             :                   OperandType::kRegCount);
     182             :         int reg_count_offset =
     183           3 :             Bytecodes::GetOperandOffset(bytecode, i + 1, operand_scale);
     184             :         const uint8_t* reg_count_operand =
     185           3 :             &bytecode_start[prefix_offset + reg_count_offset];
     186             :         uint32_t count = DecodeUnsignedOperand(
     187           3 :             reg_count_operand, OperandType::kRegCount, operand_scale);
     188             :         RegisterList reg_list = DecodeRegisterListOperand(
     189             :             operand_start, count, op_type, operand_scale);
     190           9 :         os << reg_list.first_register().ToString(parameter_count) << "-"
     191           6 :            << reg_list.last_register().ToString(parameter_count);
     192             :         i++;  // Skip kRegCount.
     193             :         break;
     194             :       }
     195             :       case interpreter::OperandType::kNone:
     196             :       case interpreter::OperandType::kRegCount:  // Dealt with in kRegList.
     197           0 :         UNREACHABLE();
     198             :         break;
     199             :     }
     200          68 :     if (i != number_of_operands - 1) {
     201          12 :       os << ", ";
     202             :     }
     203             :   }
     204             :   return os;
     205             : }
     206             : 
     207             : }  // namespace interpreter
     208             : }  // namespace internal
     209             : }  // namespace v8

Generated by: LCOV version 1.10