blob: 915c23dad394c12115b2d84bb4472de255410ed7 [file] [log] [blame]
Ben Murdoch61f157c2016-09-16 13:49:30 +01001// 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
3// found in the LICENSE file.
4
5#include "src/v8.h"
6
7#include "src/interpreter/bytecode-dead-code-optimizer.h"
8#include "src/interpreter/bytecode-label.h"
9#include "src/objects.h"
10#include "test/unittests/test-utils.h"
11
12namespace v8 {
13namespace internal {
14namespace interpreter {
15
16class BytecodeDeadCodeOptimizerTest : public BytecodePipelineStage,
17 public TestWithIsolateAndZone {
18 public:
19 BytecodeDeadCodeOptimizerTest() : dead_code_optimizer_(this) {}
20 ~BytecodeDeadCodeOptimizerTest() override {}
21
22 void Write(BytecodeNode* node) override {
23 write_count_++;
24 last_written_.Clone(node);
25 }
26
27 void WriteJump(BytecodeNode* node, BytecodeLabel* label) override {
28 write_count_++;
29 last_written_.Clone(node);
30 }
31
32 void BindLabel(BytecodeLabel* label) override {}
33 void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) override {}
34 Handle<BytecodeArray> ToBytecodeArray(
35 int fixed_register_count, int parameter_count,
36 Handle<FixedArray> handle_table) override {
37 return Handle<BytecodeArray>();
38 }
39
40 BytecodeDeadCodeOptimizer* optimizer() { return &dead_code_optimizer_; }
41
42 int write_count() const { return write_count_; }
43 const BytecodeNode& last_written() const { return last_written_; }
44
45 private:
46 BytecodeDeadCodeOptimizer dead_code_optimizer_;
47
48 int write_count_ = 0;
49 BytecodeNode last_written_;
50};
51
52TEST_F(BytecodeDeadCodeOptimizerTest, LiveCodeKept) {
53 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
54 optimizer()->Write(&add);
55 CHECK_EQ(write_count(), 1);
56 CHECK_EQ(add, last_written());
57
58 BytecodeLabel target;
59 BytecodeNode jump(Bytecode::kJump, 0);
60 optimizer()->WriteJump(&jump, &target);
61 CHECK_EQ(write_count(), 2);
62 CHECK_EQ(jump, last_written());
63}
64
65TEST_F(BytecodeDeadCodeOptimizerTest, DeadCodeAfterReturnEliminated) {
66 BytecodeNode ret(Bytecode::kReturn);
67 optimizer()->Write(&ret);
68 CHECK_EQ(write_count(), 1);
69 CHECK_EQ(ret, last_written());
70
71 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
72 optimizer()->Write(&add);
73 CHECK_EQ(write_count(), 1);
74 CHECK_EQ(ret, last_written());
75}
76
77TEST_F(BytecodeDeadCodeOptimizerTest, DeadCodeAfterThrowEliminated) {
78 BytecodeNode thrw(Bytecode::kThrow);
79 optimizer()->Write(&thrw);
80 CHECK_EQ(write_count(), 1);
81 CHECK_EQ(thrw, last_written());
82
83 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
84 optimizer()->Write(&add);
85 CHECK_EQ(write_count(), 1);
86 CHECK_EQ(thrw, last_written());
87}
88
89TEST_F(BytecodeDeadCodeOptimizerTest, DeadCodeAfterReThrowEliminated) {
90 BytecodeNode rethrow(Bytecode::kReThrow);
91 optimizer()->Write(&rethrow);
92 CHECK_EQ(write_count(), 1);
93 CHECK_EQ(rethrow, last_written());
94
95 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
96 optimizer()->Write(&add);
97 CHECK_EQ(write_count(), 1);
98 CHECK_EQ(rethrow, last_written());
99}
100
101TEST_F(BytecodeDeadCodeOptimizerTest, DeadCodeAfterJumpEliminated) {
102 BytecodeLabel target;
103 BytecodeNode jump(Bytecode::kJump, 0);
104 optimizer()->WriteJump(&jump, &target);
105 CHECK_EQ(write_count(), 1);
106 CHECK_EQ(jump, last_written());
107
108 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
109 optimizer()->Write(&add);
110 CHECK_EQ(write_count(), 1);
111 CHECK_EQ(jump, last_written());
112}
113
114TEST_F(BytecodeDeadCodeOptimizerTest, DeadCodeStillDeadAfterConditinalJump) {
115 BytecodeNode ret(Bytecode::kReturn);
116 optimizer()->Write(&ret);
117 CHECK_EQ(write_count(), 1);
118 CHECK_EQ(ret, last_written());
119
120 BytecodeLabel target;
121 BytecodeNode jump(Bytecode::kJumpIfTrue, 0);
122 optimizer()->WriteJump(&jump, &target);
123 CHECK_EQ(write_count(), 1);
124 CHECK_EQ(ret, last_written());
125
126 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
127 optimizer()->Write(&add);
128 CHECK_EQ(write_count(), 1);
129 CHECK_EQ(ret, last_written());
130}
131
132TEST_F(BytecodeDeadCodeOptimizerTest, CodeLiveAfterLabelBind) {
133 BytecodeNode ret(Bytecode::kReturn);
134 optimizer()->Write(&ret);
135 CHECK_EQ(write_count(), 1);
136 CHECK_EQ(ret, last_written());
137
138 BytecodeLabel target;
139 optimizer()->BindLabel(&target);
140
141 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand());
142 optimizer()->Write(&add);
143 CHECK_EQ(write_count(), 2);
144 CHECK_EQ(add, last_written());
145}
146
147} // namespace interpreter
148} // namespace internal
149} // namespace v8