LCOV - code coverage report
Current view: top level - test/unittests/interpreter - bytecodes-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 97 97 100.0 %
Date: 2019-04-17 Functions: 48 71 67.6 %

          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 <vector>
       6             : 
       7             : #include "src/v8.h"
       8             : 
       9             : #include "src/interpreter/bytecode-register.h"
      10             : #include "src/interpreter/bytecodes.h"
      11             : #include "test/unittests/test-utils.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : namespace interpreter {
      16             : 
      17       15443 : TEST(OperandConversion, Registers) {
      18             :   int register_count = 128;
      19             :   int step = register_count / 7;
      20             :   for (int i = 0; i < register_count; i += step) {
      21             :     if (i <= kMaxInt8) {
      22             :       uint32_t operand0 = Register(i).ToOperand();
      23             :       Register reg0 = Register::FromOperand(operand0);
      24             :       CHECK_EQ(i, reg0.index());
      25             :     }
      26             : 
      27             :     uint32_t operand1 = Register(i).ToOperand();
      28             :     Register reg1 = Register::FromOperand(operand1);
      29             :     CHECK_EQ(i, reg1.index());
      30             : 
      31             :     uint32_t operand2 = Register(i).ToOperand();
      32             :     Register reg2 = Register::FromOperand(operand2);
      33             :     CHECK_EQ(i, reg2.index());
      34             :   }
      35           1 : }
      36             : 
      37       15443 : TEST(OperandConversion, Parameters) {
      38           1 :   int parameter_counts[] = {7, 13, 99};
      39             : 
      40             :   size_t count = sizeof(parameter_counts) / sizeof(parameter_counts[0]);
      41           7 :   for (size_t p = 0; p < count; p++) {
      42           3 :     int parameter_count = parameter_counts[p];
      43         241 :     for (int i = 0; i < parameter_count; i++) {
      44         119 :       Register r = Register::FromParameterIndex(i, parameter_count);
      45             :       uint32_t operand_value = r.ToOperand();
      46         119 :       Register s = Register::FromOperand(operand_value);
      47         119 :       CHECK_EQ(i, s.ToParameterIndex(parameter_count));
      48             :     }
      49             :   }
      50           1 : }
      51             : 
      52       15443 : TEST(OperandConversion, RegistersParametersNoOverlap) {
      53             :   int register_count = 128;
      54             :   int parameter_count = 100;
      55           1 :   int32_t register_space_size = base::bits::RoundUpToPowerOfTwo32(
      56             :       static_cast<uint32_t>(register_count + parameter_count));
      57             :   uint32_t range = static_cast<uint32_t>(register_space_size);
      58           1 :   std::vector<uint8_t> operand_count(range);
      59             : 
      60         257 :   for (int i = 0; i < register_count; i += 1) {
      61             :     Register r = Register(i);
      62             :     int32_t operand = r.ToOperand();
      63         128 :     uint8_t index = static_cast<uint8_t>(operand);
      64         128 :     CHECK_LT(index, operand_count.size());
      65         128 :     operand_count[index] += 1;
      66         256 :     CHECK_EQ(operand_count[index], 1);
      67             :   }
      68             : 
      69         201 :   for (int i = 0; i < parameter_count; i += 1) {
      70         100 :     Register r = Register::FromParameterIndex(i, parameter_count);
      71             :     uint32_t operand = r.ToOperand();
      72         100 :     uint8_t index = static_cast<uint8_t>(operand);
      73         100 :     CHECK_LT(index, operand_count.size());
      74         100 :     operand_count[index] += 1;
      75         200 :     CHECK_EQ(operand_count[index], 1);
      76             :   }
      77           1 : }
      78             : 
      79       15443 : TEST(OperandScaling, ScalableAndNonScalable) {
      80             :   const OperandScale kOperandScales[] = {
      81             : #define VALUE(Name, _) OperandScale::k##Name,
      82             :       OPERAND_SCALE_LIST(VALUE)
      83             : #undef VALUE
      84           1 :   };
      85             : 
      86           7 :   for (OperandScale operand_scale : kOperandScales) {
      87           3 :     int scale = static_cast<int>(operand_scale);
      88           6 :     CHECK_EQ(Bytecodes::Size(Bytecode::kCallRuntime, operand_scale),
      89             :              1 + 2 + 2 * scale);
      90           6 :     CHECK_EQ(Bytecodes::Size(Bytecode::kCreateObjectLiteral, operand_scale),
      91             :              1 + 2 * scale + 1);
      92           6 :     CHECK_EQ(Bytecodes::Size(Bytecode::kTestIn, operand_scale), 1 + 2 * scale);
      93             :   }
      94           1 : }
      95             : 
      96       15443 : TEST(Bytecodes, RegisterOperands) {
      97           1 :   CHECK(Bytecodes::IsRegisterOperandType(OperandType::kReg));
      98           1 :   CHECK(Bytecodes::IsRegisterOperandType(OperandType::kRegPair));
      99           1 :   CHECK(Bytecodes::IsRegisterInputOperandType(OperandType::kReg));
     100           1 :   CHECK(Bytecodes::IsRegisterInputOperandType(OperandType::kRegPair));
     101           1 :   CHECK(Bytecodes::IsRegisterInputOperandType(OperandType::kRegList));
     102           1 :   CHECK(!Bytecodes::IsRegisterOutputOperandType(OperandType::kReg));
     103           1 :   CHECK(!Bytecodes::IsRegisterInputOperandType(OperandType::kRegOut));
     104           1 :   CHECK(Bytecodes::IsRegisterOutputOperandType(OperandType::kRegOut));
     105           1 :   CHECK(Bytecodes::IsRegisterOutputOperandType(OperandType::kRegOutPair));
     106           1 : }
     107             : 
     108       15443 : TEST(Bytecodes, DebugBreakExistForEachBytecode) {
     109             :   static const OperandScale kOperandScale = OperandScale::kSingle;
     110             : #define CHECK_DEBUG_BREAK_SIZE(Name, ...)                                  \
     111             :   if (!Bytecodes::IsDebugBreak(Bytecode::k##Name) &&                       \
     112             :       !Bytecodes::IsPrefixScalingBytecode(Bytecode::k##Name)) {            \
     113             :     Bytecode debug_bytecode = Bytecodes::GetDebugBreak(Bytecode::k##Name); \
     114             :     CHECK_EQ(Bytecodes::Size(Bytecode::k##Name, kOperandScale),            \
     115             :              Bytecodes::Size(debug_bytecode, kOperandScale));              \
     116             :   }
     117         170 :   BYTECODE_LIST(CHECK_DEBUG_BREAK_SIZE)
     118             : #undef CHECK_DEBUG_BREAK_SIZE
     119           1 : }
     120             : 
     121       15443 : TEST(Bytecodes, DebugBreakForPrefixBytecodes) {
     122           1 :   CHECK_EQ(Bytecode::kDebugBreakWide,
     123             :            Bytecodes::GetDebugBreak(Bytecode::kWide));
     124           1 :   CHECK_EQ(Bytecode::kDebugBreakExtraWide,
     125             :            Bytecodes::GetDebugBreak(Bytecode::kExtraWide));
     126           1 : }
     127             : 
     128       15443 : TEST(Bytecodes, PrefixMappings) {
     129           1 :   Bytecode prefixes[] = {Bytecode::kWide, Bytecode::kExtraWide};
     130           9 :   TRACED_FOREACH(Bytecode, prefix, prefixes) {
     131           4 :     CHECK_EQ(prefix, Bytecodes::OperandScaleToPrefixBytecode(
     132             :                          Bytecodes::PrefixBytecodeToOperandScale(prefix)));
     133             :   }
     134           1 : }
     135             : 
     136       15443 : TEST(Bytecodes, ScaleForSignedOperand) {
     137             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(0), OperandScale::kSingle);
     138             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMaxInt8), OperandScale::kSingle);
     139             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMinInt8), OperandScale::kSingle);
     140             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMaxInt8 + 1),
     141             :            OperandScale::kDouble);
     142             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMinInt8 - 1),
     143             :            OperandScale::kDouble);
     144             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMaxInt16), OperandScale::kDouble);
     145             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMinInt16), OperandScale::kDouble);
     146             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMaxInt16 + 1),
     147             :            OperandScale::kQuadruple);
     148             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMinInt16 - 1),
     149             :            OperandScale::kQuadruple);
     150             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMaxInt), OperandScale::kQuadruple);
     151             :   CHECK_EQ(Bytecodes::ScaleForSignedOperand(kMinInt), OperandScale::kQuadruple);
     152           1 : }
     153             : 
     154       15443 : TEST(Bytecodes, ScaleForUnsignedOperands) {
     155             :   // int overloads
     156             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(0), OperandScale::kSingle);
     157             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(kMaxUInt8),
     158             :            OperandScale::kSingle);
     159             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(kMaxUInt8 + 1),
     160             :            OperandScale::kDouble);
     161             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(kMaxUInt16),
     162             :            OperandScale::kDouble);
     163             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(kMaxUInt16 + 1),
     164             :            OperandScale::kQuadruple);
     165             :   // size_t overloads
     166             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(static_cast<size_t>(0)),
     167             :            OperandScale::kSingle);
     168             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(static_cast<size_t>(kMaxUInt8)),
     169             :            OperandScale::kSingle);
     170             :   CHECK(Bytecodes::ScaleForUnsignedOperand(
     171             :             static_cast<size_t>(kMaxUInt8 + 1)) == OperandScale::kDouble);
     172             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(static_cast<size_t>(kMaxUInt16)),
     173             :            OperandScale::kDouble);
     174             :   CHECK(Bytecodes::ScaleForUnsignedOperand(
     175             :             static_cast<size_t>(kMaxUInt16 + 1)) == OperandScale::kQuadruple);
     176             :   CHECK_EQ(Bytecodes::ScaleForUnsignedOperand(static_cast<size_t>(kMaxUInt32)),
     177             :            OperandScale::kQuadruple);
     178           1 : }
     179             : 
     180       15443 : TEST(Bytecodes, SizesForUnsignedOperands) {
     181             :   // int overloads
     182             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(0), OperandSize::kByte);
     183             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(kMaxUInt8), OperandSize::kByte);
     184             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(kMaxUInt8 + 1),
     185             :            OperandSize::kShort);
     186             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(kMaxUInt16), OperandSize::kShort);
     187             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(kMaxUInt16 + 1),
     188             :            OperandSize::kQuad);
     189             :   // size_t overloads
     190             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<size_t>(0)),
     191             :            OperandSize::kByte);
     192             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<size_t>(kMaxUInt8)),
     193             :            OperandSize::kByte);
     194             :   CHECK_EQ(
     195             :       Bytecodes::SizeForUnsignedOperand(static_cast<size_t>(kMaxUInt8 + 1)),
     196             :       OperandSize::kShort);
     197             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<size_t>(kMaxUInt16)),
     198             :            OperandSize::kShort);
     199             :   CHECK(Bytecodes::SizeForUnsignedOperand(
     200             :             static_cast<size_t>(kMaxUInt16 + 1)) == OperandSize::kQuad);
     201             :   CHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<size_t>(kMaxUInt32)),
     202             :            OperandSize::kQuad);
     203           1 : }
     204             : 
     205             : // Helper macros to generate a check for if a bytecode is in a macro list of
     206             : // bytecodes. We can use these to exhaustively test a check over all bytecodes,
     207             : // both those that should pass and those that should fail the check.
     208             : #define OR_IS_BYTECODE(Name, ...) || bytecode == Bytecode::k##Name
     209             : #define IN_BYTECODE_LIST(BYTECODE, LIST) \
     210             :   ([](Bytecode bytecode) { return false LIST(OR_IS_BYTECODE); }(BYTECODE))
     211             : 
     212       15443 : TEST(Bytecodes, IsJump) {
     213             : #define TEST_BYTECODE(Name, ...)                                 \
     214             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_BYTECODE_LIST)) { \
     215             :     EXPECT_TRUE(Bytecodes::IsJump(Bytecode::k##Name));           \
     216             :   } else {                                                       \
     217             :     EXPECT_FALSE(Bytecodes::IsJump(Bytecode::k##Name));          \
     218             :   }
     219             : 
     220             :   BYTECODE_LIST(TEST_BYTECODE)
     221             : #undef TEST_BYTECODE
     222           1 : }
     223             : 
     224       15443 : TEST(Bytecodes, IsForwardJump) {
     225             : #define TEST_BYTECODE(Name, ...)                                         \
     226             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_FORWARD_BYTECODE_LIST)) { \
     227             :     EXPECT_TRUE(Bytecodes::IsForwardJump(Bytecode::k##Name));            \
     228             :   } else {                                                               \
     229             :     EXPECT_FALSE(Bytecodes::IsForwardJump(Bytecode::k##Name));           \
     230             :   }
     231             : 
     232             :   BYTECODE_LIST(TEST_BYTECODE)
     233             : #undef TEST_BYTECODE
     234           1 : }
     235             : 
     236       15443 : TEST(Bytecodes, IsConditionalJump) {
     237             : #define TEST_BYTECODE(Name, ...)                                             \
     238             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_CONDITIONAL_BYTECODE_LIST)) { \
     239             :     EXPECT_TRUE(Bytecodes::IsConditionalJump(Bytecode::k##Name));            \
     240             :   } else {                                                                   \
     241             :     EXPECT_FALSE(Bytecodes::IsConditionalJump(Bytecode::k##Name));           \
     242             :   }
     243             : 
     244             :   BYTECODE_LIST(TEST_BYTECODE)
     245             : #undef TEST_BYTECODE
     246           1 : }
     247             : 
     248       15443 : TEST(Bytecodes, IsUnconditionalJump) {
     249             : #define TEST_BYTECODE(Name, ...)                                               \
     250             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_UNCONDITIONAL_BYTECODE_LIST)) { \
     251             :     EXPECT_TRUE(Bytecodes::IsUnconditionalJump(Bytecode::k##Name));            \
     252             :   } else {                                                                     \
     253             :     EXPECT_FALSE(Bytecodes::IsUnconditionalJump(Bytecode::k##Name));           \
     254             :   }
     255             : 
     256             :   BYTECODE_LIST(TEST_BYTECODE)
     257             : #undef TEST_BYTECODE
     258           1 : }
     259             : 
     260       15443 : TEST(Bytecodes, IsJumpImmediate) {
     261             : #define TEST_BYTECODE(Name, ...)                                           \
     262             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_IMMEDIATE_BYTECODE_LIST)) { \
     263             :     EXPECT_TRUE(Bytecodes::IsJumpImmediate(Bytecode::k##Name));            \
     264             :   } else {                                                                 \
     265             :     EXPECT_FALSE(Bytecodes::IsJumpImmediate(Bytecode::k##Name));           \
     266             :   }
     267             : 
     268             :   BYTECODE_LIST(TEST_BYTECODE)
     269             : #undef TEST_BYTECODE
     270           1 : }
     271             : 
     272       15443 : TEST(Bytecodes, IsJumpConstant) {
     273             : #define TEST_BYTECODE(Name, ...)                                          \
     274             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_CONSTANT_BYTECODE_LIST)) { \
     275             :     EXPECT_TRUE(Bytecodes::IsJumpConstant(Bytecode::k##Name));            \
     276             :   } else {                                                                \
     277             :     EXPECT_FALSE(Bytecodes::IsJumpConstant(Bytecode::k##Name));           \
     278             :   }
     279             : 
     280             :   BYTECODE_LIST(TEST_BYTECODE)
     281             : #undef TEST_BYTECODE
     282           1 : }
     283             : 
     284       15443 : TEST(Bytecodes, IsConditionalJumpImmediate) {
     285             : #define TEST_BYTECODE(Name, ...)                                             \
     286             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_CONDITIONAL_BYTECODE_LIST) && \
     287             :       IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_IMMEDIATE_BYTECODE_LIST)) {   \
     288             :     EXPECT_TRUE(Bytecodes::IsConditionalJumpImmediate(Bytecode::k##Name));   \
     289             :   } else {                                                                   \
     290             :     EXPECT_FALSE(Bytecodes::IsConditionalJumpImmediate(Bytecode::k##Name));  \
     291             :   }
     292             : 
     293             :   BYTECODE_LIST(TEST_BYTECODE)
     294             : #undef TEST_BYTECODE
     295           1 : }
     296             : 
     297       15443 : TEST(Bytecodes, IsConditionalJumpConstant) {
     298             : #define TEST_BYTECODE(Name, ...)                                             \
     299             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_CONDITIONAL_BYTECODE_LIST) && \
     300             :       IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_CONSTANT_BYTECODE_LIST)) {    \
     301             :     EXPECT_TRUE(Bytecodes::IsConditionalJumpConstant(Bytecode::k##Name));    \
     302             :   } else {                                                                   \
     303             :     EXPECT_FALSE(Bytecodes::IsConditionalJumpConstant(Bytecode::k##Name));   \
     304             :   }
     305             : 
     306             :   BYTECODE_LIST(TEST_BYTECODE)
     307             : #undef TEST_BYTECODE
     308           1 : }
     309             : 
     310       15443 : TEST(Bytecodes, IsJumpIfToBoolean) {
     311             : #define TEST_BYTECODE(Name, ...)                                            \
     312             :   if (IN_BYTECODE_LIST(Bytecode::k##Name, JUMP_TO_BOOLEAN_BYTECODE_LIST)) { \
     313             :     EXPECT_TRUE(Bytecodes::IsJumpIfToBoolean(Bytecode::k##Name));           \
     314             :   } else {                                                                  \
     315             :     EXPECT_FALSE(Bytecodes::IsJumpIfToBoolean(Bytecode::k##Name));          \
     316             :   }
     317             : 
     318             :   BYTECODE_LIST(TEST_BYTECODE)
     319             : #undef TEST_BYTECODE
     320           1 : }
     321             : 
     322             : #undef OR_IS_BYTECODE
     323             : #undef IN_BYTECODE_LIST
     324             : 
     325       15443 : TEST(OperandScale, PrefixesRequired) {
     326             :   CHECK(!Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale::kSingle));
     327             :   CHECK(Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale::kDouble));
     328             :   CHECK(
     329             :       Bytecodes::OperandScaleRequiresPrefixBytecode(OperandScale::kQuadruple));
     330             :   CHECK_EQ(Bytecodes::OperandScaleToPrefixBytecode(OperandScale::kDouble),
     331             :            Bytecode::kWide);
     332             :   CHECK_EQ(Bytecodes::OperandScaleToPrefixBytecode(OperandScale::kQuadruple),
     333             :            Bytecode::kExtraWide);
     334           1 : }
     335             : 
     336       15443 : TEST(AccumulatorUse, LogicalOperators) {
     337             :   CHECK_EQ(AccumulatorUse::kNone | AccumulatorUse::kRead,
     338             :            AccumulatorUse::kRead);
     339             :   CHECK_EQ(AccumulatorUse::kRead | AccumulatorUse::kWrite,
     340             :            AccumulatorUse::kReadWrite);
     341             :   CHECK_EQ(AccumulatorUse::kRead & AccumulatorUse::kReadWrite,
     342             :            AccumulatorUse::kRead);
     343             :   CHECK_EQ(AccumulatorUse::kRead & AccumulatorUse::kWrite,
     344             :            AccumulatorUse::kNone);
     345           1 : }
     346             : 
     347       15443 : TEST(AccumulatorUse, SampleBytecodes) {
     348           1 :   CHECK(Bytecodes::ReadsAccumulator(Bytecode::kStar));
     349           1 :   CHECK(!Bytecodes::WritesAccumulator(Bytecode::kStar));
     350           1 :   CHECK_EQ(Bytecodes::GetAccumulatorUse(Bytecode::kStar),
     351             :            AccumulatorUse::kRead);
     352           1 :   CHECK(!Bytecodes::ReadsAccumulator(Bytecode::kLdar));
     353           1 :   CHECK(Bytecodes::WritesAccumulator(Bytecode::kLdar));
     354           1 :   CHECK_EQ(Bytecodes::GetAccumulatorUse(Bytecode::kLdar),
     355             :            AccumulatorUse::kWrite);
     356           1 :   CHECK(Bytecodes::ReadsAccumulator(Bytecode::kAdd));
     357           1 :   CHECK(Bytecodes::WritesAccumulator(Bytecode::kAdd));
     358           1 :   CHECK_EQ(Bytecodes::GetAccumulatorUse(Bytecode::kAdd),
     359             :            AccumulatorUse::kReadWrite);
     360           1 : }
     361             : 
     362             : }  // namespace interpreter
     363             : }  // namespace internal
     364        9264 : }  // namespace v8

Generated by: LCOV version 1.10