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

Generated by: LCOV version 1.10