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

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

Issue 1406983010: [Interpreter] Ensure ToBoolean bytecodes are correctly emitted at the start of basic blocks (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Review comments. 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
« no previous file with comments | « test/cctest/interpreter/test-interpreter.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 "src/interpreter/bytecode-array-iterator.h"
9 #include "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 10
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 .JumpIfTrue(&start) 178 .JumpIfTrue(&start)
179 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) 179 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
180 .JumpIfFalse(&start); 180 .JumpIfFalse(&start);
181 // Perform an operation that returns a non-boolean operation to 181 // Perform an operation that returns a non-boolean operation to
182 // generate JumpIfToBooleanTrue/False. 182 // generate JumpIfToBooleanTrue/False.
183 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 183 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
184 .JumpIfTrue(&start) 184 .JumpIfTrue(&start)
185 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 185 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
186 .JumpIfFalse(&start); 186 .JumpIfFalse(&start);
187 187
188 builder.EnterBlock() 188 // Emit throw in it's own basic block so that the rest of the code isn't
189 .Throw() 189 // omitted due to being dead.
190 .LeaveBlock(); 190 BytecodeLabel after_throw;
191 builder.Jump(&after_throw)
192 .Throw()
193 .Bind(&after_throw);
191 194
192 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg); 195 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg);
193 196
194 // Wide constant pool loads 197 // Wide constant pool loads
195 for (int i = 0; i < 256; i++) { 198 for (int i = 0; i < 256; i++) {
196 // Emit junk in constant pool to force wide constant pool index. 199 // Emit junk in constant pool to force wide constant pool index.
197 builder.GetConstantPoolEntry(handle(Smi::FromInt(i), isolate())); 200 builder.GetConstantPoolEntry(handle(Smi::FromInt(i), isolate()));
198 } 201 }
199 builder.LoadLiteral(Smi::FromInt(20000000)); 202 builder.LoadLiteral(Smi::FromInt(20000000));
200 203
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { 479 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
477 BytecodeArrayBuilder builder(isolate(), zone()); 480 BytecodeArrayBuilder builder(isolate(), zone());
478 builder.set_parameter_count(0); 481 builder.set_parameter_count(0);
479 builder.set_locals_count(1); 482 builder.set_locals_count(1);
480 builder.set_context_count(0); 483 builder.set_context_count(0);
481 Register reg(0); 484 Register reg(0);
482 485
483 BytecodeLabel label0, label1, label2, label3, label4; 486 BytecodeLabel label0, label1, label2, label3, label4;
484 builder.Bind(&label0) 487 builder.Bind(&label0)
485 .Jump(&label0) 488 .Jump(&label0)
489 .Bind(&label1)
486 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) 490 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
487 .Bind(&label1)
488 .JumpIfTrue(&label1) 491 .JumpIfTrue(&label1)
492 .Bind(&label2)
489 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK) 493 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
490 .Bind(&label2)
491 .JumpIfFalse(&label2) 494 .JumpIfFalse(&label2)
495 .Bind(&label3)
492 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 496 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
493 .Bind(&label3)
494 .JumpIfTrue(&label3) 497 .JumpIfTrue(&label3)
498 .Bind(&label4)
495 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 499 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
496 .Bind(&label4)
497 .JumpIfFalse(&label4); 500 .JumpIfFalse(&label4);
498 for (int i = 0; i < 64; i++) { 501 for (int i = 0; i < 63; i++) {
499 builder.Jump(&label4); 502 builder.Jump(&label4);
500 } 503 }
501 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 504 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
502 .JumpIfFalse(&label4); 505 .JumpIfFalse(&label4);
503 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) 506 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
504 .JumpIfTrue(&label3); 507 .JumpIfTrue(&label3);
505 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) 508 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
506 .JumpIfFalse(&label2); 509 .JumpIfFalse(&label2);
507 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) 510 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
508 .JumpIfTrue(&label1); 511 .JumpIfTrue(&label1);
509 builder.Jump(&label0); 512 builder.Jump(&label0);
510 builder.Return(); 513 builder.Return();
511 514
512 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 515 Handle<BytecodeArray> array = builder.ToBytecodeArray();
513 BytecodeArrayIterator iterator(array); 516 BytecodeArrayIterator iterator(array);
514 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 517 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
515 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 518 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
516 iterator.Advance(); 519 iterator.Advance();
517 // Ignore compare operation. 520 // Ignore compare operation.
518 iterator.Advance(); 521 iterator.Advance();
519 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); 522 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
520 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 523 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
521 iterator.Advance(); 524 iterator.Advance();
522 // Ignore compare operation. 525 // Ignore compare operation.
523 iterator.Advance(); 526 iterator.Advance();
524 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); 527 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
525 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 528 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
526 iterator.Advance(); 529 iterator.Advance();
527 // Ignore binary operation. 530 // Ignore binary operation.
528 iterator.Advance(); 531 iterator.Advance();
529 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); 532 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
530 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 533 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
531 iterator.Advance(); 534 iterator.Advance();
532 // Ignore binary operation. 535 // Ignore binary operation.
533 iterator.Advance(); 536 iterator.Advance();
534 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); 537 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
535 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 538 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
536 iterator.Advance(); 539 iterator.Advance();
537 for (int i = 0; i < 64; i++) { 540 for (int i = 0; i < 63; i++) {
538 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 541 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
539 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2); 542 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 4);
540 iterator.Advance(); 543 iterator.Advance();
541 } 544 }
542 // Ignore binary operation. 545 // Ignore binary operation.
543 iterator.Advance(); 546 iterator.Advance();
544 CHECK_EQ(iterator.current_bytecode(), 547 CHECK_EQ(iterator.current_bytecode(),
545 Bytecode::kJumpIfToBooleanFalseConstant); 548 Bytecode::kJumpIfToBooleanFalseConstant);
546 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -132); 549 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -132);
547 iterator.Advance(); 550 iterator.Advance();
548 // Ignore binary operation. 551 // Ignore binary operation.
549 iterator.Advance(); 552 iterator.Advance();
550 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); 553 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
551 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -140); 554 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -140);
552 iterator.Advance(); 555 iterator.Advance();
553 // Ignore compare operation. 556 // Ignore compare operation.
554 iterator.Advance(); 557 iterator.Advance();
555 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); 558 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
556 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -148); 559 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -148);
557 iterator.Advance(); 560 iterator.Advance();
558 // Ignore compare operation. 561 // Ignore compare operation.
559 iterator.Advance(); 562 iterator.Advance();
560 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 563 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
561 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -156); 564 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -156);
562 iterator.Advance(); 565 iterator.Advance();
563 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 566 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
564 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -162); 567 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -160);
565 iterator.Advance(); 568 iterator.Advance();
566 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 569 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
567 iterator.Advance(); 570 iterator.Advance();
568 CHECK(iterator.done()); 571 CHECK(iterator.done());
569 } 572 }
570 573
571 574
572 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { 575 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
573 BytecodeArrayBuilder builder(isolate(), zone()); 576 BytecodeArrayBuilder builder(isolate(), zone());
574 builder.set_parameter_count(0); 577 builder.set_parameter_count(0);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 CHECK(iterator.done()); 634 CHECK(iterator.done());
632 } 635 }
633 636
634 637
635 TEST_F(BytecodeArrayBuilderTest, ToBoolean) { 638 TEST_F(BytecodeArrayBuilderTest, ToBoolean) {
636 BytecodeArrayBuilder builder(isolate(), zone()); 639 BytecodeArrayBuilder builder(isolate(), zone());
637 builder.set_parameter_count(0); 640 builder.set_parameter_count(0);
638 builder.set_locals_count(0); 641 builder.set_locals_count(0);
639 builder.set_context_count(0); 642 builder.set_context_count(0);
640 643
641 // Check ToBoolean emitted at start of block. 644 // Check ToBoolean emitted at start of a basic block.
642 builder.EnterBlock().CastAccumulatorToBoolean(); 645 builder.CastAccumulatorToBoolean();
643 646
644 // Check ToBoolean emitted preceding bytecode is non-boolean. 647 // Check ToBoolean emitted preceding bytecode is non-boolean.
645 builder.LoadNull().CastAccumulatorToBoolean(); 648 builder.LoadNull().CastAccumulatorToBoolean();
646 649
647 // Check ToBoolean omitted if preceding bytecode is boolean. 650 // Check ToBoolean omitted if preceding bytecode is boolean.
648 builder.LoadFalse().CastAccumulatorToBoolean(); 651 builder.LoadFalse().CastAccumulatorToBoolean();
649 652
650 // Check ToBoolean emitted if it is at the start of the next block. 653 // Check ToBoolean emitted if it is at the start of a basic block caused by a
654 // bound label.
655 BytecodeLabel label;
651 builder.LoadFalse() 656 builder.LoadFalse()
652 .LeaveBlock() 657 .Bind(&label)
653 .EnterBlock() 658 .CastAccumulatorToBoolean();
654 .CastAccumulatorToBoolean() 659
655 .LeaveBlock(); 660 // Check ToBoolean emitted if it is at the start of a basic block caused by a
661 // jump.
662 builder.LoadFalse()
663 .JumpIfTrue(&label)
664 .CastAccumulatorToBoolean();
656 665
657 builder.Return(); 666 builder.Return();
658 667
659 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 668 Handle<BytecodeArray> array = builder.ToBytecodeArray();
660 BytecodeArrayIterator iterator(array); 669 BytecodeArrayIterator iterator(array);
661 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean); 670 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
662 iterator.Advance(); 671 iterator.Advance();
663 672
664 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaNull); 673 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaNull);
665 iterator.Advance(); 674 iterator.Advance();
666 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean); 675 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
667 iterator.Advance(); 676 iterator.Advance();
668 677
669 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse); 678 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
670 iterator.Advance(); 679 iterator.Advance();
671 680
672 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse); 681 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
673 iterator.Advance(); 682 iterator.Advance();
674 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean); 683 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
675 iterator.Advance(); 684 iterator.Advance();
676 685
686 CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
687 iterator.Advance();
688 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
689 iterator.Advance();
690 CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
691 iterator.Advance();
692
677 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 693 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
678 iterator.Advance(); 694 iterator.Advance();
679 CHECK(iterator.done()); 695 CHECK(iterator.done());
680 } 696 }
681 697
682 698
683 } // namespace interpreter 699 } // namespace interpreter
684 } // namespace internal 700 } // namespace internal
685 } // namespace v8 701 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-interpreter.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698