LCOV - code coverage report
Current view: top level - test/unittests/interpreter - bytecode-array-iterator-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 232 232 100.0 %
Date: 2019-01-20 Functions: 4 7 57.1 %

          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/v8.h"
       6             : 
       7             : #include "src/interpreter/bytecode-array-builder.h"
       8             : #include "src/interpreter/bytecode-array-iterator.h"
       9             : #include "src/objects-inl.h"
      10             : #include "src/objects/smi.h"
      11             : #include "test/unittests/interpreter/bytecode-utils.h"
      12             : #include "test/unittests/test-utils.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : namespace interpreter {
      17             : 
      18             : class BytecodeArrayIteratorTest : public TestWithIsolateAndZone {
      19             :  public:
      20           1 :   BytecodeArrayIteratorTest() = default;
      21           1 :   ~BytecodeArrayIteratorTest() override = default;
      22             : };
      23             : 
      24       15129 : TEST_F(BytecodeArrayIteratorTest, IteratesBytecodeArray) {
      25             :   // Use a builder to create an array with containing multiple bytecodes
      26             :   // with 0, 1 and 2 operands.
      27           1 :   FeedbackVectorSpec feedback_spec(zone());
      28           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
      29             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
      30           2 :                               isolate()->heap()->HashSeed());
      31           1 :   double heap_num_0 = 2.718;
      32           1 :   double heap_num_1 = 2.0 * Smi::kMaxValue;
      33           1 :   Smi zero = Smi::zero();
      34           1 :   Smi smi_0 = Smi::FromInt(64);
      35           1 :   Smi smi_1 = Smi::FromInt(-65536);
      36             :   Register reg_0(0);
      37             :   Register reg_1(1);
      38           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
      39           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
      40           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
      41           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
      42           1 :   uint32_t name_index = 2;
      43           1 :   uint32_t load_feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
      44           1 :   uint32_t forin_feedback_slot = feedback_spec.AddForInSlot().ToInt();
      45             :   uint32_t load_global_feedback_slot =
      46           1 :       feedback_spec.AddLoadGlobalICSlot(TypeofMode::NOT_INSIDE_TYPEOF).ToInt();
      47             : 
      48           1 :   builder.LoadLiteral(heap_num_0)
      49           2 :       .StoreAccumulatorInRegister(reg_0)
      50           1 :       .LoadLiteral(heap_num_1)
      51           2 :       .StoreAccumulatorInRegister(reg_0)
      52           1 :       .LoadLiteral(zero)
      53           1 :       .StoreAccumulatorInRegister(reg_0)
      54           1 :       .LoadLiteral(smi_0)
      55           1 :       .StackCheck(0)
      56           1 :       .StoreAccumulatorInRegister(reg_0)
      57           1 :       .LoadLiteral(smi_1)
      58           1 :       .StackCheck(1)
      59           1 :       .StoreAccumulatorInRegister(reg_1)
      60           1 :       .LoadAccumulatorWithRegister(reg_0)
      61           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
      62           1 :       .StoreAccumulatorInRegister(reg_1)
      63           2 :       .LoadNamedProperty(reg_1, name, load_feedback_slot)
      64           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
      65           1 :       .StoreAccumulatorInRegister(param)
      66           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
      67           2 :       .ForInPrepare(triple, forin_feedback_slot)
      68           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
      69           1 :       .Debugger()
      70             :       .LoadGlobal(name, load_global_feedback_slot,
      71           1 :                   TypeofMode::NOT_INSIDE_TYPEOF)
      72           1 :       .Return();
      73             : 
      74             :   // Test iterator sees the expected output from the builder.
      75           1 :   ast_factory.Internalize(isolate());
      76           1 :   BytecodeArrayIterator iterator(builder.ToBytecodeArray(isolate()));
      77             :   const int kPrefixByteSize = 1;
      78           1 :   int offset = 0;
      79             : 
      80           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
      81           2 :   EXPECT_EQ(iterator.current_offset(), offset);
      82           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
      83           2 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_0);
      84           1 :   CHECK(!iterator.done());
      85           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
      86           1 :   iterator.Advance();
      87             : 
      88           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
      89           2 :   EXPECT_EQ(iterator.current_offset(), offset);
      90           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
      91           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
      92           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
      93           1 :   CHECK(!iterator.done());
      94           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
      95           1 :   iterator.Advance();
      96             : 
      97           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
      98           2 :   EXPECT_EQ(iterator.current_offset(), offset);
      99           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     100           2 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_1);
     101           1 :   CHECK(!iterator.done());
     102           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     103           1 :   iterator.Advance();
     104             : 
     105           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     106           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     107           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     108           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     109           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     110           1 :   CHECK(!iterator.done());
     111           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     112           1 :   iterator.Advance();
     113             : 
     114           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
     115           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     116           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     117           1 :   CHECK(!iterator.done());
     118           1 :   offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     119           1 :   iterator.Advance();
     120             : 
     121           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     122           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     123           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     124           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     125           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     126           1 :   CHECK(!iterator.done());
     127           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     128           1 :   iterator.Advance();
     129             : 
     130           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     131           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     132           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     133           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
     134           1 :   CHECK(!iterator.done());
     135           1 :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     136           1 :   iterator.Advance();
     137             : 
     138           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     139           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     140           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     141           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     142           1 :   CHECK(!iterator.done());
     143           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     144           1 :   iterator.Advance();
     145             : 
     146           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     147           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     148           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     149           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     150           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     151           1 :   CHECK(!iterator.done());
     152           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     153           1 :   iterator.Advance();
     154             : 
     155           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     156           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     157           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
     158           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
     159           1 :   CHECK(!iterator.done());
     160             :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     161           1 :             kPrefixByteSize;
     162           1 :   iterator.Advance();
     163             : 
     164           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     165           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     166           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     167           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     168           1 :   CHECK(!iterator.done());
     169           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     170           1 :   iterator.Advance();
     171             : 
     172           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     173           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     174           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     175           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     176           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     177           1 :   CHECK(!iterator.done());
     178           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     179           1 :   iterator.Advance();
     180             : 
     181           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
     182           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     183           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     184           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     185             :   CHECK(!iterator.done());
     186           1 :   offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     187           1 :   iterator.Advance();
     188             : 
     189           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     190           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     191           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     192           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     193           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     194           1 :   CHECK(!iterator.done());
     195           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     196           1 :   iterator.Advance();
     197             : 
     198           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     199           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     200           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     201           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     202           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     203           1 :   CHECK(!iterator.done());
     204           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     205           1 :   iterator.Advance();
     206             : 
     207           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
     208           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     209           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     210           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     211           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
     212           2 :   EXPECT_EQ(iterator.GetIndexOperand(2), load_feedback_slot);
     213           1 :   CHECK(!iterator.done());
     214           1 :   offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     215           1 :   iterator.Advance();
     216             : 
     217           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     218           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     219           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     220           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     221           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     222           1 :   CHECK(!iterator.done());
     223           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     224           1 :   iterator.Advance();
     225             : 
     226           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     227           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     228           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     229           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
     230           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     231           1 :   CHECK(!iterator.done());
     232           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     233           1 :   iterator.Advance();
     234             : 
     235           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
     236           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     237           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     238           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
     239           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
     240           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
     241           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     242           3 :   EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
     243           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
     244           1 :   CHECK(!iterator.done());
     245             :   offset +=
     246           1 :       Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
     247           1 :   iterator.Advance();
     248             : 
     249           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
     250           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     251           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     252           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     253           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 3);
     254           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), forin_feedback_slot);
     255           1 :   CHECK(!iterator.done());
     256           1 :   offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
     257           1 :   iterator.Advance();
     258             : 
     259           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
     260           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     261           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     262           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
     263           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
     264           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     265           1 :   CHECK(!iterator.done());
     266           1 :   offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
     267           1 :   iterator.Advance();
     268             : 
     269           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
     270           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     271           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     272           1 :   CHECK(!iterator.done());
     273           1 :   offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
     274           1 :   iterator.Advance();
     275             : 
     276           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaGlobal);
     277           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     278           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     279           2 :   EXPECT_EQ(iterator.current_bytecode_size(), 3);
     280           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), load_global_feedback_slot);
     281           1 :   offset += Bytecodes::Size(Bytecode::kLdaGlobal, OperandScale::kSingle);
     282           1 :   iterator.Advance();
     283             : 
     284           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
     285           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     286           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     287           1 :   CHECK(!iterator.done());
     288           1 :   iterator.Advance();
     289           1 :   CHECK(iterator.done());
     290           1 : }
     291             : 
     292             : }  // namespace interpreter
     293             : }  // namespace internal
     294        9075 : }  // namespace v8

Generated by: LCOV version 1.10