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

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

Issue 1426913002: [Interpreter] Merges ToBoolean and JumpIfTrue/False bytecodes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Last patch was not complete. Forgot few changes. Created 5 years, 1 month 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
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 "src/interpreter/bytecode-array-iterator.h"
9 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 10
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 125
126 // Emit cast operator invocations. 126 // Emit cast operator invocations.
127 builder.CastAccumulatorToNumber() 127 builder.CastAccumulatorToNumber()
128 .CastAccumulatorToBoolean() 128 .CastAccumulatorToBoolean()
129 .CastAccumulatorToName(); 129 .CastAccumulatorToName();
130 130
131 // Emit control flow. Return must be the last instruction. 131 // Emit control flow. Return must be the last instruction.
132 BytecodeLabel start; 132 BytecodeLabel start;
133 builder.Bind(&start); 133 builder.Bind(&start);
134 // Short jumps with Imm8 operands 134 // Short jumps with Imm8 operands
135 builder.Jump(&start) 135 builder.Jump(&start);
136 // Perform an operation that returns boolean value to
137 // generate JumpIfTrue/False
138 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
136 .JumpIfTrue(&start) 139 .JumpIfTrue(&start)
137 .JumpIfFalse(&start) 140 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
138 .JumpIfToBooleanTrue(&start) 141 .JumpIfFalse(&start);
139 .JumpIfToBooleanFalse(&start); 142 // Perform an operation that returns a non-boolean operation to
143 // generate JumpIfToBooleanTrue/False.
144 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
145 .JumpIfTrue(&start)
146 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
147 .JumpIfFalse(&start);
140 // Insert dummy ops to force longer jumps 148 // Insert dummy ops to force longer jumps
141 for (int i = 0; i < 128; i++) { 149 for (int i = 0; i < 128; i++) {
142 builder.LoadTrue(); 150 builder.LoadTrue();
143 } 151 }
144 // Longer jumps requiring Constant operand 152 // Longer jumps requiring Constant operand
145 builder.Jump(&start) 153 builder.Jump(&start);
154 // Perform an operation that returns boolean value to
155 // generate JumpIfTrue/False
156 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
146 .JumpIfTrue(&start) 157 .JumpIfTrue(&start)
147 .JumpIfFalse(&start) 158 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
148 .JumpIfToBooleanTrue(&start) 159 .JumpIfFalse(&start);
149 .JumpIfToBooleanFalse(&start); 160 // Perform an operation that returns a non-boolean operation to
161 // generate JumpIfToBooleanTrue/False.
162 builder.JumpIfTrue(&start).JumpIfFalse(&start);
150 163
151 builder.EnterBlock() 164 builder.EnterBlock()
152 .Throw() 165 .Throw()
153 .LeaveBlock(); 166 .LeaveBlock();
154 167
155 builder.Return(); 168 builder.Return();
156 169
157 // Generate BytecodeArray. 170 // Generate BytecodeArray.
158 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); 171 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
159 CHECK_EQ(the_array->frame_size(), 172 CHECK_EQ(the_array->frame_size(),
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // Should only have one entry for each identical constant. 320 // Should only have one entry for each identical constant.
308 CHECK_EQ(array->constant_pool()->length(), 3); 321 CHECK_EQ(array->constant_pool()->length(), 3);
309 } 322 }
310 323
311 324
312 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { 325 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
313 static const int kFarJumpDistance = 256; 326 static const int kFarJumpDistance = 256;
314 327
315 BytecodeArrayBuilder builder(isolate(), zone()); 328 BytecodeArrayBuilder builder(isolate(), zone());
316 builder.set_parameter_count(0); 329 builder.set_parameter_count(0);
317 builder.set_locals_count(0); 330 builder.set_locals_count(1);
318 builder.set_context_count(0); 331 builder.set_context_count(0);
319 332
320 BytecodeLabel far0, far1, far2; 333 Register reg(0);
321 BytecodeLabel near0, near1, near2; 334 BytecodeLabel far0, far1, far2, far3, far4;
335 BytecodeLabel near0, near1, near2, near3, near4;
322 336
323 builder.Jump(&near0) 337 builder.Jump(&near0)
338 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
324 .JumpIfTrue(&near1) 339 .JumpIfTrue(&near1)
340 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
325 .JumpIfFalse(&near2) 341 .JumpIfFalse(&near2)
342 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
343 .JumpIfTrue(&near3)
344 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
345 .JumpIfFalse(&near4)
326 .Bind(&near0) 346 .Bind(&near0)
327 .Bind(&near1) 347 .Bind(&near1)
328 .Bind(&near2) 348 .Bind(&near2)
349 .Bind(&near3)
350 .Bind(&near4)
329 .Jump(&far0) 351 .Jump(&far0)
352 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
330 .JumpIfTrue(&far1) 353 .JumpIfTrue(&far1)
331 .JumpIfFalse(&far2); 354 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
332 for (int i = 0; i < kFarJumpDistance - 6; i++) { 355 .JumpIfFalse(&far2)
356 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
357 .JumpIfTrue(&far3)
358 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
359 .JumpIfFalse(&far4);
360 for (int i = 0; i < kFarJumpDistance - 18; i++) {
333 builder.LoadUndefined(); 361 builder.LoadUndefined();
334 } 362 }
335 builder.Bind(&far0).Bind(&far1).Bind(&far2); 363 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4);
336 builder.Return(); 364 builder.Return();
337 365
338 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 366 Handle<BytecodeArray> array = builder.ToBytecodeArray();
339 DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1); 367 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1);
340 368
341 BytecodeArrayIterator iterator(array); 369 BytecodeArrayIterator iterator(array);
342 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 370 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
371 CHECK_EQ(iterator.GetImmediateOperand(0), 18);
372 iterator.Advance();
373
374 // Ignore compare operation.
375 iterator.Advance();
376
377 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
378 CHECK_EQ(iterator.GetImmediateOperand(0), 14);
379 iterator.Advance();
380
381 // Ignore compare operation.
382 iterator.Advance();
383
384 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
385 CHECK_EQ(iterator.GetImmediateOperand(0), 10);
386 iterator.Advance();
387
388 // Ignore add operation.
389 iterator.Advance();
390
391 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
343 CHECK_EQ(iterator.GetImmediateOperand(0), 6); 392 CHECK_EQ(iterator.GetImmediateOperand(0), 6);
344 iterator.Advance(); 393 iterator.Advance();
345 394
346 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); 395 // Ignore add operation.
347 CHECK_EQ(iterator.GetImmediateOperand(0), 4);
348 iterator.Advance(); 396 iterator.Advance();
349 397
350 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); 398 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
351 CHECK_EQ(iterator.GetImmediateOperand(0), 2); 399 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
352 iterator.Advance(); 400 iterator.Advance();
353 401
402
354 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 403 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
355 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 404 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
356 Smi::FromInt(kFarJumpDistance)); 405 Smi::FromInt(kFarJumpDistance));
357 CHECK_EQ( 406 CHECK_EQ(
358 array->get(iterator.current_offset() + 407 array->get(iterator.current_offset() +
359 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 408 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
360 Bytecodes::ToByte(Bytecode::kReturn)); 409 Bytecodes::ToByte(Bytecode::kReturn));
361 iterator.Advance(); 410 iterator.Advance();
362 411
412 // Ignore compare operation.
413 iterator.Advance();
414
363 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 415 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
364 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 416 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
365 Smi::FromInt(kFarJumpDistance - 2)); 417 Smi::FromInt(kFarJumpDistance - 4));
366 CHECK_EQ( 418 CHECK_EQ(
367 array->get(iterator.current_offset() + 419 array->get(iterator.current_offset() +
368 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 420 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
369 Bytecodes::ToByte(Bytecode::kReturn)); 421 Bytecodes::ToByte(Bytecode::kReturn));
370 iterator.Advance(); 422 iterator.Advance();
371 423
424 // Ignore compare operation.
425 iterator.Advance();
426
372 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); 427 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
373 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 428 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
374 Smi::FromInt(kFarJumpDistance - 4)); 429 Smi::FromInt(kFarJumpDistance - 8));
375 CHECK_EQ( 430 CHECK_EQ(
376 array->get(iterator.current_offset() + 431 array->get(iterator.current_offset() +
377 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 432 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
433 Bytecodes::ToByte(Bytecode::kReturn));
434 iterator.Advance();
435
436 // Ignore add operation.
437 iterator.Advance();
438
439 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
440 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
441 Smi::FromInt(kFarJumpDistance - 12));
442 CHECK_EQ(
443 array->get(iterator.current_offset() +
444 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
445 Bytecodes::ToByte(Bytecode::kReturn));
rmcilroy 2015/10/30 10:36:00 I'm not convinced this check is necessary (given i
mythria 2015/10/30 11:44:47 Done.
446 iterator.Advance();
447
448 // Ignore add operation.
449 iterator.Advance();
450
451 CHECK_EQ(iterator.current_bytecode(),
452 Bytecode::kJumpIfToBooleanFalseConstant);
453 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
454 Smi::FromInt(kFarJumpDistance - 16));
455 CHECK_EQ(
456 array->get(iterator.current_offset() +
457 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()),
rmcilroy 2015/10/30 10:36:00 ditto
mythria 2015/10/30 11:44:47 Done.
378 Bytecodes::ToByte(Bytecode::kReturn)); 458 Bytecodes::ToByte(Bytecode::kReturn));
379 iterator.Advance(); 459 iterator.Advance();
380 } 460 }
381 461
382 462
383 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { 463 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
384 BytecodeArrayBuilder builder(isolate(), zone()); 464 BytecodeArrayBuilder builder(isolate(), zone());
385 builder.set_parameter_count(0); 465 builder.set_parameter_count(0);
386 builder.set_locals_count(0); 466 builder.set_locals_count(1);
387 builder.set_context_count(0); 467 builder.set_context_count(0);
468 Register reg(0);
388 469
389 BytecodeLabel label0, label1, label2; 470 BytecodeLabel label0, label1, label2, label3, label4;
390 builder.Bind(&label0) 471 builder.Bind(&label0)
391 .Jump(&label0) 472 .Jump(&label0)
473 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
392 .Bind(&label1) 474 .Bind(&label1)
393 .JumpIfTrue(&label1) 475 .JumpIfTrue(&label1)
476 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
394 .Bind(&label2) 477 .Bind(&label2)
478 .JumpIfFalse(&label2)
479 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
480 .Bind(&label3)
481 .JumpIfTrue(&label3)
482 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
483 .Bind(&label4)
484 .JumpIfFalse(&label4);
485 for (int i = 0; i < 64; i++) {
486 builder.Jump(&label4);
487 }
488 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
489 .JumpIfFalse(&label4);
490 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
491 .JumpIfTrue(&label3);
492 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
395 .JumpIfFalse(&label2); 493 .JumpIfFalse(&label2);
396 for (int i = 0; i < 64; i++) { 494 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
397 builder.Jump(&label2); 495 .JumpIfTrue(&label1);
398 }
399 builder.JumpIfFalse(&label2);
400 builder.JumpIfTrue(&label1);
401 builder.Jump(&label0); 496 builder.Jump(&label0);
402 builder.Return(); 497 builder.Return();
403 498
404 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 499 Handle<BytecodeArray> array = builder.ToBytecodeArray();
405 BytecodeArrayIterator iterator(array); 500 BytecodeArrayIterator iterator(array);
406 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 501 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
407 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 502 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
408 iterator.Advance(); 503 iterator.Advance();
504 // Ignore compare operation.
505 iterator.Advance();
409 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); 506 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
410 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 507 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
411 iterator.Advance(); 508 iterator.Advance();
509 // Ignore compare operation.
510 iterator.Advance();
412 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); 511 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
413 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 512 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
414 iterator.Advance(); 513 iterator.Advance();
514 // Ignore binary operation.
515 iterator.Advance();
516 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
517 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
518 iterator.Advance();
519 // Ignore binary operation.
520 iterator.Advance();
521 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
522 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
523 iterator.Advance();
415 for (int i = 0; i < 64; i++) { 524 for (int i = 0; i < 64; i++) {
416 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 525 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
417 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2); 526 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2);
418 iterator.Advance(); 527 iterator.Advance();
419 } 528 }
529 // Ignore binary operation.
530 iterator.Advance();
531 CHECK_EQ(iterator.current_bytecode(),
532 Bytecode::kJumpIfToBooleanFalseConstant);
533 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -132);
534 iterator.Advance();
535 // Ignore binary operation.
536 iterator.Advance();
537 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
538 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -140);
539 iterator.Advance();
540 // Ignore compare operation.
541 iterator.Advance();
420 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); 542 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
421 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130); 543 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -148);
544 iterator.Advance();
545 // Ignore compare operation.
422 iterator.Advance(); 546 iterator.Advance();
423 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 547 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
424 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134); 548 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -156);
425 iterator.Advance(); 549 iterator.Advance();
426 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 550 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
427 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138); 551 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -162);
428 iterator.Advance(); 552 iterator.Advance();
429 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 553 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
430 iterator.Advance(); 554 iterator.Advance();
431 CHECK(iterator.done()); 555 CHECK(iterator.done());
432 } 556 }
433 557
434 558
435 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { 559 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
436 BytecodeArrayBuilder builder(isolate(), zone()); 560 BytecodeArrayBuilder builder(isolate(), zone());
437 builder.set_parameter_count(0); 561 builder.set_parameter_count(0);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 663
540 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 664 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
541 iterator.Advance(); 665 iterator.Advance();
542 CHECK(iterator.done()); 666 CHECK(iterator.done());
543 } 667 }
544 668
545 669
546 } // namespace interpreter 670 } // namespace interpreter
547 } // namespace internal 671 } // namespace internal
548 } // namespace v8 672 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698