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

Side by Side Diff: src/interpreter/bytecode-array-builder.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 | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-generator.cc » ('j') | 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
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 Handle<BytecodeArray> output = 103 Handle<BytecodeArray> output =
104 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size, 104 factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size,
105 parameter_count(), constant_pool); 105 parameter_count(), constant_pool);
106 bytecode_generated_ = true; 106 bytecode_generated_ = true;
107 return output; 107 return output;
108 } 108 }
109 109
110 110
111 template <size_t N> 111 template <size_t N>
112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { 112 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
113 // Don't output dead code.
114 if (exit_seen_in_block_) return;
115
113 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N)); 116 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N));
114 last_bytecode_start_ = bytecodes()->size(); 117 last_bytecode_start_ = bytecodes()->size();
115 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); 118 bytecodes()->push_back(Bytecodes::ToByte(bytecode));
116 for (int i = 0; i < static_cast<int>(N); i++) { 119 for (int i = 0; i < static_cast<int>(N); i++) {
117 DCHECK(OperandIsValid(bytecode, i, operands[i])); 120 DCHECK(OperandIsValid(bytecode, i, operands[i]));
118 switch (Bytecodes::GetOperandSize(bytecode, i)) { 121 switch (Bytecodes::GetOperandSize(bytecode, i)) {
119 case OperandSize::kNone: 122 case OperandSize::kNone:
120 UNREACHABLE(); 123 UNREACHABLE();
121 case OperandSize::kByte: 124 case OperandSize::kByte:
122 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); 125 bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
(...skipping 24 matching lines...) Expand all
147 } 150 }
148 151
149 152
150 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { 153 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) {
151 uint32_t operands[] = {operand0}; 154 uint32_t operands[] = {operand0};
152 Output(bytecode, operands); 155 Output(bytecode, operands);
153 } 156 }
154 157
155 158
156 void BytecodeArrayBuilder::Output(Bytecode bytecode) { 159 void BytecodeArrayBuilder::Output(Bytecode bytecode) {
160 // Don't output dead code.
161 if (exit_seen_in_block_) return;
162
157 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); 163 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
158 last_bytecode_start_ = bytecodes()->size(); 164 last_bytecode_start_ = bytecodes()->size();
159 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); 165 bytecodes()->push_back(Bytecodes::ToByte(bytecode));
160 } 166 }
161 167
162 168
163 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 169 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
164 Register reg, 170 Register reg,
165 Strength strength) { 171 Strength strength) {
166 if (is_strong(strength)) { 172 if (is_strong(strength)) {
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } 547 }
542 548
543 549
544 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) { 550 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
545 if (label->is_forward_target()) { 551 if (label->is_forward_target()) {
546 // An earlier jump instruction refers to this label. Update it's location. 552 // An earlier jump instruction refers to this label. Update it's location.
547 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset()); 553 PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset());
548 // Now treat as if the label will only be back referred to. 554 // Now treat as if the label will only be back referred to.
549 } 555 }
550 label->bind_to(bytecodes()->size()); 556 label->bind_to(bytecodes()->size());
557 LeaveBasicBlock();
551 return *this; 558 return *this;
552 } 559 }
553 560
554 561
555 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target, 562 BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
556 BytecodeLabel* label) { 563 BytecodeLabel* label) {
557 DCHECK_EQ(label->is_bound(), false); 564 DCHECK(!label->is_bound());
558 DCHECK_EQ(target.is_bound(), true); 565 DCHECK(target.is_bound());
559 PatchJump(bytecodes()->begin() + target.offset(), 566 PatchJump(bytecodes()->begin() + target.offset(),
560 bytecodes()->begin() + label->offset()); 567 bytecodes()->begin() + label->offset());
561 label->bind_to(target.offset()); 568 label->bind_to(target.offset());
569 LeaveBasicBlock();
562 return *this; 570 return *this;
563 } 571 }
564 572
565 573
566 // static 574 // static
567 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand( 575 Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand(
568 Bytecode jump_bytecode) { 576 Bytecode jump_bytecode) {
569 switch (jump_bytecode) { 577 switch (jump_bytecode) {
570 case Bytecode::kJump: 578 case Bytecode::kJump:
571 return Bytecode::kJumpConstant; 579 return Bytecode::kJumpConstant;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 return Bytecode::kJumpIfToBooleanFalse; 644 return Bytecode::kJumpIfToBooleanFalse;
637 default: 645 default:
638 UNREACHABLE(); 646 UNREACHABLE();
639 } 647 }
640 return static_cast<Bytecode>(-1); 648 return static_cast<Bytecode>(-1);
641 } 649 }
642 650
643 651
644 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, 652 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
645 BytecodeLabel* label) { 653 BytecodeLabel* label) {
654 // Don't emit dead code.
655 if (exit_seen_in_block_) return *this;
656
646 // Check if the value in accumulator is boolean, if not choose an 657 // Check if the value in accumulator is boolean, if not choose an
647 // appropriate JumpIfToBoolean bytecode. 658 // appropriate JumpIfToBoolean bytecode.
648 if (NeedToBooleanCast()) { 659 if (NeedToBooleanCast()) {
649 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); 660 jump_bytecode = GetJumpWithToBoolean(jump_bytecode);
650 } 661 }
651 662
652 int delta; 663 int delta;
653 if (label->is_bound()) { 664 if (label->is_bound()) {
654 // Label has been bound already so this is a backwards jump. 665 // Label has been bound already so this is a backwards jump.
655 CHECK_GE(bytecodes()->size(), label->offset()); 666 CHECK_GE(bytecodes()->size(), label->offset());
(...skipping 11 matching lines...) Expand all
667 Output(jump_bytecode, static_cast<uint8_t>(delta)); 678 Output(jump_bytecode, static_cast<uint8_t>(delta));
668 } else { 679 } else {
669 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate())); 680 size_t entry = GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate()));
670 if (FitsInIdx8Operand(entry)) { 681 if (FitsInIdx8Operand(entry)) {
671 Output(GetJumpWithConstantOperand(jump_bytecode), 682 Output(GetJumpWithConstantOperand(jump_bytecode),
672 static_cast<uint8_t>(entry)); 683 static_cast<uint8_t>(entry));
673 } else { 684 } else {
674 UNIMPLEMENTED(); 685 UNIMPLEMENTED();
675 } 686 }
676 } 687 }
688 LeaveBasicBlock();
677 return *this; 689 return *this;
678 } 690 }
679 691
680 692
681 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) { 693 BytecodeArrayBuilder& BytecodeArrayBuilder::Jump(BytecodeLabel* label) {
682 return OutputJump(Bytecode::kJump, label); 694 return OutputJump(Bytecode::kJump, label);
683 } 695 }
684 696
685 697
686 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) { 698 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfTrue(BytecodeLabel* label) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 return *this; 742 return *this;
731 } 743 }
732 744
733 745
734 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register for_in_state) { 746 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register for_in_state) {
735 Output(Bytecode::kForInDone, for_in_state.ToOperand()); 747 Output(Bytecode::kForInDone, for_in_state.ToOperand());
736 return *this; 748 return *this;
737 } 749 }
738 750
739 751
740 BytecodeArrayBuilder& BytecodeArrayBuilder::EnterBlock() { return *this; } 752 void BytecodeArrayBuilder::LeaveBasicBlock() {
741
742
743 BytecodeArrayBuilder& BytecodeArrayBuilder::LeaveBlock() {
744 last_block_end_ = bytecodes()->size(); 753 last_block_end_ = bytecodes()->size();
745 exit_seen_in_block_ = false; 754 exit_seen_in_block_ = false;
746 return *this;
747 } 755 }
748 756
749 757
750 void BytecodeArrayBuilder::EnsureReturn() { 758 void BytecodeArrayBuilder::EnsureReturn() {
751 if (!exit_seen_in_block_) { 759 if (!exit_seen_in_block_) {
752 LoadUndefined(); 760 LoadUndefined();
753 Return(); 761 Return();
754 } 762 }
755 } 763 }
756 764
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 DCHECK_GT(next_consecutive_count_, 0); 1247 DCHECK_GT(next_consecutive_count_, 0);
1240 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); 1248 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_);
1241 allocated_.push_back(next_consecutive_register_); 1249 allocated_.push_back(next_consecutive_register_);
1242 next_consecutive_count_--; 1250 next_consecutive_count_--;
1243 return Register(next_consecutive_register_++); 1251 return Register(next_consecutive_register_++);
1244 } 1252 }
1245 1253
1246 } // namespace interpreter 1254 } // namespace interpreter
1247 } // namespace internal 1255 } // namespace internal
1248 } // namespace v8 1256 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698