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

Side by Side Diff: src/interpreter/bytecode-array-builder.cc

Issue 1510553002: [Interpreter] Fixes PreviousBytecodeHelper to check if previous bytecode is in the same basic block. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments. Created 5 years 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 | « no previous file | 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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/bytecode-array-builder.h" 5 #include "src/interpreter/bytecode-array-builder.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace interpreter { 9 namespace interpreter {
10 10
11 class BytecodeArrayBuilder::PreviousBytecodeHelper { 11 class BytecodeArrayBuilder::PreviousBytecodeHelper {
12 public: 12 public:
13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder) 13 explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
14 : array_builder_(array_builder) {} 14 : array_builder_(array_builder),
15 15 previous_bytecode_start_(array_builder_.last_bytecode_start_) {
16 Bytecode GetBytecode() const { 16 // This helper is expected to be instantiated only when the last bytecode is
17 // Returns the previous bytecode in the same basicblock. If there is none it 17 // in the same basic block.
18 // returns Bytecode::kLast. 18 DCHECK(array_builder_.LastBytecodeInSameBlock());
19 if (!array_builder_.LastBytecodeInSameBlock()) {
20 return Bytecode::kLast;
21 }
22 return Bytecodes::FromByte(
23 array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_));
24 } 19 }
25 20
26 uint32_t GetOperand(int operand_index) const { 21 // Returns the previous bytecode in the same basic block.
22 MUST_USE_RESULT Bytecode GetBytecode() const {
23 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
24 return Bytecodes::FromByte(
25 array_builder_.bytecodes()->at(previous_bytecode_start_));
26 }
27
28 // Returns the operand at operand_index for the previous bytecode in the
29 // same basic block.
30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const {
31 DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
27 Bytecode bytecode = GetBytecode(); 32 Bytecode bytecode = GetBytecode();
28 DCHECK_GE(operand_index, 0); 33 DCHECK_GE(operand_index, 0);
29 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); 34 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
30 size_t operand_offset = 35 size_t operand_offset =
31 array_builder_.last_bytecode_start_ + 36 previous_bytecode_start_ +
32 Bytecodes::GetOperandOffset(bytecode, operand_index); 37 Bytecodes::GetOperandOffset(bytecode, operand_index);
33 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); 38 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
34 switch (size) { 39 switch (size) {
35 default: 40 default:
36 case OperandSize::kNone: 41 case OperandSize::kNone:
37 UNREACHABLE(); 42 UNREACHABLE();
38 case OperandSize::kByte: 43 case OperandSize::kByte:
39 return static_cast<uint32_t>( 44 return static_cast<uint32_t>(
40 array_builder_.bytecodes()->at(operand_offset)); 45 array_builder_.bytecodes()->at(operand_offset));
41 case OperandSize::kShort: 46 case OperandSize::kShort:
42 uint16_t operand = 47 uint16_t operand =
43 (array_builder_.bytecodes()->at(operand_offset) << 8) + 48 (array_builder_.bytecodes()->at(operand_offset) << 8) +
44 array_builder_.bytecodes()->at(operand_offset + 1); 49 array_builder_.bytecodes()->at(operand_offset + 1);
45 return static_cast<uint32_t>(operand); 50 return static_cast<uint32_t>(operand);
46 } 51 }
47 } 52 }
48 53
49 Handle<Object> GetConstantForIndexOperand(int operand_index) const { 54 Handle<Object> GetConstantForIndexOperand(int operand_index) const {
50 return array_builder_.constants_.at(GetOperand(operand_index)); 55 return array_builder_.constants_.at(GetOperand(operand_index));
51 } 56 }
52 57
53 private: 58 private:
54 const BytecodeArrayBuilder& array_builder_; 59 const BytecodeArrayBuilder& array_builder_;
60 size_t previous_bytecode_start_;
61
62 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
55 }; 63 };
56 64
57 65
58 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) 66 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
59 : isolate_(isolate), 67 : isolate_(isolate),
60 zone_(zone), 68 zone_(zone),
61 bytecodes_(zone), 69 bytecodes_(zone),
62 bytecode_generated_(false), 70 bytecode_generated_(false),
63 last_block_end_(0), 71 last_block_end_(0),
64 last_bytecode_start_(~0), 72 last_bytecode_start_(~0),
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } 581 }
574 582
575 583
576 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 584 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
577 Output(Bytecode::kPopContext, context.ToOperand()); 585 Output(Bytecode::kPopContext, context.ToOperand());
578 return *this; 586 return *this;
579 } 587 }
580 588
581 589
582 bool BytecodeArrayBuilder::NeedToBooleanCast() { 590 bool BytecodeArrayBuilder::NeedToBooleanCast() {
591 if (!LastBytecodeInSameBlock()) {
592 return true;
593 }
583 PreviousBytecodeHelper previous_bytecode(*this); 594 PreviousBytecodeHelper previous_bytecode(*this);
584 switch (previous_bytecode.GetBytecode()) { 595 switch (previous_bytecode.GetBytecode()) {
585 case Bytecode::kToBoolean: 596 case Bytecode::kToBoolean:
586 UNREACHABLE(); 597 UNREACHABLE();
587 // If the previous bytecode puts a boolean in the accumulator return true. 598 // If the previous bytecode puts a boolean in the accumulator return true.
588 case Bytecode::kLdaTrue: 599 case Bytecode::kLdaTrue:
589 case Bytecode::kLdaFalse: 600 case Bytecode::kLdaFalse:
590 case Bytecode::kLogicalNot: 601 case Bytecode::kLogicalNot:
591 case Bytecode::kTestEqual: 602 case Bytecode::kTestEqual:
592 case Bytecode::kTestNotEqual: 603 case Bytecode::kTestNotEqual:
593 case Bytecode::kTestEqualStrict: 604 case Bytecode::kTestEqualStrict:
594 case Bytecode::kTestNotEqualStrict: 605 case Bytecode::kTestNotEqualStrict:
595 case Bytecode::kTestLessThan: 606 case Bytecode::kTestLessThan:
596 case Bytecode::kTestLessThanOrEqual: 607 case Bytecode::kTestLessThanOrEqual:
597 case Bytecode::kTestGreaterThan: 608 case Bytecode::kTestGreaterThan:
598 case Bytecode::kTestGreaterThanOrEqual: 609 case Bytecode::kTestGreaterThanOrEqual:
599 case Bytecode::kTestInstanceOf: 610 case Bytecode::kTestInstanceOf:
600 case Bytecode::kTestIn: 611 case Bytecode::kTestIn:
601 case Bytecode::kForInDone: 612 case Bytecode::kForInDone:
602 return false; 613 return false;
603 // Also handles the case where the previous bytecode was in a different
604 // block.
605 default: 614 default:
606 return true; 615 return true;
607 } 616 }
608 } 617 }
609 618
610 619
611 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { 620 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
612 PreviousBytecodeHelper previous_bytecode(*this); 621 if (!LastBytecodeInSameBlock()) {
622 Output(Bytecode::kToBoolean);
623 return *this;
624 }
613 // If the previous bytecode puts a boolean in the accumulator 625 // If the previous bytecode puts a boolean in the accumulator
614 // there is no need to emit an instruction. 626 // there is no need to emit an instruction.
615 if (NeedToBooleanCast()) { 627 if (NeedToBooleanCast()) {
628 PreviousBytecodeHelper previous_bytecode(*this);
616 switch (previous_bytecode.GetBytecode()) { 629 switch (previous_bytecode.GetBytecode()) {
617 // If the previous bytecode is a constant evaluate it and return false. 630 // If the previous bytecode is a constant evaluate it and return false.
618 case Bytecode::kLdaZero: { 631 case Bytecode::kLdaZero: {
619 LoadFalse(); 632 LoadFalse();
620 break; 633 break;
621 } 634 }
622 case Bytecode::kLdaSmi8: { 635 case Bytecode::kLdaSmi8: {
623 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0); 636 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0);
624 break; 637 break;
625 } 638 }
(...skipping 10 matching lines...) Expand all
636 } 649 }
637 650
638 651
639 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 652 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
640 Output(Bytecode::kToObject); 653 Output(Bytecode::kToObject);
641 return *this; 654 return *this;
642 } 655 }
643 656
644 657
645 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 658 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
646 PreviousBytecodeHelper previous_bytecode(*this); 659 if (LastBytecodeInSameBlock()) {
647 switch (previous_bytecode.GetBytecode()) { 660 PreviousBytecodeHelper previous_bytecode(*this);
648 case Bytecode::kLdaConstantWide: 661 switch (previous_bytecode.GetBytecode()) {
649 case Bytecode::kLdaConstant: { 662 case Bytecode::kToName:
650 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); 663 case Bytecode::kTypeOf:
651 if (object->IsName()) return *this; 664 return *this;
652 break; 665 case Bytecode::kLdaConstantWide:
666 case Bytecode::kLdaConstant: {
667 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
668 if (object->IsName()) return *this;
669 break;
670 }
671 default:
672 break;
653 } 673 }
654 case Bytecode::kToName:
655 case Bytecode::kTypeOf:
656 return *this;
657 default:
658 break;
659 } 674 }
660 Output(Bytecode::kToName); 675 Output(Bytecode::kToName);
661 return *this; 676 return *this;
662 } 677 }
663 678
664 679
665 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 680 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
666 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns 681 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
667 // a number. 682 // a number.
668 Output(Bytecode::kToNumber); 683 Output(Bytecode::kToNumber);
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1097 }
1083 1098
1084 1099
1085 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1100 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
1086 return last_bytecode_start_ < bytecodes()->size() && 1101 return last_bytecode_start_ < bytecodes()->size() &&
1087 last_bytecode_start_ >= last_block_end_; 1102 last_bytecode_start_ >= last_block_end_;
1088 } 1103 }
1089 1104
1090 1105
1091 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1106 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
1092 PreviousBytecodeHelper previous_bytecode(*this); 1107 if (LastBytecodeInSameBlock()) {
1093 if (previous_bytecode.GetBytecode() == Bytecode::kLdar || 1108 PreviousBytecodeHelper previous_bytecode(*this);
1094 previous_bytecode.GetBytecode() == Bytecode::kStar) { 1109 Bytecode bytecode = previous_bytecode.GetBytecode();
1095 if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) { 1110 if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) &&
1111 (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) {
1096 return true; 1112 return true;
1097 } 1113 }
1098 } 1114 }
1099 return false; 1115 return false;
1100 } 1116 }
1101 1117
1102 1118
1103 // static 1119 // static
1104 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { 1120 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
1105 switch (op) { 1121 switch (op) {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 DCHECK_GT(next_consecutive_count_, 0); 1440 DCHECK_GT(next_consecutive_count_, 0);
1425 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); 1441 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_);
1426 allocated_.push_back(next_consecutive_register_); 1442 allocated_.push_back(next_consecutive_register_);
1427 next_consecutive_count_--; 1443 next_consecutive_count_--;
1428 return Register(next_consecutive_register_++); 1444 return Register(next_consecutive_register_++);
1429 } 1445 }
1430 1446
1431 } // namespace interpreter 1447 } // namespace interpreter
1432 } // namespace internal 1448 } // namespace internal
1433 } // namespace v8 1449 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698