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

Side by Side Diff: src/interpreter/bytecode-pipeline.h

Issue 2393683004: [Interpreter] Optimize the Register Optimizer. (Closed)
Patch Set: Rebase Created 4 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-peephole-optimizer.cc ('k') | src/interpreter/bytecode-pipeline.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 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_ 5 #ifndef V8_INTERPRETER_BYTECODE_PIPELINE_H_
6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_ 6 #define V8_INTERPRETER_BYTECODE_PIPELINE_H_
7 7
8 #include "src/base/compiler-specific.h" 8 #include "src/base/compiler-specific.h"
9 #include "src/globals.h" 9 #include "src/globals.h"
10 #include "src/interpreter/bytecode-register-allocator.h" 10 #include "src/interpreter/bytecode-register-allocator.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 position_type_ = PositionType::kExpression; 88 position_type_ = PositionType::kExpression;
89 source_position_ = source_position; 89 source_position_ = source_position;
90 } 90 }
91 91
92 // Forces an instance into an expression position. 92 // Forces an instance into an expression position.
93 void ForceExpressionPosition(int source_position) { 93 void ForceExpressionPosition(int source_position) {
94 position_type_ = PositionType::kExpression; 94 position_type_ = PositionType::kExpression;
95 source_position_ = source_position; 95 source_position_ = source_position;
96 } 96 }
97 97
98 // Clones a source position. The current instance is expected to be
99 // invalid.
100 void Clone(const BytecodeSourceInfo& other) {
101 DCHECK(!is_valid());
102 position_type_ = other.position_type_;
103 source_position_ = other.source_position_;
104 }
105
106 int source_position() const { 98 int source_position() const {
107 DCHECK(is_valid()); 99 DCHECK(is_valid());
108 return source_position_; 100 return source_position_;
109 } 101 }
110 102
111 bool is_statement() const { 103 bool is_statement() const {
112 return position_type_ == PositionType::kStatement; 104 return position_type_ == PositionType::kStatement;
113 } 105 }
114 bool is_expression() const { 106 bool is_expression() const {
115 return position_type_ == PositionType::kExpression; 107 return position_type_ == PositionType::kExpression;
(...skipping 19 matching lines...) Expand all
135 enum class PositionType : uint8_t { kNone, kExpression, kStatement }; 127 enum class PositionType : uint8_t { kNone, kExpression, kStatement };
136 128
137 PositionType position_type_; 129 PositionType position_type_;
138 int source_position_; 130 int source_position_;
139 }; 131 };
140 132
141 // A container for a generated bytecode, it's operands, and source information. 133 // A container for a generated bytecode, it's operands, and source information.
142 // These must be allocated by a BytecodeNodeAllocator instance. 134 // These must be allocated by a BytecodeNodeAllocator instance.
143 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) { 135 class V8_EXPORT_PRIVATE BytecodeNode final : NON_EXPORTED_BASE(ZoneObject) {
144 public: 136 public:
145 INLINE(BytecodeNode(const Bytecode bytecode, 137 INLINE(BytecodeNode(Bytecode bytecode,
146 BytecodeSourceInfo* source_info = nullptr)) 138 BytecodeSourceInfo source_info = BytecodeSourceInfo()))
147 : bytecode_(bytecode), 139 : bytecode_(bytecode),
148 operand_count_(0), 140 operand_count_(0),
149 operand_scale_(OperandScale::kSingle) { 141 operand_scale_(OperandScale::kSingle),
142 source_info_(source_info) {
150 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); 143 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
151 AttachSourceInfo(source_info);
152 } 144 }
153 145
154 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, 146 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0,
155 BytecodeSourceInfo* source_info = nullptr)) 147 BytecodeSourceInfo source_info = BytecodeSourceInfo()))
156 : bytecode_(bytecode), 148 : bytecode_(bytecode),
157 operand_count_(1), 149 operand_count_(1),
158 operand_scale_(OperandScale::kSingle) { 150 operand_scale_(OperandScale::kSingle),
151 source_info_(source_info) {
159 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); 152 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
160 SetOperand(0, operand0); 153 SetOperand(0, operand0);
161 AttachSourceInfo(source_info);
162 } 154 }
163 155
164 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, 156 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
165 uint32_t operand1, 157 BytecodeSourceInfo source_info = BytecodeSourceInfo()))
166 BytecodeSourceInfo* source_info = nullptr))
167 : bytecode_(bytecode), 158 : bytecode_(bytecode),
168 operand_count_(2), 159 operand_count_(2),
169 operand_scale_(OperandScale::kSingle) { 160 operand_scale_(OperandScale::kSingle),
161 source_info_(source_info) {
170 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); 162 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
171 SetOperand(0, operand0); 163 SetOperand(0, operand0);
172 SetOperand(1, operand1); 164 SetOperand(1, operand1);
173 AttachSourceInfo(source_info);
174 } 165 }
175 166
176 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, 167 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
177 uint32_t operand1, uint32_t operand2, 168 uint32_t operand2,
178 BytecodeSourceInfo* source_info = nullptr)) 169 BytecodeSourceInfo source_info = BytecodeSourceInfo()))
179 : bytecode_(bytecode), 170 : bytecode_(bytecode),
180 operand_count_(3), 171 operand_count_(3),
181 operand_scale_(OperandScale::kSingle) { 172 operand_scale_(OperandScale::kSingle),
173 source_info_(source_info) {
182 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); 174 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
183 SetOperand(0, operand0); 175 SetOperand(0, operand0);
184 SetOperand(1, operand1); 176 SetOperand(1, operand1);
185 SetOperand(2, operand2); 177 SetOperand(2, operand2);
186 AttachSourceInfo(source_info);
187 } 178 }
188 179
189 INLINE(BytecodeNode(const Bytecode bytecode, uint32_t operand0, 180 INLINE(BytecodeNode(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
190 uint32_t operand1, uint32_t operand2, uint32_t operand3, 181 uint32_t operand2, uint32_t operand3,
191 BytecodeSourceInfo* source_info = nullptr)) 182 BytecodeSourceInfo source_info = BytecodeSourceInfo()))
192 : bytecode_(bytecode), 183 : bytecode_(bytecode),
193 operand_count_(4), 184 operand_count_(4),
194 operand_scale_(OperandScale::kSingle) { 185 operand_scale_(OperandScale::kSingle),
186 source_info_(source_info) {
195 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count()); 187 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count());
196 SetOperand(0, operand0); 188 SetOperand(0, operand0);
197 SetOperand(1, operand1); 189 SetOperand(1, operand1);
198 SetOperand(2, operand2); 190 SetOperand(2, operand2);
199 SetOperand(3, operand3); 191 SetOperand(3, operand3);
200 AttachSourceInfo(source_info);
201 } 192 }
202 193
203 BytecodeNode(const BytecodeNode& other);
204 BytecodeNode& operator=(const BytecodeNode& other);
205
206 // Replace the bytecode of this node with |bytecode| and keep the operands. 194 // Replace the bytecode of this node with |bytecode| and keep the operands.
207 void replace_bytecode(Bytecode bytecode) { 195 void replace_bytecode(Bytecode bytecode) {
208 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_), 196 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode_),
209 Bytecodes::NumberOfOperands(bytecode)); 197 Bytecodes::NumberOfOperands(bytecode));
210 bytecode_ = bytecode; 198 bytecode_ = bytecode;
211 } 199 }
200
212 void set_bytecode(Bytecode bytecode) { 201 void set_bytecode(Bytecode bytecode) {
213 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); 202 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
214 bytecode_ = bytecode; 203 bytecode_ = bytecode;
215 operand_count_ = 0; 204 operand_count_ = 0;
216 operand_scale_ = OperandScale::kSingle; 205 operand_scale_ = OperandScale::kSingle;
217 } 206 }
207
218 void set_bytecode(Bytecode bytecode, uint32_t operand0) { 208 void set_bytecode(Bytecode bytecode, uint32_t operand0) {
219 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1); 209 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
220 bytecode_ = bytecode; 210 bytecode_ = bytecode;
221 operand_count_ = 1; 211 operand_count_ = 1;
222 operand_scale_ = OperandScale::kSingle; 212 operand_scale_ = OperandScale::kSingle;
223 SetOperand(0, operand0); 213 SetOperand(0, operand0);
224 } 214 }
215
225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) { 216 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1) {
226 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2); 217 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2);
227 bytecode_ = bytecode; 218 bytecode_ = bytecode;
228 operand_count_ = 2; 219 operand_count_ = 2;
229 operand_scale_ = OperandScale::kSingle; 220 operand_scale_ = OperandScale::kSingle;
230 SetOperand(0, operand0); 221 SetOperand(0, operand0);
231 SetOperand(1, operand1); 222 SetOperand(1, operand1);
232 } 223 }
224
233 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1, 225 void set_bytecode(Bytecode bytecode, uint32_t operand0, uint32_t operand1,
234 uint32_t operand2) { 226 uint32_t operand2) {
235 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); 227 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3);
236 bytecode_ = bytecode; 228 bytecode_ = bytecode;
237 operand_count_ = 3; 229 operand_count_ = 3;
238 operand_scale_ = OperandScale::kSingle; 230 operand_scale_ = OperandScale::kSingle;
239 SetOperand(0, operand0); 231 SetOperand(0, operand0);
240 SetOperand(1, operand1); 232 SetOperand(1, operand1);
241 SetOperand(2, operand2); 233 SetOperand(2, operand2);
242 } 234 }
243 235
244 // Clone |other|.
245 void Clone(const BytecodeNode* const other);
246
247 // Print to stream |os|. 236 // Print to stream |os|.
248 void Print(std::ostream& os) const; 237 void Print(std::ostream& os) const;
249 238
250 // Transform to a node representing |new_bytecode| which has one 239 // Transform to a node representing |new_bytecode| which has one
251 // operand more than the current bytecode. 240 // operand more than the current bytecode.
252 void Transform(Bytecode new_bytecode, uint32_t extra_operand) { 241 void Transform(Bytecode new_bytecode, uint32_t extra_operand) {
253 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode), 242 DCHECK_EQ(Bytecodes::NumberOfOperands(new_bytecode),
254 Bytecodes::NumberOfOperands(bytecode()) + 1); 243 Bytecodes::NumberOfOperands(bytecode()) + 1);
255 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 || 244 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 1 ||
256 Bytecodes::GetOperandType(new_bytecode, 0) == 245 Bytecodes::GetOperandType(new_bytecode, 0) ==
257 Bytecodes::GetOperandType(bytecode(), 0)); 246 Bytecodes::GetOperandType(bytecode(), 0));
258 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 || 247 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 2 ||
259 Bytecodes::GetOperandType(new_bytecode, 1) == 248 Bytecodes::GetOperandType(new_bytecode, 1) ==
260 Bytecodes::GetOperandType(bytecode(), 1)); 249 Bytecodes::GetOperandType(bytecode(), 1));
261 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 || 250 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 3 ||
262 Bytecodes::GetOperandType(new_bytecode, 2) == 251 Bytecodes::GetOperandType(new_bytecode, 2) ==
263 Bytecodes::GetOperandType(bytecode(), 2)); 252 Bytecodes::GetOperandType(bytecode(), 2));
264 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4); 253 DCHECK(Bytecodes::NumberOfOperands(bytecode()) < 4);
265 254
266 bytecode_ = new_bytecode; 255 bytecode_ = new_bytecode;
267 operand_count_++; 256 operand_count_++;
268 SetOperand(operand_count() - 1, extra_operand); 257 SetOperand(operand_count() - 1, extra_operand);
269 } 258 }
270 259
271 // Updates the operand at |operand_index| to |operand|.
272 void UpdateOperand(int operand_index, uint32_t operand) {
273 DCHECK_LE(operand_index, Bytecodes::NumberOfOperands(bytecode()));
274 operands_[operand_index] = operand;
275 if ((Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index) &&
276 Bytecodes::ScaleForSignedOperand(operand) != operand_scale_) ||
277 (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), operand_index) &&
278 Bytecodes::ScaleForUnsignedOperand(operand) != operand_scale_)) {
279 UpdateScale();
280 }
281 }
282
283 Bytecode bytecode() const { return bytecode_; } 260 Bytecode bytecode() const { return bytecode_; }
284 261
285 uint32_t operand(int i) const { 262 uint32_t operand(int i) const {
286 DCHECK_LT(i, operand_count()); 263 DCHECK_LT(i, operand_count());
287 return operands_[i]; 264 return operands_[i];
288 } 265 }
289 const uint32_t* operands() const { return operands_; } 266 const uint32_t* operands() const { return operands_; }
290 267
291 int operand_count() const { return operand_count_; } 268 int operand_count() const { return operand_count_; }
292 OperandScale operand_scale() const { return operand_scale_; } 269 OperandScale operand_scale() const { return operand_scale_; }
293 270
294 const BytecodeSourceInfo& source_info() const { return source_info_; } 271 const BytecodeSourceInfo& source_info() const { return source_info_; }
295 BytecodeSourceInfo* source_info_ptr() { return &source_info_; } 272 void set_source_info(BytecodeSourceInfo source_info) {
273 source_info_ = source_info;
274 }
296 275
297 bool operator==(const BytecodeNode& other) const; 276 bool operator==(const BytecodeNode& other) const;
298 bool operator!=(const BytecodeNode& other) const { return !(*this == other); } 277 bool operator!=(const BytecodeNode& other) const { return !(*this == other); }
299 278
300 private: 279 private:
301 INLINE(void AttachSourceInfo(BytecodeSourceInfo* source_info)) {
302 if (source_info && source_info->is_valid()) {
303 // Statement positions need to be emitted immediately. Expression
304 // positions can be pushed back until a bytecode is found that can
305 // throw (if expression position filtering is turned on). We only
306 // invalidate the existing source position information if it is used.
307 if (source_info->is_statement() ||
308 !FLAG_ignition_filter_expression_positions ||
309 !Bytecodes::IsWithoutExternalSideEffects(bytecode())) {
310 source_info_.Clone(*source_info);
311 source_info->set_invalid();
312 }
313 }
314 }
315
316 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) { 280 INLINE(void UpdateScaleForOperand(int operand_index, uint32_t operand)) {
317 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) { 281 if (Bytecodes::OperandIsScalableSignedByte(bytecode(), operand_index)) {
318 operand_scale_ = 282 operand_scale_ =
319 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand)); 283 std::max(operand_scale_, Bytecodes::ScaleForSignedOperand(operand));
320 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(), 284 } else if (Bytecodes::OperandIsScalableUnsignedByte(bytecode(),
321 operand_index)) { 285 operand_index)) {
322 operand_scale_ = 286 operand_scale_ =
323 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand)); 287 std::max(operand_scale_, Bytecodes::ScaleForUnsignedOperand(operand));
324 } 288 }
325 } 289 }
326 290
327 INLINE(void SetOperand(int operand_index, uint32_t operand)) { 291 INLINE(void SetOperand(int operand_index, uint32_t operand)) {
328 operands_[operand_index] = operand; 292 operands_[operand_index] = operand;
329 UpdateScaleForOperand(operand_index, operand); 293 UpdateScaleForOperand(operand_index, operand);
330 } 294 }
331 295
332 void UpdateScale() {
333 operand_scale_ = OperandScale::kSingle;
334 for (int i = 0; i < operand_count(); i++) {
335 UpdateScaleForOperand(i, operands_[i]);
336 }
337 }
338
339 Bytecode bytecode_; 296 Bytecode bytecode_;
340 uint32_t operands_[Bytecodes::kMaxOperands]; 297 uint32_t operands_[Bytecodes::kMaxOperands];
341 int operand_count_; 298 int operand_count_;
342 OperandScale operand_scale_; 299 OperandScale operand_scale_;
343 BytecodeSourceInfo source_info_; 300 BytecodeSourceInfo source_info_;
344 }; 301 };
345 302
346 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 303 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
347 const BytecodeSourceInfo& info); 304 const BytecodeSourceInfo& info);
348 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 305 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
349 const BytecodeNode& node); 306 const BytecodeNode& node);
350 307
351 } // namespace interpreter 308 } // namespace interpreter
352 } // namespace internal 309 } // namespace internal
353 } // namespace v8 310 } // namespace v8
354 311
355 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_ 312 #endif // V8_INTERPRETER_BYTECODE_PIPELINE_H_
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-peephole-optimizer.cc ('k') | src/interpreter/bytecode-pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698