OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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-peephole-optimizer.h" | 5 #include "src/interpreter/bytecode-peephole-optimizer.h" |
6 | 6 |
7 #include "src/interpreter/constant-array-builder.h" | |
8 #include "src/objects-inl.h" | 7 #include "src/objects-inl.h" |
9 #include "src/objects.h" | 8 #include "src/objects.h" |
10 | 9 |
11 namespace v8 { | 10 namespace v8 { |
12 namespace internal { | 11 namespace internal { |
13 namespace interpreter { | 12 namespace interpreter { |
14 | 13 |
15 BytecodePeepholeOptimizer::BytecodePeepholeOptimizer( | 14 BytecodePeepholeOptimizer::BytecodePeepholeOptimizer( |
16 ConstantArrayBuilder* constant_array_builder, | |
17 BytecodePipelineStage* next_stage) | 15 BytecodePipelineStage* next_stage) |
18 : constant_array_builder_(constant_array_builder), next_stage_(next_stage) { | 16 : next_stage_(next_stage) { |
19 InvalidateLast(); | 17 InvalidateLast(); |
20 } | 18 } |
21 | 19 |
22 // override | 20 // override |
23 Handle<BytecodeArray> BytecodePeepholeOptimizer::ToBytecodeArray( | 21 Handle<BytecodeArray> BytecodePeepholeOptimizer::ToBytecodeArray( |
24 int fixed_register_count, int parameter_count, | 22 int fixed_register_count, int parameter_count, |
25 Handle<FixedArray> handler_table) { | 23 Handle<FixedArray> handler_table) { |
26 Flush(); | 24 Flush(); |
27 return next_stage_->ToBytecodeArray(fixed_register_count, parameter_count, | 25 return next_stage_->ToBytecodeArray(fixed_register_count, parameter_count, |
28 handler_table); | 26 handler_table); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 74 |
77 void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) { | 75 void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) { |
78 // An action shouldn't leave a NOP as last bytecode unless it has | 76 // An action shouldn't leave a NOP as last bytecode unless it has |
79 // source position information. NOP without source information can | 77 // source position information. NOP without source information can |
80 // always be elided. | 78 // always be elided. |
81 DCHECK(node->bytecode() != Bytecode::kNop || node->source_info().is_valid()); | 79 DCHECK(node->bytecode() != Bytecode::kNop || node->source_info().is_valid()); |
82 | 80 |
83 last_.Clone(node); | 81 last_.Clone(node); |
84 } | 82 } |
85 | 83 |
86 Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand( | |
87 const BytecodeNode* const node, int index) const { | |
88 DCHECK_LE(index, node->operand_count()); | |
89 DCHECK_EQ(Bytecodes::GetOperandType(node->bytecode(), 0), OperandType::kIdx); | |
90 uint32_t index_operand = node->operand(0); | |
91 return constant_array_builder_->At(index_operand); | |
92 } | |
93 | |
94 bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition( | 84 bool BytecodePeepholeOptimizer::CanElideLastBasedOnSourcePosition( |
95 const BytecodeNode* const current) const { | 85 const BytecodeNode* const current) const { |
96 // | 86 // |
97 // The rules for allowing the elision of the last bytecode based | 87 // The rules for allowing the elision of the last bytecode based |
98 // on source position are: | 88 // on source position are: |
99 // | 89 // |
100 // C U R R E N T | 90 // C U R R E N T |
101 // +--------+--------+--------+ | 91 // +--------+--------+--------+ |
102 // | None | Expr | Stmt | | 92 // | None | Expr | Stmt | |
103 // L +--------+--------+--------+--------+ | 93 // L +--------+--------+--------+--------+ |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 if (!node->source_info().is_valid() || !last()->source_info().is_valid()) { | 272 if (!node->source_info().is_valid() || !last()->source_info().is_valid()) { |
283 // Fused last and current into current. | 273 // Fused last and current into current. |
284 TransformLdaZeroBinaryOpToBinaryOpWithZero(action_data->bytecode, last(), | 274 TransformLdaZeroBinaryOpToBinaryOpWithZero(action_data->bytecode, last(), |
285 node); | 275 node); |
286 SetLast(node); | 276 SetLast(node); |
287 } else { | 277 } else { |
288 DefaultAction(node); | 278 DefaultAction(node); |
289 } | 279 } |
290 } | 280 } |
291 | 281 |
292 void BytecodePeepholeOptimizer::TransformToStarIfLoadingNameConstantAction( | |
293 BytecodeNode* const node, const PeepholeActionAndData* action_data) { | |
294 DCHECK_EQ(last()->bytecode(), Bytecode::kLdaConstant); | |
295 DCHECK(!Bytecodes::IsJump(node->bytecode())); | |
296 | |
297 // TODO(5203): Remove this temporary exception. | |
298 AllowHandleDereference allow_deref; | |
299 if (GetConstantForIndexOperand(last(), 0)->IsName()) { | |
300 node->replace_bytecode(Bytecode::kStar); | |
301 } | |
302 DefaultAction(node); | |
303 } | |
304 | |
305 void BytecodePeepholeOptimizer::DefaultJumpAction( | 282 void BytecodePeepholeOptimizer::DefaultJumpAction( |
306 BytecodeNode* const node, const PeepholeActionAndData* action_data) { | 283 BytecodeNode* const node, const PeepholeActionAndData* action_data) { |
307 DCHECK(LastIsValid()); | 284 DCHECK(LastIsValid()); |
308 DCHECK(Bytecodes::IsJump(node->bytecode())); | 285 DCHECK(Bytecodes::IsJump(node->bytecode())); |
309 | 286 |
310 next_stage()->Write(last()); | 287 next_stage()->Write(last()); |
311 InvalidateLast(); | 288 InvalidateLast(); |
312 } | 289 } |
313 | 290 |
314 void BytecodePeepholeOptimizer::UpdateLastJumpAction( | 291 void BytecodePeepholeOptimizer::UpdateLastJumpAction( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 #undef CASE | 334 #undef CASE |
358 default: | 335 default: |
359 UNREACHABLE(); | 336 UNREACHABLE(); |
360 break; | 337 break; |
361 } | 338 } |
362 } | 339 } |
363 | 340 |
364 } // namespace interpreter | 341 } // namespace interpreter |
365 } // namespace internal | 342 } // namespace internal |
366 } // namespace v8 | 343 } // namespace v8 |
OLD | NEW |