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

Generated by: LCOV version 1.10