Chromium Code Reviews| 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-register-allocator.h" | 10 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "test/unittests/test-utils.h" | 11 #include "test/unittests/test-utils.h" |
| 11 | 12 |
| 12 namespace v8 { | 13 namespace v8 { |
| 13 namespace internal { | 14 namespace internal { |
| 14 namespace interpreter { | 15 namespace interpreter { |
| 15 | 16 |
| 16 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { | 17 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { |
| 17 public: | 18 public: |
| 18 BytecodeArrayBuilderTest() {} | 19 BytecodeArrayBuilderTest() {} |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 } | 346 } |
| 346 i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale); | 347 i += prefix_offset + Bytecodes::Size(final_bytecode, operand_scale); |
| 347 } | 348 } |
| 348 | 349 |
| 349 // Insert entry for illegal bytecode as this is never willingly emitted. | 350 // Insert entry for illegal bytecode as this is never willingly emitted. |
| 350 scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1; | 351 scorecard[Bytecodes::ToByte(Bytecode::kIllegal)] = 1; |
| 351 | 352 |
| 352 // Insert entry for nop bytecode as this often gets optimized out. | 353 // Insert entry for nop bytecode as this often gets optimized out. |
| 353 scorecard[Bytecodes::ToByte(Bytecode::kNop)] = 1; | 354 scorecard[Bytecodes::ToByte(Bytecode::kNop)] = 1; |
| 354 | 355 |
| 355 // Insert entries for bytecodes only emiited by peephole optimizer. | 356 // Insert entries for bytecodes only emiited by peephole optimizer. |
|
oth
2016/06/03 09:50:21
emitted
rmcilroy
2016/06/03 14:27:15
Done.
| |
| 356 scorecard[Bytecodes::ToByte(Bytecode::kLdrNamedProperty)] = 1; | 357 scorecard[Bytecodes::ToByte(Bytecode::kLdrNamedProperty)] = 1; |
| 357 scorecard[Bytecodes::ToByte(Bytecode::kLdrKeyedProperty)] = 1; | 358 scorecard[Bytecodes::ToByte(Bytecode::kLdrKeyedProperty)] = 1; |
| 358 scorecard[Bytecodes::ToByte(Bytecode::kLdrGlobal)] = 1; | 359 scorecard[Bytecodes::ToByte(Bytecode::kLdrGlobal)] = 1; |
| 359 scorecard[Bytecodes::ToByte(Bytecode::kLdrContextSlot)] = 1; | 360 scorecard[Bytecodes::ToByte(Bytecode::kLdrContextSlot)] = 1; |
| 360 scorecard[Bytecodes::ToByte(Bytecode::kLdrUndefined)] = 1; | 361 scorecard[Bytecodes::ToByte(Bytecode::kLdrUndefined)] = 1; |
| 362 if (!FLAG_ignition_peephole) { | |
|
oth
2016/06/03 09:50:21
Comment here explaining why the delta.
rmcilroy
2016/06/03 14:27:15
Added writes for the preceding Ldr instructions an
| |
| 363 scorecard[Bytecodes::ToByte(Bytecode::kLogicalNot)] = 1; | |
| 364 scorecard[Bytecodes::ToByte(Bytecode::kJump)] = 1; | |
| 365 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrue)] = 1; | |
| 366 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalse)] = 1; | |
| 367 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfTrueConstant)] = 1; | |
| 368 scorecard[Bytecodes::ToByte(Bytecode::kJumpIfFalseConstant)] = 1; | |
| 369 } | |
| 361 | 370 |
| 362 // Check return occurs at the end and only once in the BytecodeArray. | 371 // Check return occurs at the end and only once in the BytecodeArray. |
| 363 CHECK_EQ(final_bytecode, Bytecode::kReturn); | 372 CHECK_EQ(final_bytecode, Bytecode::kReturn); |
| 364 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); | 373 CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); |
| 365 | 374 |
| 366 #define CHECK_BYTECODE_PRESENT(Name, ...) \ | 375 #define CHECK_BYTECODE_PRESENT(Name, ...) \ |
| 367 /* Check Bytecode is marked in scorecard, unless it's a debug break */ \ | 376 /* Check Bytecode is marked in scorecard, unless it's a debug break */ \ |
| 368 if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) { \ | 377 if (!Bytecodes::IsDebugBreak(Bytecode::k##Name)) { \ |
| 369 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); \ | 378 CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); \ |
| 370 } | 379 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 .LoadLiteral(heap_num_1) | 472 .LoadLiteral(heap_num_1) |
| 464 .LoadLiteral(heap_num_1) | 473 .LoadLiteral(heap_num_1) |
| 465 .LoadLiteral(heap_num_2_copy) | 474 .LoadLiteral(heap_num_2_copy) |
| 466 .Return(); | 475 .Return(); |
| 467 | 476 |
| 468 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 477 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 469 // Should only have one entry for each identical constant. | 478 // Should only have one entry for each identical constant. |
| 470 CHECK_EQ(array->constant_pool()->length(), 3); | 479 CHECK_EQ(array->constant_pool()->length(), 3); |
| 471 } | 480 } |
| 472 | 481 |
| 482 static Bytecode PeepholeToBoolean(Bytecode jump_bytecode) { | |
| 483 return FLAG_ignition_peephole | |
| 484 ? Bytecodes::GetJumpWithoutToBoolean(jump_bytecode) | |
| 485 : jump_bytecode; | |
| 486 } | |
| 473 | 487 |
| 474 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { | 488 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { |
| 475 static const int kFarJumpDistance = 256; | 489 static const int kFarJumpDistance = 256; |
| 476 | 490 |
| 477 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); | 491 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); |
| 478 | 492 |
| 479 Register reg(0); | 493 Register reg(0); |
| 480 BytecodeLabel far0, far1, far2, far3, far4; | 494 BytecodeLabel far0, far1, far2, far3, far4; |
| 481 BytecodeLabel near0, near1, near2, near3, near4; | 495 BytecodeLabel near0, near1, near2, near3, near4; |
| 482 | 496 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 513 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); | 527 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1); |
| 514 | 528 |
| 515 BytecodeArrayIterator iterator(array); | 529 BytecodeArrayIterator iterator(array); |
| 516 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 530 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 517 CHECK_EQ(iterator.GetImmediateOperand(0), 18); | 531 CHECK_EQ(iterator.GetImmediateOperand(0), 18); |
| 518 iterator.Advance(); | 532 iterator.Advance(); |
| 519 | 533 |
| 520 // Ignore compare operation. | 534 // Ignore compare operation. |
| 521 iterator.Advance(); | 535 iterator.Advance(); |
| 522 | 536 |
| 523 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); | 537 CHECK_EQ(iterator.current_bytecode(), |
| 538 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | |
| 524 CHECK_EQ(iterator.GetImmediateOperand(0), 14); | 539 CHECK_EQ(iterator.GetImmediateOperand(0), 14); |
| 525 iterator.Advance(); | 540 iterator.Advance(); |
| 526 | 541 |
| 527 // Ignore compare operation. | 542 // Ignore compare operation. |
| 528 iterator.Advance(); | 543 iterator.Advance(); |
| 529 | 544 |
| 530 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); | 545 CHECK_EQ(iterator.current_bytecode(), |
| 546 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | |
| 531 CHECK_EQ(iterator.GetImmediateOperand(0), 10); | 547 CHECK_EQ(iterator.GetImmediateOperand(0), 10); |
| 532 iterator.Advance(); | 548 iterator.Advance(); |
| 533 | 549 |
| 534 // Ignore add operation. | 550 // Ignore add operation. |
| 535 iterator.Advance(); | 551 iterator.Advance(); |
| 536 | 552 |
| 537 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 553 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 538 CHECK_EQ(iterator.GetImmediateOperand(0), 6); | 554 CHECK_EQ(iterator.GetImmediateOperand(0), 6); |
| 539 iterator.Advance(); | 555 iterator.Advance(); |
| 540 | 556 |
| 541 // Ignore add operation. | 557 // Ignore add operation. |
| 542 iterator.Advance(); | 558 iterator.Advance(); |
| 543 | 559 |
| 544 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); | 560 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse); |
| 545 CHECK_EQ(iterator.GetImmediateOperand(0), 2); | 561 CHECK_EQ(iterator.GetImmediateOperand(0), 2); |
| 546 iterator.Advance(); | 562 iterator.Advance(); |
| 547 | 563 |
| 548 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); | 564 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); |
| 549 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 565 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 550 Smi::FromInt(kFarJumpDistance)); | 566 Smi::FromInt(kFarJumpDistance)); |
| 551 iterator.Advance(); | 567 iterator.Advance(); |
| 552 | 568 |
| 553 // Ignore compare operation. | 569 // Ignore compare operation. |
| 554 iterator.Advance(); | 570 iterator.Advance(); |
| 555 | 571 |
| 556 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); | 572 CHECK_EQ(iterator.current_bytecode(), |
| 573 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrueConstant)); | |
| 557 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 574 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 558 Smi::FromInt(kFarJumpDistance - 4)); | 575 Smi::FromInt(kFarJumpDistance - 4)); |
| 559 iterator.Advance(); | 576 iterator.Advance(); |
| 560 | 577 |
| 561 // Ignore compare operation. | 578 // Ignore compare operation. |
| 562 iterator.Advance(); | 579 iterator.Advance(); |
| 563 | 580 |
| 564 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); | 581 CHECK_EQ(iterator.current_bytecode(), |
| 582 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalseConstant)); | |
| 565 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 583 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 566 Smi::FromInt(kFarJumpDistance - 8)); | 584 Smi::FromInt(kFarJumpDistance - 8)); |
| 567 iterator.Advance(); | 585 iterator.Advance(); |
| 568 | 586 |
| 569 // Ignore add operation. | 587 // Ignore add operation. |
| 570 iterator.Advance(); | 588 iterator.Advance(); |
| 571 | 589 |
| 572 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); | 590 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant); |
| 573 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), | 591 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), |
| 574 Smi::FromInt(kFarJumpDistance - 12)); | 592 Smi::FromInt(kFarJumpDistance - 12)); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 builder.Jump(&label0); | 639 builder.Jump(&label0); |
| 622 builder.Return(); | 640 builder.Return(); |
| 623 | 641 |
| 624 Handle<BytecodeArray> array = builder.ToBytecodeArray(); | 642 Handle<BytecodeArray> array = builder.ToBytecodeArray(); |
| 625 BytecodeArrayIterator iterator(array); | 643 BytecodeArrayIterator iterator(array); |
| 626 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 644 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 627 CHECK_EQ(iterator.GetImmediateOperand(0), 0); | 645 CHECK_EQ(iterator.GetImmediateOperand(0), 0); |
| 628 iterator.Advance(); | 646 iterator.Advance(); |
| 629 // Ignore compare operation. | 647 // Ignore compare operation. |
| 630 iterator.Advance(); | 648 iterator.Advance(); |
| 631 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); | 649 CHECK_EQ(iterator.current_bytecode(), |
| 650 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | |
| 632 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 651 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
| 633 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 652 CHECK_EQ(iterator.GetImmediateOperand(0), -2); |
| 634 iterator.Advance(); | 653 iterator.Advance(); |
| 635 // Ignore compare operation. | 654 // Ignore compare operation. |
| 636 iterator.Advance(); | 655 iterator.Advance(); |
| 637 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); | 656 CHECK_EQ(iterator.current_bytecode(), |
| 657 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | |
| 638 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 658 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
| 639 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 659 CHECK_EQ(iterator.GetImmediateOperand(0), -2); |
| 640 iterator.Advance(); | 660 iterator.Advance(); |
| 641 // Ignore binary operation. | 661 // Ignore binary operation. |
| 642 iterator.Advance(); | 662 iterator.Advance(); |
| 643 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 663 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 644 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); | 664 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kSingle); |
| 645 CHECK_EQ(iterator.GetImmediateOperand(0), -2); | 665 CHECK_EQ(iterator.GetImmediateOperand(0), -2); |
| 646 iterator.Advance(); | 666 iterator.Advance(); |
| 647 // Ignore binary operation. | 667 // Ignore binary operation. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 668 CHECK_EQ(iterator.GetImmediateOperand(0), -389); | 688 CHECK_EQ(iterator.GetImmediateOperand(0), -389); |
| 669 iterator.Advance(); | 689 iterator.Advance(); |
| 670 // Ignore binary operation. | 690 // Ignore binary operation. |
| 671 iterator.Advance(); | 691 iterator.Advance(); |
| 672 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); | 692 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue); |
| 673 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 693 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
| 674 CHECK_EQ(iterator.GetImmediateOperand(0), -399); | 694 CHECK_EQ(iterator.GetImmediateOperand(0), -399); |
| 675 iterator.Advance(); | 695 iterator.Advance(); |
| 676 // Ignore compare operation. | 696 // Ignore compare operation. |
| 677 iterator.Advance(); | 697 iterator.Advance(); |
| 678 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); | 698 CHECK_EQ(iterator.current_bytecode(), |
| 699 PeepholeToBoolean(Bytecode::kJumpIfToBooleanFalse)); | |
| 679 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 700 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
| 680 CHECK_EQ(iterator.GetImmediateOperand(0), -409); | 701 CHECK_EQ(iterator.GetImmediateOperand(0), -409); |
| 681 iterator.Advance(); | 702 iterator.Advance(); |
| 682 // Ignore compare operation. | 703 // Ignore compare operation. |
| 683 iterator.Advance(); | 704 iterator.Advance(); |
| 684 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); | 705 CHECK_EQ(iterator.current_bytecode(), |
| 706 PeepholeToBoolean(Bytecode::kJumpIfToBooleanTrue)); | |
| 685 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 707 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
| 686 CHECK_EQ(iterator.GetImmediateOperand(0), -419); | 708 CHECK_EQ(iterator.GetImmediateOperand(0), -419); |
| 687 iterator.Advance(); | 709 iterator.Advance(); |
| 688 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); | 710 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); |
| 689 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); | 711 CHECK_EQ(iterator.current_operand_scale(), OperandScale::kDouble); |
| 690 CHECK_EQ(iterator.GetImmediateOperand(0), -425); | 712 CHECK_EQ(iterator.GetImmediateOperand(0), -425); |
| 691 iterator.Advance(); | 713 iterator.Advance(); |
| 692 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 714 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 693 iterator.Advance(); | 715 iterator.Advance(); |
| 694 CHECK(iterator.done()); | 716 CHECK(iterator.done()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 iterator.Advance(); | 767 iterator.Advance(); |
| 746 } | 768 } |
| 747 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 769 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 748 iterator.Advance(); | 770 iterator.Advance(); |
| 749 CHECK(iterator.done()); | 771 CHECK(iterator.done()); |
| 750 } | 772 } |
| 751 | 773 |
| 752 } // namespace interpreter | 774 } // namespace interpreter |
| 753 } // namespace internal | 775 } // namespace internal |
| 754 } // namespace v8 | 776 } // namespace v8 |
| OLD | NEW |