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
|