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

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

Issue 2030583002: [Interpreter] Don't try to eliminate dead-code in bytecode-array-builder (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Test Created 4 years, 6 months 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-peephole-optimizer.h » ('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 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-writer.h" 8 #include "src/interpreter/bytecode-array-writer.h"
9 #include "src/interpreter/bytecode-peephole-optimizer.h" 9 #include "src/interpreter/bytecode-peephole-optimizer.h"
10 #include "src/interpreter/bytecode-register-optimizer.h" 10 #include "src/interpreter/bytecode-register-optimizer.h"
11 #include "src/interpreter/interpreter-intrinsics.h" 11 #include "src/interpreter/interpreter-intrinsics.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 namespace interpreter { 15 namespace interpreter {
16 16
17 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone, 17 BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
18 int parameter_count, 18 int parameter_count,
19 int context_count, int locals_count, 19 int context_count, int locals_count,
20 FunctionLiteral* literal) 20 FunctionLiteral* literal)
21 : isolate_(isolate), 21 : isolate_(isolate),
22 zone_(zone), 22 zone_(zone),
23 bytecode_generated_(false), 23 bytecode_generated_(false),
24 constant_array_builder_(isolate, zone), 24 constant_array_builder_(isolate, zone),
25 handler_table_builder_(isolate, zone), 25 handler_table_builder_(isolate, zone),
26 source_position_table_builder_(isolate, zone), 26 source_position_table_builder_(isolate, zone),
27 exit_seen_in_block_(false), 27 return_seen_in_block_(false),
28 unbound_jumps_(0), 28 unbound_jumps_(0),
29 parameter_count_(parameter_count), 29 parameter_count_(parameter_count),
30 local_register_count_(locals_count), 30 local_register_count_(locals_count),
31 context_register_count_(context_count), 31 context_register_count_(context_count),
32 temporary_allocator_(zone, fixed_register_count()), 32 temporary_allocator_(zone, fixed_register_count()),
33 bytecode_array_writer_(zone, &source_position_table_builder_), 33 bytecode_array_writer_(zone, &source_position_table_builder_),
34 pipeline_(&bytecode_array_writer_) { 34 pipeline_(&bytecode_array_writer_) {
35 DCHECK_GE(parameter_count_, 0); 35 DCHECK_GE(parameter_count_, 0);
36 DCHECK_GE(context_register_count_, 0); 36 DCHECK_GE(context_register_count_, 0);
37 DCHECK_GE(local_register_count_, 0); 37 DCHECK_GE(local_register_count_, 0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 73
74 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const { 74 bool BytecodeArrayBuilder::RegisterIsParameterOrLocal(Register reg) const {
75 return reg.is_parameter() || reg.index() < locals_count(); 75 return reg.is_parameter() || reg.index() < locals_count();
76 } 76 }
77 77
78 78
79 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { 79 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
80 DCHECK_EQ(0, unbound_jumps_); 80 DCHECK_EQ(0, unbound_jumps_);
81 DCHECK_EQ(bytecode_generated_, false); 81 DCHECK_EQ(bytecode_generated_, false);
82 DCHECK(exit_seen_in_block_); 82 DCHECK(return_seen_in_block_);
83 83
84 pipeline()->FlushBasicBlock(); 84 pipeline()->FlushBasicBlock();
85 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes(); 85 const ZoneVector<uint8_t>* bytecodes = bytecode_array_writer()->bytecodes();
86 86
87 int bytecode_size = static_cast<int>(bytecodes->size()); 87 int bytecode_size = static_cast<int>(bytecodes->size());
88 88
89 // All locals need a frame slot for the debugger, but may not be 89 // All locals need a frame slot for the debugger, but may not be
90 // present in generated code. 90 // present in generated code.
91 int frame_size_for_locals = fixed_register_count() * kPointerSize; 91 int frame_size_for_locals = fixed_register_count() * kPointerSize;
92 int frame_size_used = bytecode_array_writer()->GetMaximumFrameSizeUsed(); 92 int frame_size_used = bytecode_array_writer()->GetMaximumFrameSizeUsed();
(...skipping 17 matching lines...) Expand all
110 } 110 }
111 111
112 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) { 112 void BytecodeArrayBuilder::AttachSourceInfo(BytecodeNode* node) {
113 if (latest_source_info_.is_valid()) { 113 if (latest_source_info_.is_valid()) {
114 node->source_info().Update(latest_source_info_); 114 node->source_info().Update(latest_source_info_);
115 latest_source_info_.set_invalid(); 115 latest_source_info_.set_invalid();
116 } 116 }
117 } 117 }
118 118
119 void BytecodeArrayBuilder::Output(Bytecode bytecode) { 119 void BytecodeArrayBuilder::Output(Bytecode bytecode) {
120 // Don't output dead code.
121 if (exit_seen_in_block_) return;
122
123 BytecodeNode node(bytecode); 120 BytecodeNode node(bytecode);
124 AttachSourceInfo(&node); 121 AttachSourceInfo(&node);
125 pipeline()->Write(&node); 122 pipeline()->Write(&node);
126 } 123 }
127 124
128 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, 125 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
129 OperandScale operand_scale, 126 OperandScale operand_scale,
130 uint32_t operand0, uint32_t operand1, 127 uint32_t operand0, uint32_t operand1,
131 uint32_t operand2, uint32_t operand3) { 128 uint32_t operand2, uint32_t operand3) {
132 // Don't output dead code.
133 if (exit_seen_in_block_) return;
134 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); 129 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
135 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); 130 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
136 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); 131 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
137 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3)); 132 DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3));
138 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3, 133 BytecodeNode node(bytecode, operand0, operand1, operand2, operand3,
139 operand_scale); 134 operand_scale);
140 AttachSourceInfo(&node); 135 AttachSourceInfo(&node);
141 pipeline()->Write(&node); 136 pipeline()->Write(&node);
142 } 137 }
143 138
144 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, 139 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
145 OperandScale operand_scale, 140 OperandScale operand_scale,
146 uint32_t operand0, uint32_t operand1, 141 uint32_t operand0, uint32_t operand1,
147 uint32_t operand2) { 142 uint32_t operand2) {
148 // Don't output dead code.
149 if (exit_seen_in_block_) return;
150 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); 143 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
151 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); 144 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
152 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2)); 145 DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
153 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale); 146 BytecodeNode node(bytecode, operand0, operand1, operand2, operand_scale);
154 AttachSourceInfo(&node); 147 AttachSourceInfo(&node);
155 pipeline()->Write(&node); 148 pipeline()->Write(&node);
156 } 149 }
157 150
158 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, 151 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
159 OperandScale operand_scale, 152 OperandScale operand_scale,
160 uint32_t operand0, uint32_t operand1) { 153 uint32_t operand0, uint32_t operand1) {
161 // Don't output dead code.
162 if (exit_seen_in_block_) return;
163 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); 154 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
164 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1)); 155 DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
165 BytecodeNode node(bytecode, operand0, operand1, operand_scale); 156 BytecodeNode node(bytecode, operand0, operand1, operand_scale);
166 AttachSourceInfo(&node); 157 AttachSourceInfo(&node);
167 pipeline()->Write(&node); 158 pipeline()->Write(&node);
168 } 159 }
169 160
170 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, 161 void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
171 OperandScale operand_scale, 162 OperandScale operand_scale,
172 uint32_t operand0) { 163 uint32_t operand0) {
173 // Don't output dead code.
174 if (exit_seen_in_block_) return;
175 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0)); 164 DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
176 BytecodeNode node(bytecode, operand0, operand_scale); 165 BytecodeNode node(bytecode, operand0, operand_scale);
177 AttachSourceInfo(&node); 166 AttachSourceInfo(&node);
178 pipeline()->Write(&node); 167 pipeline()->Write(&node);
179 } 168 }
180 169
181 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, 170 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
182 Register reg) { 171 Register reg) {
183 OperandScale operand_scale = 172 OperandScale operand_scale =
184 Bytecodes::OperandSizesToScale(reg.SizeOfOperand()); 173 Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 break; 648 break;
660 default: 649 default:
661 UNREACHABLE(); 650 UNREACHABLE();
662 } 651 }
663 unbound_jumps_--; 652 unbound_jumps_--;
664 } 653 }
665 654
666 655
667 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, 656 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
668 BytecodeLabel* label) { 657 BytecodeLabel* label) {
669 // Don't emit dead code.
670 if (exit_seen_in_block_) return *this;
671
672 if (label->is_bound()) { 658 if (label->is_bound()) {
673 // Label has been bound already so this is a backwards jump. 659 // Label has been bound already so this is a backwards jump.
674 size_t current_offset = pipeline()->FlushForOffset(); 660 size_t current_offset = pipeline()->FlushForOffset();
675 CHECK_GE(current_offset, label->offset()); 661 CHECK_GE(current_offset, label->offset());
676 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt)); 662 CHECK_LE(current_offset, static_cast<size_t>(kMaxInt));
677 size_t abs_delta = current_offset - label->offset(); 663 size_t abs_delta = current_offset - label->offset();
678 int delta = -static_cast<int>(abs_delta); 664 int delta = -static_cast<int>(abs_delta);
679 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta); 665 OperandSize operand_size = Bytecodes::SizeForSignedOperand(delta);
680 if (operand_size > OperandSize::kByte) { 666 if (operand_size > OperandSize::kByte) {
681 // Adjust for scaling byte prefix for wide jump offset. 667 // Adjust for scaling byte prefix for wide jump offset.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 return *this; 733 return *this;
748 } 734 }
749 735
750 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole( 736 BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
751 BytecodeLabel* label) { 737 BytecodeLabel* label) {
752 return OutputJump(Bytecode::kJumpIfNotHole, label); 738 return OutputJump(Bytecode::kJumpIfNotHole, label);
753 } 739 }
754 740
755 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() { 741 BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
756 Output(Bytecode::kThrow); 742 Output(Bytecode::kThrow);
757 exit_seen_in_block_ = true;
758 return *this; 743 return *this;
759 } 744 }
760 745
761 746
762 BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() { 747 BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
763 Output(Bytecode::kReThrow); 748 Output(Bytecode::kReThrow);
764 exit_seen_in_block_ = true;
765 return *this; 749 return *this;
766 } 750 }
767 751
768 752
769 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { 753 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
770 Output(Bytecode::kReturn); 754 Output(Bytecode::kReturn);
771 exit_seen_in_block_ = true; 755 return_seen_in_block_ = true;
772 return *this; 756 return *this;
773 } 757 }
774 758
775 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() { 759 BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
776 Output(Bytecode::kDebugger); 760 Output(Bytecode::kDebugger);
777 return *this; 761 return *this;
778 } 762 }
779 763
780 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare( 764 BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
781 Register cache_info_triple) { 765 Register cache_info_triple) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 840
857 841
858 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) { 842 BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
859 size_t offset = pipeline()->FlushForOffset(); 843 size_t offset = pipeline()->FlushForOffset();
860 handler_table_builder()->SetTryRegionEnd(handler_id, offset); 844 handler_table_builder()->SetTryRegionEnd(handler_id, offset);
861 return *this; 845 return *this;
862 } 846 }
863 847
864 848
865 void BytecodeArrayBuilder::LeaveBasicBlock() { 849 void BytecodeArrayBuilder::LeaveBasicBlock() {
866 exit_seen_in_block_ = false;
867 pipeline()->FlushBasicBlock(); 850 pipeline()->FlushBasicBlock();
851 return_seen_in_block_ = false;
868 } 852 }
869 853
870 void BytecodeArrayBuilder::EnsureReturn() { 854 void BytecodeArrayBuilder::EnsureReturn() {
871 if (!exit_seen_in_block_) { 855 if (!return_seen_in_block_) {
872 LoadUndefined(); 856 LoadUndefined();
873 SetReturnPosition(); 857 SetReturnPosition();
874 Return(); 858 Return();
875 } 859 }
876 DCHECK(exit_seen_in_block_); 860 DCHECK(return_seen_in_block_);
877 } 861 }
878 862
879 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, 863 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
880 Register receiver_args, 864 Register receiver_args,
881 size_t receiver_args_count, 865 size_t receiver_args_count,
882 int feedback_slot, 866 int feedback_slot,
883 TailCallMode tail_call_mode) { 867 TailCallMode tail_call_mode) {
884 Bytecode bytecode = BytecodeForCall(tail_call_mode); 868 Bytecode bytecode = BytecodeForCall(tail_call_mode);
885 OperandScale operand_scale = Bytecodes::OperandSizesToScale( 869 OperandScale operand_scale = Bytecodes::OperandSizesToScale(
886 callable.SizeOfOperand(), receiver_args.SizeOfOperand(), 870 callable.SizeOfOperand(), receiver_args.SizeOfOperand(),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 RegisterOperand(object)); 951 RegisterOperand(object));
968 return *this; 952 return *this;
969 } 953 }
970 954
971 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { 955 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
972 return constant_array_builder()->Insert(object); 956 return constant_array_builder()->Insert(object);
973 } 957 }
974 958
975 void BytecodeArrayBuilder::SetReturnPosition() { 959 void BytecodeArrayBuilder::SetReturnPosition() {
976 if (return_position_ == RelocInfo::kNoPosition) return; 960 if (return_position_ == RelocInfo::kNoPosition) return;
977 if (exit_seen_in_block_) return;
978 latest_source_info_.Update({return_position_, true}); 961 latest_source_info_.Update({return_position_, true});
979 } 962 }
980 963
981 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { 964 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
982 if (stmt->position() == RelocInfo::kNoPosition) return; 965 if (stmt->position() == RelocInfo::kNoPosition) return;
983 if (exit_seen_in_block_) return;
984 latest_source_info_.Update({stmt->position(), true}); 966 latest_source_info_.Update({stmt->position(), true});
985 } 967 }
986 968
987 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { 969 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
988 if (expr->position() == RelocInfo::kNoPosition) return; 970 if (expr->position() == RelocInfo::kNoPosition) return;
989 if (exit_seen_in_block_) return;
990 latest_source_info_.Update({expr->position(), false}); 971 latest_source_info_.Update({expr->position(), false});
991 } 972 }
992 973
993 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) { 974 void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) {
994 if (expr->position() == RelocInfo::kNoPosition) return; 975 if (expr->position() == RelocInfo::kNoPosition) return;
995 if (exit_seen_in_block_) return;
996 latest_source_info_.Update({expr->position(), true}); 976 latest_source_info_.Update({expr->position(), true});
997 } 977 }
998 978
999 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { 979 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
1000 return temporary_register_allocator()->RegisterIsLive(reg); 980 return temporary_register_allocator()->RegisterIsLive(reg);
1001 } 981 }
1002 982
1003 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, 983 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode,
1004 OperandScale operand_scale, 984 OperandScale operand_scale,
1005 int operand_index, 985 int operand_index,
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 } 1272 }
1293 1273
1294 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) { 1274 uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) {
1295 DCHECK_LE(value, kMaxUInt32); 1275 DCHECK_LE(value, kMaxUInt32);
1296 return static_cast<uint32_t>(value); 1276 return static_cast<uint32_t>(value);
1297 } 1277 }
1298 1278
1299 } // namespace interpreter 1279 } // namespace interpreter
1300 } // namespace internal 1280 } // namespace internal
1301 } // namespace v8 1281 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-array-builder.h ('k') | src/interpreter/bytecode-peephole-optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698