Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(616)

Side by Side Diff: test/unittests/interpreter/bytecode-array-builder-unittest.cc

Issue 1343363002: [Interpreter] Basic flow control. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Switch test-bytecode-generator/IfConditions to use new style bytecode array check. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/unittests/compiler/interpreter-assembler-unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/interpreter/bytecode-array-builder.h" 7 #include "src/interpreter/bytecode-array-builder.h"
8 #include "src/interpreter/bytecode-array-iterator.h"
8 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 namespace interpreter { 13 namespace interpreter {
13 14
14 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { 15 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
15 public: 16 public:
16 BytecodeArrayBuilderTest() {} 17 BytecodeArrayBuilderTest() {}
17 ~BytecodeArrayBuilderTest() override {} 18 ~BytecodeArrayBuilderTest() override {}
(...skipping 26 matching lines...) Expand all
44 45
45 // Emit load / store property operations. 46 // Emit load / store property operations.
46 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY) 47 builder.LoadNamedProperty(reg, 0, LanguageMode::SLOPPY)
47 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY) 48 .LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY)
48 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY) 49 .StoreNamedProperty(reg, reg, 0, LanguageMode::SLOPPY)
49 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY); 50 .StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY);
50 51
51 // Call operations. 52 // Call operations.
52 builder.Call(reg, reg, 0); 53 builder.Call(reg, reg, 0);
53 54
54 // Emit binary operators invocations. 55 // Emit binary operator invocations.
55 builder.BinaryOperation(Token::Value::ADD, reg) 56 builder.BinaryOperation(Token::Value::ADD, reg)
56 .BinaryOperation(Token::Value::SUB, reg) 57 .BinaryOperation(Token::Value::SUB, reg)
57 .BinaryOperation(Token::Value::MUL, reg) 58 .BinaryOperation(Token::Value::MUL, reg)
58 .BinaryOperation(Token::Value::DIV, reg) 59 .BinaryOperation(Token::Value::DIV, reg)
59 .BinaryOperation(Token::Value::MOD, reg); 60 .BinaryOperation(Token::Value::MOD, reg);
60 61
62 // Emit test operator invocations.
63 builder.CompareOperation(Token::Value::EQ, reg, LanguageMode::SLOPPY)
64 .CompareOperation(Token::Value::NE, reg, LanguageMode::SLOPPY)
65 .CompareOperation(Token::Value::EQ_STRICT, reg, LanguageMode::SLOPPY)
66 .CompareOperation(Token::Value::NE_STRICT, reg, LanguageMode::SLOPPY)
67 .CompareOperation(Token::Value::LT, reg, LanguageMode::SLOPPY)
68 .CompareOperation(Token::Value::GT, reg, LanguageMode::SLOPPY)
69 .CompareOperation(Token::Value::LTE, reg, LanguageMode::SLOPPY)
70 .CompareOperation(Token::Value::GTE, reg, LanguageMode::SLOPPY)
71 .CompareOperation(Token::Value::INSTANCEOF, reg, LanguageMode::SLOPPY)
72 .CompareOperation(Token::Value::IN, reg, LanguageMode::SLOPPY);
73
74 // Emit cast operator invocations.
75 builder.LoadNull().CastAccumulatorToBoolean();
76
61 // Emit control flow. Return must be the last instruction. 77 // Emit control flow. Return must be the last instruction.
78 BytecodeLabel start;
79 builder.Bind(&start);
80 // Short jumps with Imm8 operands
81 builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
82 // Insert dummy ops to force longer jumps
83 for (int i = 0; i < 128; i++) {
84 builder.LoadTrue();
85 }
86 // Longer jumps requiring Constant operand
87 builder.Jump(&start).JumpIfTrue(&start).JumpIfFalse(&start);
62 builder.Return(); 88 builder.Return();
63 89
64 // Generate BytecodeArray. 90 // Generate BytecodeArray.
65 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); 91 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
66 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); 92 CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize);
67 93
68 // Build scorecard of bytecodes encountered in the BytecodeArray. 94 // Build scorecard of bytecodes encountered in the BytecodeArray.
69 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); 95 std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1);
70 Bytecode final_bytecode = Bytecode::kLdaZero; 96 Bytecode final_bytecode = Bytecode::kLdaZero;
71 for (int i = 0; i < the_array->length(); i++) { 97 for (int i = 0; i < the_array->length(); i++) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 .LoadLiteral(large_smi) 202 .LoadLiteral(large_smi)
177 .LoadLiteral(heap_num_1) 203 .LoadLiteral(heap_num_1)
178 .LoadLiteral(heap_num_1) 204 .LoadLiteral(heap_num_1)
179 .LoadLiteral(heap_num_2_copy); 205 .LoadLiteral(heap_num_2_copy);
180 206
181 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 207 Handle<BytecodeArray> array = builder.ToBytecodeArray();
182 // Should only have one entry for each identical constant. 208 // Should only have one entry for each identical constant.
183 CHECK_EQ(array->constant_pool()->length(), 3); 209 CHECK_EQ(array->constant_pool()->length(), 3);
184 } 210 }
185 211
212
213 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
214 static const int kFarJumpDistance = 256;
215
216 BytecodeArrayBuilder builder(isolate(), zone());
217 builder.set_parameter_count(0);
218 builder.set_locals_count(0);
219
220 BytecodeLabel far0, far1, far2;
221 BytecodeLabel near0, near1, near2;
222
223 builder.Jump(&near0)
224 .JumpIfTrue(&near1)
225 .JumpIfFalse(&near2)
226 .Bind(&near0)
227 .Bind(&near1)
228 .Bind(&near2)
229 .Jump(&far0)
230 .JumpIfTrue(&far1)
231 .JumpIfFalse(&far2);
232 for (int i = 0; i < kFarJumpDistance - 6; i++) {
233 builder.LoadUndefined();
234 }
235 builder.Bind(&far0).Bind(&far1).Bind(&far2);
236 builder.Return();
237
238 Handle<BytecodeArray> array = builder.ToBytecodeArray();
239 DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1);
240
241 BytecodeArrayIterator iterator(array);
242 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
243 CHECK_EQ(iterator.GetSmi8Operand(0), 6);
244 iterator.Advance();
245
246 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
247 CHECK_EQ(iterator.GetSmi8Operand(0), 4);
248 iterator.Advance();
249
250 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
251 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
252 iterator.Advance();
253
254 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
255 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
256 Smi::FromInt(kFarJumpDistance));
257 CHECK_EQ(
258 array->get(iterator.current_offset() +
259 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
260 Bytecodes::ToByte(Bytecode::kReturn));
261 iterator.Advance();
262
263 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
264 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
265 Smi::FromInt(kFarJumpDistance - 2));
266 CHECK_EQ(
267 array->get(iterator.current_offset() +
268 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
269 Bytecodes::ToByte(Bytecode::kReturn));
270 iterator.Advance();
271
272 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
273 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
274 Smi::FromInt(kFarJumpDistance - 4));
275 CHECK_EQ(
276 array->get(iterator.current_offset() +
277 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
278 Bytecodes::ToByte(Bytecode::kReturn));
279 iterator.Advance();
280 }
281
282
283 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
284 BytecodeArrayBuilder builder(isolate(), zone());
285 builder.set_parameter_count(0);
286 builder.set_locals_count(0);
287
288 BytecodeLabel label0, label1, label2;
289 builder.Bind(&label0)
290 .Jump(&label0)
291 .Bind(&label1)
292 .JumpIfTrue(&label1)
293 .Bind(&label2)
294 .JumpIfFalse(&label2);
295 for (int i = 0; i < 64; i++) {
296 builder.Jump(&label2);
297 }
298 builder.JumpIfFalse(&label2);
299 builder.JumpIfTrue(&label1);
300 builder.Jump(&label0);
301 builder.Return();
302
303 Handle<BytecodeArray> array = builder.ToBytecodeArray();
304 BytecodeArrayIterator iterator(array);
305 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
306 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
307 iterator.Advance();
308 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
309 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
310 iterator.Advance();
311 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
312 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
313 iterator.Advance();
314 for (int i = 0; i < 64; i++) {
315 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
316 CHECK_EQ(iterator.GetSmi8Operand(0), -i * 2 - 2);
317 iterator.Advance();
318 }
319 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
320 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130);
321 iterator.Advance();
322 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
323 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134);
324 iterator.Advance();
325 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
326 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138);
327 iterator.Advance();
328 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
329 iterator.Advance();
330 CHECK(iterator.done());
331 }
332
333
334 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
335 BytecodeArrayBuilder builder(isolate(), zone());
336 builder.set_parameter_count(0);
337 builder.set_locals_count(0);
338
339 // Labels can only have 1 forward reference, but
340 // can be referred to mulitple times once bound.
341 BytecodeLabel label;
342
343 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return();
344
345 Handle<BytecodeArray> array = builder.ToBytecodeArray();
346 BytecodeArrayIterator iterator(array);
347 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
348 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
349 iterator.Advance();
350 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
351 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
352 iterator.Advance();
353 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
354 CHECK_EQ(iterator.GetSmi8Operand(0), -2);
355 iterator.Advance();
356 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
357 iterator.Advance();
358 CHECK(iterator.done());
359 }
360
361
362 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
363 static const int kRepeats = 3;
364
365 BytecodeArrayBuilder builder(isolate(), zone());
366 builder.set_parameter_count(0);
367 builder.set_locals_count(0);
368
369 for (int i = 0; i < kRepeats; i++) {
370 BytecodeLabel label;
371 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label);
372 }
373
374 builder.Return();
375
376 Handle<BytecodeArray> array = builder.ToBytecodeArray();
377 BytecodeArrayIterator iterator(array);
378 for (int i = 0; i < kRepeats; i++) {
379 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
380 CHECK_EQ(iterator.GetSmi8Operand(0), 2);
381 iterator.Advance();
382 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
383 CHECK_EQ(iterator.GetSmi8Operand(0), 0);
384 iterator.Advance();
385 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
386 CHECK_EQ(iterator.GetSmi8Operand(0), -2);
387 iterator.Advance();
388 }
389 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
390 iterator.Advance();
391 CHECK(iterator.done());
392 }
393
394
186 } // namespace interpreter 395 } // namespace interpreter
187 } // namespace internal 396 } // namespace internal
188 } // namespace v8 397 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/compiler/interpreter-assembler-unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698