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

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: Changes PreviousBytecodeHelper to be instantiated only when the last bytecode is in the same basicb… 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 // This helper is expected to be instantiated only when the last bytecode is
16 // in the same basicblock.
rmcilroy 2015/12/08 13:43:02 /s/basicblock/basic block/ throughout, and also in
mythria 2015/12/08 14:53:29 Done.
17 CHECK(array_builder_.LastBytecodeInSameBlock());
rmcilroy 2015/12/08 13:43:02 DCHECK is fine here I think.
mythria 2015/12/08 14:53:29 Done.
18 }
15 19
16 Bytecode GetBytecode() const { 20 // Returns the previous bytecode in the same basicblock. Expects that the
17 // Returns the previous bytecode in the same basicblock. If there is none it 21 // lastbytecode is in the same basicblock.
rmcilroy 2015/12/08 13:43:02 /s/lastbytecode/last bytecode/. Actually, there is
mythria 2015/12/08 14:53:29 Done.
18 // returns Bytecode::kLast. 22 MUST_USE_RESULT Bytecode GetBytecode() const {
19 if (!array_builder_.LastBytecodeInSameBlock()) { 23 DCHECK(array_builder_.LastBytecodeInSameBlock());
rmcilroy 2015/12/08 13:43:02 Rather than DCHECKING this (which is already CHECK
mythria 2015/12/08 14:53:29 Done.
20 return Bytecode::kLast;
21 }
22 return Bytecodes::FromByte( 24 return Bytecodes::FromByte(
23 array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_)); 25 array_builder_.bytecodes()->at(array_builder_.last_bytecode_start_));
24 } 26 }
25 27
26 uint32_t GetOperand(int operand_index) const { 28 // Returns the operand at operand_index for the previous bytecode. Expects
29 // that the previous bytecode is in the same basicblock.
rmcilroy 2015/12/08 13:43:02 ditto for the last sentence.
mythria 2015/12/08 14:53:29 Done.
30 MUST_USE_RESULT uint32_t GetOperand(int operand_index) const {
27 Bytecode bytecode = GetBytecode(); 31 Bytecode bytecode = GetBytecode();
28 DCHECK_GE(operand_index, 0); 32 DCHECK_GE(operand_index, 0);
29 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode)); 33 DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
30 size_t operand_offset = 34 size_t operand_offset =
31 array_builder_.last_bytecode_start_ + 35 array_builder_.last_bytecode_start_ +
32 Bytecodes::GetOperandOffset(bytecode, operand_index); 36 Bytecodes::GetOperandOffset(bytecode, operand_index);
33 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index); 37 OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
34 switch (size) { 38 switch (size) {
35 default: 39 default:
36 case OperandSize::kNone: 40 case OperandSize::kNone:
37 UNREACHABLE(); 41 UNREACHABLE();
38 case OperandSize::kByte: 42 case OperandSize::kByte:
39 return static_cast<uint32_t>( 43 return static_cast<uint32_t>(
40 array_builder_.bytecodes()->at(operand_offset)); 44 array_builder_.bytecodes()->at(operand_offset));
41 case OperandSize::kShort: 45 case OperandSize::kShort:
42 uint16_t operand = 46 uint16_t operand =
43 (array_builder_.bytecodes()->at(operand_offset) << 8) + 47 (array_builder_.bytecodes()->at(operand_offset) << 8) +
44 array_builder_.bytecodes()->at(operand_offset + 1); 48 array_builder_.bytecodes()->at(operand_offset + 1);
45 return static_cast<uint32_t>(operand); 49 return static_cast<uint32_t>(operand);
46 } 50 }
47 } 51 }
48 52
49 Handle<Object> GetConstantForIndexOperand(int operand_index) const { 53 Handle<Object> GetConstantForIndexOperand(int operand_index) const {
50 return array_builder_.constants_.at(GetOperand(operand_index)); 54 return array_builder_.constants_.at(GetOperand(operand_index));
51 } 55 }
52 56
53 private: 57 private:
54 const BytecodeArrayBuilder& array_builder_; 58 const BytecodeArrayBuilder& array_builder_;
59 DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
rmcilroy 2015/12/08 13:43:02 nit - newline above
mythria 2015/12/08 14:53:29 Done.
55 }; 60 };
56 61
57 62
58 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone) 63 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
59 : isolate_(isolate), 64 : isolate_(isolate),
60 zone_(zone), 65 zone_(zone),
61 bytecodes_(zone), 66 bytecodes_(zone),
62 bytecode_generated_(false), 67 bytecode_generated_(false),
63 last_block_end_(0), 68 last_block_end_(0),
64 last_bytecode_start_(~0), 69 last_bytecode_start_(~0),
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } 578 }
574 579
575 580
576 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) { 581 BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
577 Output(Bytecode::kPopContext, context.ToOperand()); 582 Output(Bytecode::kPopContext, context.ToOperand());
578 return *this; 583 return *this;
579 } 584 }
580 585
581 586
582 bool BytecodeArrayBuilder::NeedToBooleanCast() { 587 bool BytecodeArrayBuilder::NeedToBooleanCast() {
588 if (!LastBytecodeInSameBlock()) {
589 return true;
590 }
583 PreviousBytecodeHelper previous_bytecode(*this); 591 PreviousBytecodeHelper previous_bytecode(*this);
584 switch (previous_bytecode.GetBytecode()) { 592 switch (previous_bytecode.GetBytecode()) {
585 case Bytecode::kToBoolean: 593 case Bytecode::kToBoolean:
586 UNREACHABLE(); 594 UNREACHABLE();
587 // If the previous bytecode puts a boolean in the accumulator return true. 595 // If the previous bytecode puts a boolean in the accumulator return true.
588 case Bytecode::kLdaTrue: 596 case Bytecode::kLdaTrue:
589 case Bytecode::kLdaFalse: 597 case Bytecode::kLdaFalse:
590 case Bytecode::kLogicalNot: 598 case Bytecode::kLogicalNot:
591 case Bytecode::kTestEqual: 599 case Bytecode::kTestEqual:
592 case Bytecode::kTestNotEqual: 600 case Bytecode::kTestNotEqual:
593 case Bytecode::kTestEqualStrict: 601 case Bytecode::kTestEqualStrict:
594 case Bytecode::kTestNotEqualStrict: 602 case Bytecode::kTestNotEqualStrict:
595 case Bytecode::kTestLessThan: 603 case Bytecode::kTestLessThan:
596 case Bytecode::kTestLessThanOrEqual: 604 case Bytecode::kTestLessThanOrEqual:
597 case Bytecode::kTestGreaterThan: 605 case Bytecode::kTestGreaterThan:
598 case Bytecode::kTestGreaterThanOrEqual: 606 case Bytecode::kTestGreaterThanOrEqual:
599 case Bytecode::kTestInstanceOf: 607 case Bytecode::kTestInstanceOf:
600 case Bytecode::kTestIn: 608 case Bytecode::kTestIn:
601 case Bytecode::kForInDone: 609 case Bytecode::kForInDone:
602 return false; 610 return false;
603 // Also handles the case where the previous bytecode was in a different
604 // block.
605 default: 611 default:
606 return true; 612 return true;
607 } 613 }
608 } 614 }
609 615
610 616
611 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() { 617 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToBoolean() {
612 PreviousBytecodeHelper previous_bytecode(*this); 618 if (!LastBytecodeInSameBlock()) {
619 Output(Bytecode::kToBoolean);
620 return *this;
621 }
613 // If the previous bytecode puts a boolean in the accumulator 622 // If the previous bytecode puts a boolean in the accumulator
614 // there is no need to emit an instruction. 623 // there is no need to emit an instruction.
615 if (NeedToBooleanCast()) { 624 if (NeedToBooleanCast()) {
625 PreviousBytecodeHelper previous_bytecode(*this);
616 switch (previous_bytecode.GetBytecode()) { 626 switch (previous_bytecode.GetBytecode()) {
617 // If the previous bytecode is a constant evaluate it and return false. 627 // If the previous bytecode is a constant evaluate it and return false.
618 case Bytecode::kLdaZero: { 628 case Bytecode::kLdaZero: {
619 LoadFalse(); 629 LoadFalse();
620 break; 630 break;
621 } 631 }
622 case Bytecode::kLdaSmi8: { 632 case Bytecode::kLdaSmi8: {
623 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0); 633 LoadBooleanConstant(previous_bytecode.GetOperand(0) != 0);
624 break; 634 break;
625 } 635 }
(...skipping 10 matching lines...) Expand all
636 } 646 }
637 647
638 648
639 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() { 649 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
640 Output(Bytecode::kToObject); 650 Output(Bytecode::kToObject);
641 return *this; 651 return *this;
642 } 652 }
643 653
644 654
645 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() { 655 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
656 if (!LastBytecodeInSameBlock()) {
rmcilroy 2015/12/08 13:43:02 If you reverse this (do the check for if (LastByte
mythria 2015/12/08 14:53:29 Done.
657 Output(Bytecode::kToName);
658 return *this;
659 }
646 PreviousBytecodeHelper previous_bytecode(*this); 660 PreviousBytecodeHelper previous_bytecode(*this);
647 switch (previous_bytecode.GetBytecode()) { 661 switch (previous_bytecode.GetBytecode()) {
662 case Bytecode::kToName:
663 case Bytecode::kTypeOf:
664 return *this;
648 case Bytecode::kLdaConstantWide: 665 case Bytecode::kLdaConstantWide:
649 case Bytecode::kLdaConstant: { 666 case Bytecode::kLdaConstant: {
650 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0); 667 Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
651 if (object->IsName()) return *this; 668 if (object->IsName()) return *this;
652 break; 669 break;
653 } 670 }
654 case Bytecode::kToName:
655 case Bytecode::kTypeOf:
656 return *this;
657 default: 671 default:
658 break; 672 break;
659 } 673 }
660 Output(Bytecode::kToName); 674 Output(Bytecode::kToName);
661 return *this; 675 return *this;
662 } 676 }
663 677
664 678
665 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() { 679 BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
666 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns 680 // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1096 }
1083 1097
1084 1098
1085 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { 1099 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
1086 return last_bytecode_start_ < bytecodes()->size() && 1100 return last_bytecode_start_ < bytecodes()->size() &&
1087 last_bytecode_start_ >= last_block_end_; 1101 last_bytecode_start_ >= last_block_end_;
1088 } 1102 }
1089 1103
1090 1104
1091 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { 1105 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
1106 if (!LastBytecodeInSameBlock()) {
rmcilroy 2015/12/08 13:43:02 ditto (avoids double return false)
mythria 2015/12/08 14:53:28 Done.
1107 return false;
1108 }
1092 PreviousBytecodeHelper previous_bytecode(*this); 1109 PreviousBytecodeHelper previous_bytecode(*this);
1093 if (previous_bytecode.GetBytecode() == Bytecode::kLdar || 1110 Bytecode bytecode = previous_bytecode.GetBytecode();
1094 previous_bytecode.GetBytecode() == Bytecode::kStar) { 1111 if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) &&
1095 if (reg == Register::FromOperand(previous_bytecode.GetOperand(0))) { 1112 (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) {
1096 return true; 1113 return true;
1097 }
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) {
1106 case Token::Value::ADD: 1122 case Token::Value::ADD:
1107 return Bytecode::kAdd; 1123 return Bytecode::kAdd;
(...skipping 316 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