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