LCOV - code coverage report
Current view: top level - test/unittests/interpreter - bytecode-array-random-iterator-unittest.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 748 748 100.0 %
Date: 2019-04-17 Functions: 16 23 69.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 "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-random-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 BytecodeArrayRandomIteratorTest : public TestWithIsolateAndZone {
      20             :  public:
      21           7 :   BytecodeArrayRandomIteratorTest() = default;
      22          14 :   ~BytecodeArrayRandomIteratorTest() override = default;
      23             : };
      24             : 
      25       15444 : TEST_F(BytecodeArrayRandomIteratorTest, InvalidBeforeStart) {
      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             :   double heap_num_0 = 2.718;
      33             :   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             :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
      44             : 
      45           1 :   builder.LoadLiteral(heap_num_0)
      46           1 :       .StoreAccumulatorInRegister(reg_0)
      47           1 :       .LoadLiteral(heap_num_1)
      48           1 :       .StoreAccumulatorInRegister(reg_0)
      49           1 :       .LoadLiteral(zero)
      50           1 :       .StoreAccumulatorInRegister(reg_0)
      51           1 :       .LoadLiteral(smi_0)
      52           1 :       .StackCheck(0)
      53           1 :       .StoreAccumulatorInRegister(reg_0)
      54           1 :       .LoadLiteral(smi_1)
      55           1 :       .StackCheck(1)
      56           1 :       .StoreAccumulatorInRegister(reg_1)
      57           1 :       .LoadAccumulatorWithRegister(reg_0)
      58           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
      59           1 :       .StoreAccumulatorInRegister(reg_1)
      60           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
      61           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
      62           1 :       .StoreAccumulatorInRegister(param)
      63           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
      64           1 :       .ForInPrepare(triple, feedback_slot)
      65           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
      66           1 :       .Debugger()
      67           1 :       .Return();
      68             : 
      69           1 :   ast_factory.Internalize(isolate());
      70           1 :   Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
      71           1 :   BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
      72             : 
      73             :   iterator.GoToStart();
      74           2 :   ASSERT_TRUE(iterator.IsValid());
      75             :   --iterator;
      76           2 :   ASSERT_FALSE(iterator.IsValid());
      77             : }
      78             : 
      79       15444 : TEST_F(BytecodeArrayRandomIteratorTest, InvalidAfterEnd) {
      80             :   // Use a builder to create an array with containing multiple bytecodes
      81             :   // with 0, 1 and 2 operands.
      82             :   FeedbackVectorSpec feedback_spec(zone());
      83           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
      84             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
      85           1 :                               HashSeed(isolate()));
      86             :   double heap_num_0 = 2.718;
      87             :   double heap_num_1 = 2.0 * Smi::kMaxValue;
      88           1 :   Smi zero = Smi::zero();
      89           1 :   Smi smi_0 = Smi::FromInt(64);
      90           1 :   Smi smi_1 = Smi::FromInt(-65536);
      91             :   Register reg_0(0);
      92             :   Register reg_1(1);
      93           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
      94           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
      95           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
      96           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
      97             :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
      98             : 
      99           1 :   builder.LoadLiteral(heap_num_0)
     100           1 :       .StoreAccumulatorInRegister(reg_0)
     101           1 :       .LoadLiteral(heap_num_1)
     102           1 :       .StoreAccumulatorInRegister(reg_0)
     103           1 :       .LoadLiteral(zero)
     104           1 :       .StoreAccumulatorInRegister(reg_0)
     105           1 :       .LoadLiteral(smi_0)
     106           1 :       .StackCheck(0)
     107           1 :       .StoreAccumulatorInRegister(reg_0)
     108           1 :       .LoadLiteral(smi_1)
     109           1 :       .StackCheck(1)
     110           1 :       .StoreAccumulatorInRegister(reg_1)
     111           1 :       .LoadAccumulatorWithRegister(reg_0)
     112           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     113           1 :       .StoreAccumulatorInRegister(reg_1)
     114           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     115           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     116           1 :       .StoreAccumulatorInRegister(param)
     117           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     118           1 :       .ForInPrepare(triple, feedback_slot)
     119           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     120           1 :       .Debugger()
     121           1 :       .Return();
     122             : 
     123           1 :   ast_factory.Internalize(isolate());
     124           1 :   Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
     125           1 :   BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
     126             : 
     127             :   iterator.GoToEnd();
     128           2 :   ASSERT_TRUE(iterator.IsValid());
     129             :   ++iterator;
     130           2 :   ASSERT_FALSE(iterator.IsValid());
     131             : }
     132             : 
     133       15444 : TEST_F(BytecodeArrayRandomIteratorTest, AccessesFirst) {
     134             :   // Use a builder to create an array with containing multiple bytecodes
     135             :   // with 0, 1 and 2 operands.
     136             :   FeedbackVectorSpec feedback_spec(zone());
     137           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
     138             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
     139           1 :                               HashSeed(isolate()));
     140           1 :   double heap_num_0 = 2.718;
     141             :   double heap_num_1 = 2.0 * Smi::kMaxValue;
     142           1 :   Smi zero = Smi::zero();
     143           1 :   Smi smi_0 = Smi::FromInt(64);
     144           1 :   Smi smi_1 = Smi::FromInt(-65536);
     145             :   Register reg_0(0);
     146             :   Register reg_1(1);
     147           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
     148           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
     149           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
     150           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
     151             :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
     152             : 
     153           1 :   builder.LoadLiteral(heap_num_0)
     154           2 :       .StoreAccumulatorInRegister(reg_0)
     155           1 :       .LoadLiteral(heap_num_1)
     156           1 :       .StoreAccumulatorInRegister(reg_0)
     157           1 :       .LoadLiteral(zero)
     158           1 :       .StoreAccumulatorInRegister(reg_0)
     159           1 :       .LoadLiteral(smi_0)
     160           1 :       .StackCheck(0)
     161           1 :       .StoreAccumulatorInRegister(reg_0)
     162           1 :       .LoadLiteral(smi_1)
     163           1 :       .StackCheck(1)
     164           1 :       .StoreAccumulatorInRegister(reg_1)
     165           1 :       .LoadAccumulatorWithRegister(reg_0)
     166           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     167           1 :       .StoreAccumulatorInRegister(reg_1)
     168           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     169           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     170           1 :       .StoreAccumulatorInRegister(param)
     171           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     172           1 :       .ForInPrepare(triple, feedback_slot)
     173           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     174           1 :       .Debugger()
     175           1 :       .Return();
     176             : 
     177           1 :   ast_factory.Internalize(isolate());
     178           1 :   Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
     179           1 :   BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
     180             : 
     181             :   iterator.GoToStart();
     182             : 
     183           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     184           2 :   EXPECT_EQ(iterator.current_index(), 0);
     185           2 :   EXPECT_EQ(iterator.current_offset(), 0);
     186           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     187           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_0);
     188           2 :   ASSERT_TRUE(iterator.IsValid());
     189             : }
     190             : 
     191       15444 : TEST_F(BytecodeArrayRandomIteratorTest, AccessesLast) {
     192             :   // Use a builder to create an array with containing multiple bytecodes
     193             :   // with 0, 1 and 2 operands.
     194             :   FeedbackVectorSpec feedback_spec(zone());
     195           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
     196             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
     197           1 :                               HashSeed(isolate()));
     198             :   double heap_num_0 = 2.718;
     199             :   double heap_num_1 = 2.0 * Smi::kMaxValue;
     200           1 :   Smi zero = Smi::zero();
     201           1 :   Smi smi_0 = Smi::FromInt(64);
     202           1 :   Smi smi_1 = Smi::FromInt(-65536);
     203             :   Register reg_0(0);
     204             :   Register reg_1(1);
     205           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
     206           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
     207           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
     208           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
     209             :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
     210             : 
     211           1 :   builder.LoadLiteral(heap_num_0)
     212           1 :       .StoreAccumulatorInRegister(reg_0)
     213           1 :       .LoadLiteral(heap_num_1)
     214           1 :       .StoreAccumulatorInRegister(reg_0)
     215           1 :       .LoadLiteral(zero)
     216           1 :       .StoreAccumulatorInRegister(reg_0)
     217           1 :       .LoadLiteral(smi_0)
     218           1 :       .StackCheck(0)
     219           1 :       .StoreAccumulatorInRegister(reg_0)
     220           1 :       .LoadLiteral(smi_1)
     221           1 :       .StackCheck(1)
     222           1 :       .StoreAccumulatorInRegister(reg_1)
     223           1 :       .LoadAccumulatorWithRegister(reg_0)
     224           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     225           1 :       .StoreAccumulatorInRegister(reg_1)
     226           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     227           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     228           1 :       .StoreAccumulatorInRegister(param)
     229           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     230           1 :       .ForInPrepare(triple, feedback_slot)
     231           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     232           1 :       .Debugger()
     233           1 :       .Return();
     234             : 
     235           1 :   ast_factory.Internalize(isolate());
     236           1 :   Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
     237           1 :   BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
     238             : 
     239             :   iterator.GoToEnd();
     240             : 
     241           1 :   int offset = bytecodeArray->length() -
     242           1 :                Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
     243           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
     244           2 :   EXPECT_EQ(iterator.current_index(), 22);
     245           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     246           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     247           2 :   ASSERT_TRUE(iterator.IsValid());
     248             : }
     249             : 
     250       15444 : TEST_F(BytecodeArrayRandomIteratorTest, RandomAccessValid) {
     251             :   // Use a builder to create an array with containing multiple bytecodes
     252             :   // with 0, 1 and 2 operands.
     253             :   FeedbackVectorSpec feedback_spec(zone());
     254           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
     255             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
     256           1 :                               HashSeed(isolate()));
     257             :   double heap_num_0 = 2.718;
     258           1 :   double heap_num_1 = 2.0 * Smi::kMaxValue;
     259           1 :   Smi zero = Smi::zero();
     260           1 :   Smi smi_0 = Smi::FromInt(64);
     261           1 :   Smi smi_1 = Smi::FromInt(-65536);
     262             :   Register reg_0(0);
     263             :   Register reg_1(1);
     264           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
     265           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
     266           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
     267           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
     268           1 :   uint32_t name_index = 2;
     269           1 :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
     270             : 
     271           1 :   builder.LoadLiteral(heap_num_0)
     272           1 :       .StoreAccumulatorInRegister(reg_0)
     273           1 :       .LoadLiteral(heap_num_1)
     274           2 :       .StoreAccumulatorInRegister(reg_0)
     275           1 :       .LoadLiteral(zero)
     276           1 :       .StoreAccumulatorInRegister(reg_0)
     277           1 :       .LoadLiteral(smi_0)
     278           1 :       .StackCheck(0)
     279           1 :       .StoreAccumulatorInRegister(reg_0)
     280           1 :       .LoadLiteral(smi_1)
     281           1 :       .StackCheck(1)
     282           1 :       .StoreAccumulatorInRegister(reg_1)
     283           1 :       .LoadAccumulatorWithRegister(reg_0)
     284           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     285           1 :       .StoreAccumulatorInRegister(reg_1)
     286           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     287           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     288           1 :       .StoreAccumulatorInRegister(param)
     289           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     290           1 :       .ForInPrepare(triple, feedback_slot)
     291           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     292           1 :       .Debugger()
     293           1 :       .Return();
     294             : 
     295             :   // Test iterator sees the expected output from the builder.
     296           1 :   ast_factory.Internalize(isolate());
     297             :   BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
     298           1 :                                        zone());
     299             :   const int kPrefixByteSize = 1;
     300           1 :   int offset = 0;
     301             : 
     302             :   iterator.GoToIndex(13);
     303           1 :   offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     304           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     305           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     306           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     307           1 :   offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     308           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     309           1 :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     310           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     311           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     312             :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     313           1 :             kPrefixByteSize;
     314           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     315           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     316           1 :   offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     317             : 
     318           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     319           2 :   EXPECT_EQ(iterator.current_index(), 13);
     320           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     321           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     322           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     323           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     324           2 :   ASSERT_TRUE(iterator.IsValid());
     325             : 
     326             :   iterator.GoToIndex(2);
     327           1 :   offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     328           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     329             : 
     330           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     331           2 :   EXPECT_EQ(iterator.current_index(), 2);
     332           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     333           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     334           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_1);
     335           2 :   ASSERT_TRUE(iterator.IsValid());
     336             : 
     337             :   iterator.GoToIndex(18);
     338           1 :   offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     339           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     340           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     341           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     342           1 :   offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     343           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     344           1 :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     345           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     346           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     347             :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     348           1 :             kPrefixByteSize;
     349           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     350           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     351           1 :   offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     352           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     353           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     354           1 :   offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     355           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     356           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     357             : 
     358           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
     359           2 :   EXPECT_EQ(iterator.current_index(), 18);
     360           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     361           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     362           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
     363           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
     364           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
     365           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     366           3 :   EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
     367           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
     368           2 :   ASSERT_TRUE(iterator.IsValid());
     369             : 
     370             :   iterator -= 3;
     371           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     372           1 :   offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     373           1 :   offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     374             : 
     375           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
     376           2 :   EXPECT_EQ(iterator.current_index(), 15);
     377           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     378           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     379           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     380           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
     381           2 :   EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
     382           2 :   ASSERT_TRUE(iterator.IsValid());
     383             : 
     384             :   iterator += 2;
     385           1 :   offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     386           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     387             : 
     388           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     389           2 :   EXPECT_EQ(iterator.current_index(), 17);
     390           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     391           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     392           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
     393           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     394           2 :   ASSERT_TRUE(iterator.IsValid());
     395             : 
     396             :   iterator.GoToIndex(22);
     397           1 :   offset = Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     398           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     399           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     400           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     401           1 :   offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     402           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     403           1 :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     404           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     405           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     406             :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     407           1 :             kPrefixByteSize;
     408           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     409           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     410           1 :   offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     411           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     412           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     413           1 :   offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     414           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     415           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     416             :   offset +=
     417           1 :       Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
     418           1 :   offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
     419           1 :   offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
     420           1 :   offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
     421             : 
     422           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
     423           2 :   EXPECT_EQ(iterator.current_index(), 22);
     424           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     425           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     426           2 :   ASSERT_TRUE(iterator.IsValid());
     427             : 
     428             :   iterator.GoToIndex(24);
     429           2 :   EXPECT_FALSE(iterator.IsValid());
     430             : 
     431             :   iterator.GoToIndex(-5);
     432           2 :   EXPECT_FALSE(iterator.IsValid());
     433             : }
     434             : 
     435       15444 : TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArray) {
     436             :   // Use a builder to create an array with containing multiple bytecodes
     437             :   // with 0, 1 and 2 operands.
     438             :   FeedbackVectorSpec feedback_spec(zone());
     439           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
     440             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
     441           1 :                               HashSeed(isolate()));
     442           1 :   double heap_num_0 = 2.718;
     443           1 :   double heap_num_1 = 2.0 * Smi::kMaxValue;
     444           1 :   Smi zero = Smi::zero();
     445           1 :   Smi smi_0 = Smi::FromInt(64);
     446           1 :   Smi smi_1 = Smi::FromInt(-65536);
     447             :   Register reg_0(0);
     448             :   Register reg_1(1);
     449           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
     450           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
     451           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
     452           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
     453           1 :   uint32_t name_index = 2;
     454           1 :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
     455             : 
     456           1 :   builder.LoadLiteral(heap_num_0)
     457           2 :       .StoreAccumulatorInRegister(reg_0)
     458           1 :       .LoadLiteral(heap_num_1)
     459           2 :       .StoreAccumulatorInRegister(reg_0)
     460           1 :       .LoadLiteral(zero)
     461           1 :       .StoreAccumulatorInRegister(reg_0)
     462           1 :       .LoadLiteral(smi_0)
     463           1 :       .StackCheck(0)
     464           1 :       .StoreAccumulatorInRegister(reg_0)
     465           1 :       .LoadLiteral(smi_1)
     466           1 :       .StackCheck(1)
     467           1 :       .StoreAccumulatorInRegister(reg_1)
     468           1 :       .LoadAccumulatorWithRegister(reg_0)
     469           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     470           1 :       .StoreAccumulatorInRegister(reg_1)
     471           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     472           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     473           1 :       .StoreAccumulatorInRegister(param)
     474           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     475           1 :       .ForInPrepare(triple, feedback_slot)
     476           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     477           1 :       .Debugger()
     478           1 :       .Return();
     479             : 
     480             :   // Test iterator sees the expected output from the builder.
     481           1 :   ast_factory.Internalize(isolate());
     482             :   BytecodeArrayRandomIterator iterator(builder.ToBytecodeArray(isolate()),
     483           1 :                                        zone());
     484             :   const int kPrefixByteSize = 1;
     485           1 :   int offset = 0;
     486             : 
     487           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     488           2 :   EXPECT_EQ(iterator.current_index(), 0);
     489           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     490           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     491           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_0);
     492           2 :   ASSERT_TRUE(iterator.IsValid());
     493           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     494             :   ++iterator;
     495             : 
     496           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     497           2 :   EXPECT_EQ(iterator.current_index(), 1);
     498           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     499           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     500           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     501           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     502           2 :   ASSERT_TRUE(iterator.IsValid());
     503           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     504             :   ++iterator;
     505             : 
     506           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     507           2 :   EXPECT_EQ(iterator.current_index(), 2);
     508           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     509           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     510           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_1);
     511           2 :   ASSERT_TRUE(iterator.IsValid());
     512           1 :   offset += Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     513             :   ++iterator;
     514             : 
     515           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     516           2 :   EXPECT_EQ(iterator.current_index(), 3);
     517           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     518           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     519           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     520           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     521           2 :   ASSERT_TRUE(iterator.IsValid());
     522           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     523             :   ++iterator;
     524             : 
     525           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
     526           2 :   EXPECT_EQ(iterator.current_index(), 4);
     527           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     528           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     529           2 :   ASSERT_TRUE(iterator.IsValid());
     530           1 :   offset += Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     531             :   ++iterator;
     532             : 
     533           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     534           2 :   EXPECT_EQ(iterator.current_index(), 5);
     535           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     536           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     537           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     538           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     539           2 :   ASSERT_TRUE(iterator.IsValid());
     540           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     541             :   ++iterator;
     542             : 
     543           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     544           2 :   EXPECT_EQ(iterator.current_index(), 6);
     545           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     546           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     547           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
     548           2 :   ASSERT_TRUE(iterator.IsValid());
     549           1 :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     550             :   ++iterator;
     551             : 
     552           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     553           2 :   EXPECT_EQ(iterator.current_index(), 7);
     554           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     555           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     556           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     557           2 :   ASSERT_TRUE(iterator.IsValid());
     558           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     559             :   ++iterator;
     560             : 
     561           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     562           2 :   EXPECT_EQ(iterator.current_index(), 8);
     563           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     564           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     565           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     566           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     567           2 :   ASSERT_TRUE(iterator.IsValid());
     568           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     569             :   ++iterator;
     570             : 
     571           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     572           2 :   EXPECT_EQ(iterator.current_index(), 9);
     573           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     574           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
     575           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
     576           2 :   ASSERT_TRUE(iterator.IsValid());
     577             :   offset += Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     578           1 :             kPrefixByteSize;
     579             :   ++iterator;
     580             : 
     581           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     582           2 :   EXPECT_EQ(iterator.current_index(), 10);
     583           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     584           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     585           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     586           2 :   ASSERT_TRUE(iterator.IsValid());
     587           1 :   offset += Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     588             :   ++iterator;
     589             : 
     590           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     591           2 :   EXPECT_EQ(iterator.current_index(), 11);
     592           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     593           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     594           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     595           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     596           2 :   ASSERT_TRUE(iterator.IsValid());
     597           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     598             :   ++iterator;
     599             : 
     600           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
     601           2 :   EXPECT_EQ(iterator.current_index(), 12);
     602           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     603           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     604           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     605           2 :   ASSERT_TRUE(iterator.IsValid());
     606           1 :   offset += Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     607             :   ++iterator;
     608             : 
     609           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     610           2 :   EXPECT_EQ(iterator.current_index(), 13);
     611           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     612           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     613           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     614           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     615           2 :   ASSERT_TRUE(iterator.IsValid());
     616           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     617             :   ++iterator;
     618             : 
     619           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     620           2 :   EXPECT_EQ(iterator.current_index(), 14);
     621           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     622           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     623           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     624           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     625           2 :   ASSERT_TRUE(iterator.IsValid());
     626           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     627             :   ++iterator;
     628             : 
     629           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
     630           2 :   EXPECT_EQ(iterator.current_index(), 15);
     631           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     632           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     633           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     634           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
     635           2 :   EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
     636           2 :   ASSERT_TRUE(iterator.IsValid());
     637           1 :   offset += Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     638             :   ++iterator;
     639             : 
     640           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     641           2 :   EXPECT_EQ(iterator.current_index(), 16);
     642           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     643           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     644           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     645           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     646           2 :   ASSERT_TRUE(iterator.IsValid());
     647           1 :   offset += Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     648             :   ++iterator;
     649             : 
     650           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     651           2 :   EXPECT_EQ(iterator.current_index(), 17);
     652           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     653           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     654           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
     655           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     656           2 :   ASSERT_TRUE(iterator.IsValid());
     657           1 :   offset += Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     658             :   ++iterator;
     659             : 
     660           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
     661           2 :   EXPECT_EQ(iterator.current_index(), 18);
     662           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     663           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     664           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
     665           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
     666           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
     667           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     668           3 :   EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
     669           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
     670           2 :   ASSERT_TRUE(iterator.IsValid());
     671             :   offset +=
     672           1 :       Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
     673             :   ++iterator;
     674             : 
     675           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
     676           2 :   EXPECT_EQ(iterator.current_index(), 19);
     677           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     678           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     679           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     680           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 3);
     681           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), feedback_slot);
     682           2 :   ASSERT_TRUE(iterator.IsValid());
     683           1 :   offset += Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
     684             :   ++iterator;
     685             : 
     686           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
     687           2 :   EXPECT_EQ(iterator.current_index(), 20);
     688           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     689           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     690           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
     691           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
     692           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     693           2 :   ASSERT_TRUE(iterator.IsValid());
     694           1 :   offset += Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
     695             :   ++iterator;
     696             : 
     697           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
     698           2 :   EXPECT_EQ(iterator.current_index(), 21);
     699           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     700           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     701           2 :   ASSERT_TRUE(iterator.IsValid());
     702           1 :   offset += Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
     703             :   ++iterator;
     704             : 
     705           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
     706           2 :   EXPECT_EQ(iterator.current_index(), 22);
     707           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     708           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     709           2 :   ASSERT_TRUE(iterator.IsValid());
     710             :   ++iterator;
     711           2 :   ASSERT_TRUE(!iterator.IsValid());
     712             : }
     713             : 
     714       15444 : TEST_F(BytecodeArrayRandomIteratorTest, IteratesBytecodeArrayBackwards) {
     715             :   // Use a builder to create an array with containing multiple bytecodes
     716             :   // with 0, 1 and 2 operands.
     717             :   FeedbackVectorSpec feedback_spec(zone());
     718           2 :   BytecodeArrayBuilder builder(zone(), 3, 3, &feedback_spec);
     719             :   AstValueFactory ast_factory(zone(), isolate()->ast_string_constants(),
     720           1 :                               HashSeed(isolate()));
     721           1 :   double heap_num_0 = 2.718;
     722           1 :   double heap_num_1 = 2.0 * Smi::kMaxValue;
     723           1 :   Smi zero = Smi::zero();
     724           1 :   Smi smi_0 = Smi::FromInt(64);
     725           1 :   Smi smi_1 = Smi::FromInt(-65536);
     726             :   Register reg_0(0);
     727             :   Register reg_1(1);
     728           1 :   RegisterList pair = BytecodeUtils::NewRegisterList(0, 2);
     729           1 :   RegisterList triple = BytecodeUtils::NewRegisterList(0, 3);
     730           1 :   Register param = Register::FromParameterIndex(2, builder.parameter_count());
     731           1 :   const AstRawString* name = ast_factory.GetOneByteString("abc");
     732           1 :   uint32_t name_index = 2;
     733           1 :   uint32_t feedback_slot = feedback_spec.AddLoadICSlot().ToInt();
     734             : 
     735           1 :   builder.LoadLiteral(heap_num_0)
     736           2 :       .StoreAccumulatorInRegister(reg_0)
     737           1 :       .LoadLiteral(heap_num_1)
     738           2 :       .StoreAccumulatorInRegister(reg_0)
     739           1 :       .LoadLiteral(zero)
     740           1 :       .StoreAccumulatorInRegister(reg_0)
     741           1 :       .LoadLiteral(smi_0)
     742           1 :       .StackCheck(0)
     743           1 :       .StoreAccumulatorInRegister(reg_0)
     744           1 :       .LoadLiteral(smi_1)
     745           1 :       .StackCheck(1)
     746           1 :       .StoreAccumulatorInRegister(reg_1)
     747           1 :       .LoadAccumulatorWithRegister(reg_0)
     748           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 2)
     749           1 :       .StoreAccumulatorInRegister(reg_1)
     750           1 :       .LoadNamedProperty(reg_1, name, feedback_slot)
     751           1 :       .BinaryOperation(Token::Value::ADD, reg_0, 3)
     752           1 :       .StoreAccumulatorInRegister(param)
     753           1 :       .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, param, pair)
     754           1 :       .ForInPrepare(triple, feedback_slot)
     755           1 :       .CallRuntime(Runtime::kLoadIC_Miss, reg_0)
     756           1 :       .Debugger()
     757           1 :       .Return();
     758             : 
     759             :   // Test iterator sees the expected output from the builder.
     760           1 :   ast_factory.Internalize(isolate());
     761           1 :   Handle<BytecodeArray> bytecodeArray = builder.ToBytecodeArray(isolate());
     762           1 :   BytecodeArrayRandomIterator iterator(bytecodeArray, zone());
     763             :   const int kPrefixByteSize = 1;
     764           1 :   int offset = bytecodeArray->length();
     765             : 
     766             :   iterator.GoToEnd();
     767             : 
     768           1 :   offset -= Bytecodes::Size(Bytecode::kReturn, OperandScale::kSingle);
     769           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kReturn);
     770           2 :   EXPECT_EQ(iterator.current_index(), 22);
     771           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     772           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     773           2 :   ASSERT_TRUE(iterator.IsValid());
     774             :   --iterator;
     775             : 
     776           1 :   offset -= Bytecodes::Size(Bytecode::kDebugger, OperandScale::kSingle);
     777           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kDebugger);
     778           2 :   EXPECT_EQ(iterator.current_index(), 21);
     779           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     780           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     781           2 :   ASSERT_TRUE(iterator.IsValid());
     782             :   --iterator;
     783             : 
     784           1 :   offset -= Bytecodes::Size(Bytecode::kCallRuntime, OperandScale::kSingle);
     785           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntime);
     786           2 :   EXPECT_EQ(iterator.current_index(), 20);
     787           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     788           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     789           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadIC_Miss);
     790           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), reg_0.index());
     791           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     792           2 :   ASSERT_TRUE(iterator.IsValid());
     793             :   --iterator;
     794             : 
     795           1 :   offset -= Bytecodes::Size(Bytecode::kForInPrepare, OperandScale::kSingle);
     796           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kForInPrepare);
     797           2 :   EXPECT_EQ(iterator.current_index(), 19);
     798           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     799           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     800           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     801           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 3);
     802           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), feedback_slot);
     803           2 :   ASSERT_TRUE(iterator.IsValid());
     804             :   --iterator;
     805             : 
     806             :   offset -=
     807           1 :       Bytecodes::Size(Bytecode::kCallRuntimeForPair, OperandScale::kSingle);
     808           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kCallRuntimeForPair);
     809           2 :   EXPECT_EQ(iterator.current_index(), 18);
     810           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     811           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     812           2 :   EXPECT_EQ(iterator.GetRuntimeIdOperand(0), Runtime::kLoadLookupSlotForCall);
     813           3 :   EXPECT_EQ(iterator.GetRegisterOperand(1).index(), param.index());
     814           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(1), 1);
     815           2 :   EXPECT_EQ(iterator.GetRegisterCountOperand(2), 1u);
     816           3 :   EXPECT_EQ(iterator.GetRegisterOperand(3).index(), reg_0.index());
     817           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(3), 2);
     818           2 :   ASSERT_TRUE(iterator.IsValid());
     819             :   --iterator;
     820             : 
     821           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     822           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     823           2 :   EXPECT_EQ(iterator.current_index(), 17);
     824           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     825           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     826           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), param.index());
     827           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     828           2 :   ASSERT_TRUE(iterator.IsValid());
     829             :   --iterator;
     830             : 
     831           1 :   offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     832           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     833           2 :   EXPECT_EQ(iterator.current_index(), 16);
     834           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     835           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     836           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     837           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     838           2 :   ASSERT_TRUE(iterator.IsValid());
     839             :   --iterator;
     840             : 
     841           1 :   offset -= Bytecodes::Size(Bytecode::kLdaNamedProperty, OperandScale::kSingle);
     842           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaNamedProperty);
     843           2 :   EXPECT_EQ(iterator.current_index(), 15);
     844           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     845           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     846           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     847           2 :   EXPECT_EQ(iterator.GetIndexOperand(1), name_index);
     848           2 :   EXPECT_EQ(iterator.GetIndexOperand(2), feedback_slot);
     849           2 :   ASSERT_TRUE(iterator.IsValid());
     850             :   --iterator;
     851             : 
     852           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     853           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     854           2 :   EXPECT_EQ(iterator.current_index(), 14);
     855           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     856           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     857           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     858           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     859           2 :   ASSERT_TRUE(iterator.IsValid());
     860             :   --iterator;
     861             : 
     862           1 :   offset -= Bytecodes::Size(Bytecode::kAdd, OperandScale::kSingle);
     863           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kAdd);
     864           2 :   EXPECT_EQ(iterator.current_index(), 13);
     865           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     866           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     867           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     868           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     869           2 :   ASSERT_TRUE(iterator.IsValid());
     870             :   --iterator;
     871             : 
     872           1 :   offset -= Bytecodes::Size(Bytecode::kLdar, OperandScale::kSingle);
     873           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdar);
     874           2 :   EXPECT_EQ(iterator.current_index(), 12);
     875           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     876           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     877           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     878           2 :   ASSERT_TRUE(iterator.IsValid());
     879             :   --iterator;
     880             : 
     881           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     882           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     883           2 :   EXPECT_EQ(iterator.current_index(), 11);
     884           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     885           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     886           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_1.index());
     887           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     888           2 :   ASSERT_TRUE(iterator.IsValid());
     889             :   --iterator;
     890             : 
     891           1 :   offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     892           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     893           2 :   EXPECT_EQ(iterator.current_index(), 10);
     894           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     895           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     896           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     897           2 :   ASSERT_TRUE(iterator.IsValid());
     898             :   --iterator;
     899             : 
     900             :   offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kQuadruple) +
     901           1 :             kPrefixByteSize;
     902           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     903           2 :   EXPECT_EQ(iterator.current_index(), 9);
     904           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     905           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kQuadruple);
     906           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_1);
     907           2 :   ASSERT_TRUE(iterator.IsValid());
     908             :   --iterator;
     909             : 
     910           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     911           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     912           2 :   EXPECT_EQ(iterator.current_index(), 8);
     913           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     914           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     915           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     916           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     917           2 :   ASSERT_TRUE(iterator.IsValid());
     918             :   --iterator;
     919             : 
     920           1 :   offset -= Bytecodes::Size(Bytecode::kStackCheck, OperandScale::kSingle);
     921           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStackCheck);
     922           2 :   EXPECT_EQ(iterator.current_index(), 7);
     923           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     924           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     925           3 :   EXPECT_EQ(Bytecodes::NumberOfOperands(iterator.current_bytecode()), 0);
     926           2 :   ASSERT_TRUE(iterator.IsValid());
     927             :   --iterator;
     928             : 
     929           1 :   offset -= Bytecodes::Size(Bytecode::kLdaSmi, OperandScale::kSingle);
     930           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaSmi);
     931           2 :   EXPECT_EQ(iterator.current_index(), 6);
     932           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     933           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     934           3 :   EXPECT_EQ(Smi::FromInt(iterator.GetImmediateOperand(0)), smi_0);
     935           2 :   ASSERT_TRUE(iterator.IsValid());
     936             :   --iterator;
     937             : 
     938           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     939           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     940           2 :   EXPECT_EQ(iterator.current_index(), 5);
     941           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     942           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     943           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     944           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     945           2 :   ASSERT_TRUE(iterator.IsValid());
     946             :   --iterator;
     947             : 
     948           1 :   offset -= Bytecodes::Size(Bytecode::kLdaZero, OperandScale::kSingle);
     949           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaZero);
     950           2 :   EXPECT_EQ(iterator.current_index(), 4);
     951           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     952           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     953           2 :   ASSERT_TRUE(iterator.IsValid());
     954             :   --iterator;
     955             : 
     956           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     957           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     958           2 :   EXPECT_EQ(iterator.current_index(), 3);
     959           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     960           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     961           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     962           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     963           2 :   ASSERT_TRUE(iterator.IsValid());
     964             :   --iterator;
     965             : 
     966           1 :   offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     967           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     968           2 :   EXPECT_EQ(iterator.current_index(), 2);
     969           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     970           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     971           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_1);
     972           2 :   ASSERT_TRUE(iterator.IsValid());
     973             :   --iterator;
     974             : 
     975           1 :   offset -= Bytecodes::Size(Bytecode::kStar, OperandScale::kSingle);
     976           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kStar);
     977           2 :   EXPECT_EQ(iterator.current_index(), 1);
     978           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     979           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     980           3 :   EXPECT_EQ(iterator.GetRegisterOperand(0).index(), reg_0.index());
     981           2 :   EXPECT_EQ(iterator.GetRegisterOperandRange(0), 1);
     982           2 :   ASSERT_TRUE(iterator.IsValid());
     983             :   --iterator;
     984             : 
     985           1 :   offset -= Bytecodes::Size(Bytecode::kLdaConstant, OperandScale::kSingle);
     986           2 :   EXPECT_EQ(iterator.current_bytecode(), Bytecode::kLdaConstant);
     987           2 :   EXPECT_EQ(iterator.current_index(), 0);
     988           2 :   EXPECT_EQ(iterator.current_offset(), offset);
     989           2 :   EXPECT_EQ(iterator.current_operand_scale(), OperandScale::kSingle);
     990           3 :   EXPECT_EQ(iterator.GetConstantForIndexOperand(0)->Number(), heap_num_0);
     991           2 :   ASSERT_TRUE(iterator.IsValid());
     992             :   --iterator;
     993           2 :   ASSERT_FALSE(iterator.IsValid());
     994             : }
     995             : 
     996             : }  // namespace interpreter
     997             : }  // namespace internal
     998        9264 : }  // namespace v8

Generated by: LCOV version 1.10