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

Side by Side Diff: src/interpreter/bytecode-peephole-optimizer.cc

Issue 2035813002: [Interpreter] Move jump processing to bytecode array writer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_fix_bytecode
Patch Set: Address comments 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-peephole-optimizer.h ('k') | src/interpreter/bytecode-pipeline.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-peephole-optimizer.h" 5 #include "src/interpreter/bytecode-peephole-optimizer.h"
6 6
7 #include "src/interpreter/constant-array-builder.h" 7 #include "src/interpreter/constant-array-builder.h"
8 #include "src/objects-inl.h" 8 #include "src/objects-inl.h"
9 #include "src/objects.h" 9 #include "src/objects.h"
10 10
11 namespace v8 { 11 namespace v8 {
12 namespace internal { 12 namespace internal {
13 namespace interpreter { 13 namespace interpreter {
14 14
15 BytecodePeepholeOptimizer::BytecodePeepholeOptimizer( 15 BytecodePeepholeOptimizer::BytecodePeepholeOptimizer(
16 ConstantArrayBuilder* constant_array_builder, 16 ConstantArrayBuilder* constant_array_builder,
17 BytecodePipelineStage* next_stage) 17 BytecodePipelineStage* next_stage)
18 : constant_array_builder_(constant_array_builder), 18 : constant_array_builder_(constant_array_builder), next_stage_(next_stage) {
19 next_stage_(next_stage),
20 last_is_discardable_(false) {
21 InvalidateLast(); 19 InvalidateLast();
22 } 20 }
23 21
22 // override
23 Handle<BytecodeArray> BytecodePeepholeOptimizer::ToBytecodeArray(
24 int fixed_register_count, int parameter_count,
25 Handle<FixedArray> handler_table) {
26 Flush();
27 return next_stage_->ToBytecodeArray(fixed_register_count, parameter_count,
28 handler_table);
29 }
30
31 // override
32 void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
33 node = OptimizeAndEmitLast(node);
34 if (node != nullptr) {
35 SetLast(node);
36 }
37 }
38
39 // override
40 void BytecodePeepholeOptimizer::WriteJump(BytecodeNode* node,
41 BytecodeLabel* label) {
42 node = OptimizeAndEmitLast(node);
43 next_stage_->WriteJump(node, label);
44 }
45
46 // override
47 void BytecodePeepholeOptimizer::BindLabel(BytecodeLabel* label) {
48 Flush();
49 next_stage_->BindLabel(label);
50 }
51
52 // override
53 void BytecodePeepholeOptimizer::BindLabel(const BytecodeLabel& target,
54 BytecodeLabel* label) {
55 // There is no need to flush here, it will have been flushed when |target|
56 // was bound.
57 next_stage_->BindLabel(target, label);
58 }
59
60 void BytecodePeepholeOptimizer::Flush() {
61 // TODO(oth/rmcilroy): We could check CanElideLast() here to potentially
62 // eliminate last rather than writing it.
63 if (LastIsValid()) {
64 next_stage_->Write(&last_);
65 InvalidateLast();
66 }
67 }
68
24 void BytecodePeepholeOptimizer::InvalidateLast() { 69 void BytecodePeepholeOptimizer::InvalidateLast() {
25 last_.set_bytecode(Bytecode::kIllegal); 70 last_.set_bytecode(Bytecode::kIllegal);
26 } 71 }
27 72
28 bool BytecodePeepholeOptimizer::LastIsValid() const { 73 bool BytecodePeepholeOptimizer::LastIsValid() const {
29 return last_.bytecode() != Bytecode::kIllegal; 74 return last_.bytecode() != Bytecode::kIllegal;
30 } 75 }
31 76
32 void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) { 77 void BytecodePeepholeOptimizer::SetLast(const BytecodeNode* const node) {
33 last_.Clone(node); 78 last_.Clone(node);
34 last_is_discardable_ = true;
35 }
36
37 // override
38 size_t BytecodePeepholeOptimizer::FlushForOffset() {
39 size_t buffered_size = next_stage_->FlushForOffset();
40 if (LastIsValid()) {
41 if (last_.bytecode() == Bytecode::kNop &&
42 !last_.source_info().is_statement()) {
43 // The Nop can be dropped as it doesn't have a statement
44 // position for the debugger and doesn't have any effects by
45 // definition.
46 InvalidateLast();
47 } else {
48 buffered_size += last_.Size();
49 last_is_discardable_ = false;
50 }
51 }
52 return buffered_size;
53 }
54
55 // override
56 void BytecodePeepholeOptimizer::FlushBasicBlock() {
57 if (LastIsValid()) {
58 next_stage_->Write(&last_);
59 InvalidateLast();
60 }
61 next_stage_->FlushBasicBlock();
62 }
63
64 // override
65 void BytecodePeepholeOptimizer::Write(BytecodeNode* node) {
66 // Attempt optimization if there is an earlier node to optimize with.
67 if (LastIsValid()) {
68 node = Optimize(node);
69 // Only output the last node if it wasn't invalidated by the optimization.
70 if (LastIsValid()) {
71 next_stage_->Write(&last_);
72 InvalidateLast();
73 }
74 }
75
76 if (node != nullptr) {
77 SetLast(node);
78 }
79 } 79 }
80 80
81 Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand( 81 Handle<Object> BytecodePeepholeOptimizer::GetConstantForIndexOperand(
82 const BytecodeNode* const node, int index) const { 82 const BytecodeNode* const node, int index) const {
83 DCHECK_LE(index, node->operand_count()); 83 DCHECK_LE(index, node->operand_count());
84 DCHECK_EQ(Bytecodes::GetOperandType(node->bytecode(), 0), OperandType::kIdx); 84 DCHECK_EQ(Bytecodes::GetOperandType(node->bytecode(), 0), OperandType::kIdx);
85 uint32_t index_operand = node->operand(0); 85 uint32_t index_operand = node->operand(0);
86 return constant_array_builder_->At(index_operand); 86 return constant_array_builder_->At(index_operand);
87 } 87 }
88 88
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 253 }
254 254
255 bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes( 255 bool BytecodePeepholeOptimizer::TransformLastAndCurrentBytecodes(
256 BytecodeNode* const current) { 256 BytecodeNode* const current) {
257 return RemoveToBooleanFromJump(current) || 257 return RemoveToBooleanFromJump(current) ||
258 RemoveToBooleanFromLogicalNot(current) || ChangeLdaToLdr(current); 258 RemoveToBooleanFromLogicalNot(current) || ChangeLdaToLdr(current);
259 } 259 }
260 260
261 bool BytecodePeepholeOptimizer::CanElideLast( 261 bool BytecodePeepholeOptimizer::CanElideLast(
262 const BytecodeNode* const current) const { 262 const BytecodeNode* const current) const {
263 if (!last_is_discardable_) {
264 return false;
265 }
266
267 if (last_.bytecode() == Bytecode::kNop) { 263 if (last_.bytecode() == Bytecode::kNop) {
268 // Nop are placeholders for holding source position information. 264 // Nop are placeholders for holding source position information.
269 return true; 265 return true;
270 } else if (Bytecodes::IsAccumulatorLoadWithoutEffects(current->bytecode()) && 266 } else if (Bytecodes::IsAccumulatorLoadWithoutEffects(current->bytecode()) &&
271 Bytecodes::IsAccumulatorLoadWithoutEffects(last_.bytecode())) { 267 Bytecodes::IsAccumulatorLoadWithoutEffects(last_.bytecode())) {
272 // The accumulator is invisible to the debugger. If there is a sequence of 268 // The accumulator is invisible to the debugger. If there is a sequence of
273 // consecutive accumulator loads (that don't have side effects) then only 269 // consecutive accumulator loads (that don't have side effects) then only
274 // the final load is potentially visible. 270 // the final load is potentially visible.
275 return true; 271 return true;
276 } else if (Bytecodes::GetAccumulatorUse(current->bytecode()) == 272 } else if (Bytecodes::GetAccumulatorUse(current->bytecode()) ==
(...skipping 27 matching lines...) Expand all
304 300
305 if (CanElideLast(current) && CanElideLastBasedOnSourcePosition(current)) { 301 if (CanElideLast(current) && CanElideLastBasedOnSourcePosition(current)) {
306 current->source_info().Update(last_.source_info()); 302 current->source_info().Update(last_.source_info());
307 InvalidateLast(); 303 InvalidateLast();
308 return current; 304 return current;
309 } 305 }
310 306
311 return current; 307 return current;
312 } 308 }
313 309
310 BytecodeNode* BytecodePeepholeOptimizer::OptimizeAndEmitLast(
311 BytecodeNode* current) {
312 // Attempt optimization if there is an earlier node to optimize with.
313 if (LastIsValid()) {
314 current = Optimize(current);
315 // Only output the last node if it wasn't invalidated by the optimization.
316 if (LastIsValid()) {
317 next_stage_->Write(&last_);
318 InvalidateLast();
319 }
320 }
321 return current;
322 }
323
314 } // namespace interpreter 324 } // namespace interpreter
315 } // namespace internal 325 } // namespace internal
316 } // namespace v8 326 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-peephole-optimizer.h ('k') | src/interpreter/bytecode-pipeline.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698