| OLD | NEW |
| 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 "src/interpreter/bytecode-label.h" | 9 #include "src/interpreter/bytecode-label.h" |
| 10 #include "src/interpreter/bytecode-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 builder.Debugger(); | 561 builder.Debugger(); |
| 562 } | 562 } |
| 563 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); | 563 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4); |
| 564 builder.Return(); | 564 builder.Return(); |
| 565 | 565 |
| 566 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 566 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
| 567 DCHECK_EQ(array->length(), 44 + kFarJumpDistance - 22 + 1); | 567 DCHECK_EQ(array->length(), 44 + kFarJumpDistance - 22 + 1); |
| 568 | 568 |
| 569 BytecodeArrayIterator iterator(array); | 569 BytecodeArrayIterator iterator(array); |
| 570 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 570 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 571 CHECK_EQ(iterator.GetImmediateOperand(0), 22); | 571 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 22); |
| 572 iterator.Advance(); | 572 iterator.Advance(); |
| 573 | 573 |
| 574 // Ignore compare operation. | 574 // Ignore compare operation. |
| 575 iterator.Advance(); | 575 iterator.Advance(); |
| 576 | 576 |
| 577 CHECK_EQ(iterator.current_bytecode(), | 577 CHECK_EQ(iterator.current_bytecode(), |
| 578 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | 578 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); |
| 579 CHECK_EQ(iterator.GetImmediateOperand(0), 17); | 579 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 17); |
| 580 iterator.Advance(); | 580 iterator.Advance(); |
| 581 | 581 |
| 582 // Ignore compare operation. | 582 // Ignore compare operation. |
| 583 iterator.Advance(); | 583 iterator.Advance(); |
| 584 | 584 |
| 585 CHECK_EQ(iterator.current_bytecode(), | 585 CHECK_EQ(iterator.current_bytecode(), |
| 586 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | 586 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); |
| 587 CHECK_EQ(iterator.GetImmediateOperand(0), 12); | 587 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 12); |
| 588 iterator.Advance(); | 588 iterator.Advance(); |
| 589 | 589 |
| 590 // Ignore add operation. | 590 // Ignore add operation. |
| 591 iterator.Advance(); | 591 iterator.Advance(); |
| 592 | 592 |
| 593 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 593 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 594 CHECK_EQ(iterator.GetImmediateOperand(0), 7); | 594 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 7); |
| 595 iterator.Advance(); | 595 iterator.Advance(); |
| 596 | 596 |
| 597 // Ignore add operation. | 597 // Ignore add operation. |
| 598 iterator.Advance(); | 598 iterator.Advance(); |
| 599 | 599 |
| 600 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 600 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
| 601 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 601 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2); |
| 602 iterator.Advance(); | 602 iterator.Advance(); |
| 603 | 603 |
| 604 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 604 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
| 605 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 605 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 606 Smi::FromInt(kFarJumpDistance)); | 606 Smi::FromInt(kFarJumpDistance)); |
| 607 iterator.Advance(); | 607 iterator.Advance(); |
| 608 | 608 |
| 609 // Ignore compare operation. | 609 // Ignore compare operation. |
| 610 iterator.Advance(); | 610 iterator.Advance(); |
| 611 | 611 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 } | 662 } |
| 663 | 663 |
| 664 builder.JumpLoop(&label0, 0); | 664 builder.JumpLoop(&label0, 0); |
| 665 BytecodeLabel end; | 665 BytecodeLabel end; |
| 666 builder.Bind(&end); | 666 builder.Bind(&end); |
| 667 builder.Return(); | 667 builder.Return(); |
| 668 | 668 |
| 669 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 669 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
| 670 BytecodeArrayIterator iterator(array); | 670 BytecodeArrayIterator iterator(array); |
| 671 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 671 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 672 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 672 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0); |
| 673 iterator.Advance(); | 673 iterator.Advance(); |
| 674 for (int i = 0; i < 42; i++) { | 674 for (unsigned i = 0; i < 42; i++) { |
| 675 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 675 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 676 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 676 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
| 677 // offset of 3 (because kJumpLoop takes two immediate operands) | 677 // offset of 3 (because kJumpLoop takes two immediate operands) |
| 678 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 3 - 3); | 678 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), i * 3 + 3); |
| 679 iterator.Advance(); | 679 iterator.Advance(); |
| 680 } | 680 } |
| 681 // Check padding to force wide backwards jumps. | 681 // Check padding to force wide backwards jumps. |
| 682 for (int i = 0; i < 256; i++) { | 682 for (int i = 0; i < 256; i++) { |
| 683 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); | 683 CHECK_EQ(iterator.current_bytecode(), Bytecode::kDebugger); |
| 684 iterator.Advance(); | 684 iterator.Advance(); |
| 685 } | 685 } |
| 686 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 686 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 687 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 687 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
| 688 CHECK_EQ(iterator.GetImmediateOperand(0), -386); | 688 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 386); |
| 689 iterator.Advance(); | 689 iterator.Advance(); |
| 690 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 690 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 691 iterator.Advance(); | 691 iterator.Advance(); |
| 692 CHECK(iterator.done()); | 692 CHECK(iterator.done()); |
| 693 } | 693 } |
| 694 | 694 |
| 695 | 695 |
| 696 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { | 696 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { |
| 697 CanonicalHandleScope canonical(isolate()); | 697 CanonicalHandleScope canonical(isolate()); |
| 698 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); | 698 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); |
| 699 | 699 |
| 700 // Labels can only have 1 forward reference, but | 700 // Labels can only have 1 forward reference, but |
| 701 // can be referred to mulitple times once bound. | 701 // can be referred to mulitple times once bound. |
| 702 BytecodeLabel label, after_jump0, after_jump1; | 702 BytecodeLabel label, after_jump0, after_jump1; |
| 703 | 703 |
| 704 builder.Jump(&label) | 704 builder.Jump(&label) |
| 705 .Bind(&label) | 705 .Bind(&label) |
| 706 .JumpLoop(&label, 0) | 706 .JumpLoop(&label, 0) |
| 707 .Bind(&after_jump0) | 707 .Bind(&after_jump0) |
| 708 .JumpLoop(&label, 0) | 708 .JumpLoop(&label, 0) |
| 709 .Bind(&after_jump1) | 709 .Bind(&after_jump1) |
| 710 .Return(); | 710 .Return(); |
| 711 | 711 |
| 712 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 712 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
| 713 BytecodeArrayIterator iterator(array); | 713 BytecodeArrayIterator iterator(array); |
| 714 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 714 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 715 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 715 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2); |
| 716 iterator.Advance(); | 716 iterator.Advance(); |
| 717 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 717 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 718 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 718 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0); |
| 719 iterator.Advance(); | 719 iterator.Advance(); |
| 720 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 720 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 721 CHECK_EQ(iterator.GetImmediateOperand(0), -3); | 721 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 3); |
| 722 iterator.Advance(); | 722 iterator.Advance(); |
| 723 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 723 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 724 iterator.Advance(); | 724 iterator.Advance(); |
| 725 CHECK(iterator.done()); | 725 CHECK(iterator.done()); |
| 726 } | 726 } |
| 727 | 727 |
| 728 | 728 |
| 729 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { | 729 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { |
| 730 CanonicalHandleScope canonical(isolate()); | 730 CanonicalHandleScope canonical(isolate()); |
| 731 static const int kRepeats = 3; | 731 static const int kRepeats = 3; |
| 732 | 732 |
| 733 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); | 733 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); |
| 734 for (int i = 0; i < kRepeats; i++) { | 734 for (int i = 0; i < kRepeats; i++) { |
| 735 BytecodeLabel label, after_jump0, after_jump1; | 735 BytecodeLabel label, after_jump0, after_jump1; |
| 736 builder.Jump(&label) | 736 builder.Jump(&label) |
| 737 .Bind(&label) | 737 .Bind(&label) |
| 738 .JumpLoop(&label, 0) | 738 .JumpLoop(&label, 0) |
| 739 .Bind(&after_jump0) | 739 .Bind(&after_jump0) |
| 740 .JumpLoop(&label, 0) | 740 .JumpLoop(&label, 0) |
| 741 .Bind(&after_jump1); | 741 .Bind(&after_jump1); |
| 742 } | 742 } |
| 743 builder.Return(); | 743 builder.Return(); |
| 744 | 744 |
| 745 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); | 745 Handle<BytecodeArray> array = builder.ToBytecodeArray(isolate()); |
| 746 BytecodeArrayIterator iterator(array); | 746 BytecodeArrayIterator iterator(array); |
| 747 for (int i = 0; i < kRepeats; i++) { | 747 for (int i = 0; i < kRepeats; i++) { |
| 748 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 748 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 749 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 749 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 2); |
| 750 iterator.Advance(); | 750 iterator.Advance(); |
| 751 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 751 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 752 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 752 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 0); |
| 753 iterator.Advance(); | 753 iterator.Advance(); |
| 754 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); | 754 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpLoop); |
| 755 CHECK_EQ(iterator.GetImmediateOperand(0), -3); | 755 CHECK_EQ(iterator.GetUnsignedImmediateOperand(0), 3); |
| 756 iterator.Advance(); | 756 iterator.Advance(); |
| 757 } | 757 } |
| 758 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 758 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 759 iterator.Advance(); | 759 iterator.Advance(); |
| 760 CHECK(iterator.done()); | 760 CHECK(iterator.done()); |
| 761 } | 761 } |
| 762 | 762 |
| 763 } // namespace interpreter | 763 } // namespace interpreter |
| 764 } // namespace internal | 764 } // namespace internal |
| 765 } // namespace v8 | 765 } // namespace v8 |
| OLD | NEW |