1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "pretty_printer.h"
18
19 #include "base/arena_allocator.h"
20 #include "builder.h"
21 #include "dex/dex_file.h"
22 #include "dex/dex_instruction.h"
23 #include "nodes.h"
24 #include "optimizing_unit_test.h"
25
26 #include "gtest/gtest.h"
27
28 namespace art {
29
30 class PrettyPrinterTest : public OptimizingUnitTest {
31 protected:
32 void TestCode(const std::vector<uint16_t>& data, const char* expected);
33 };
34
TestCode(const std::vector<uint16_t> & data,const char * expected)35 void PrettyPrinterTest::TestCode(const std::vector<uint16_t>& data, const char* expected) {
36 HGraph* graph = CreateCFG(data);
37 StringPrettyPrinter printer(graph);
38 printer.VisitInsertionOrder();
39 ASSERT_STREQ(expected, printer.str().c_str());
40 }
41
TEST_F(PrettyPrinterTest,ReturnVoid)42 TEST_F(PrettyPrinterTest, ReturnVoid) {
43 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
44 Instruction::RETURN_VOID);
45
46 const char* expected =
47 "BasicBlock 0, succ: 1\n"
48 " 0: SuspendCheck\n"
49 " 1: Goto 1\n"
50 "BasicBlock 1, pred: 0, succ: 2\n"
51 " 2: ReturnVoid\n"
52 "BasicBlock 2, pred: 1\n"
53 " 3: Exit\n";
54
55 TestCode(data, expected);
56 }
57
TEST_F(PrettyPrinterTest,CFG1)58 TEST_F(PrettyPrinterTest, CFG1) {
59 const char* expected =
60 "BasicBlock 0, succ: 1\n"
61 " 0: SuspendCheck\n"
62 " 1: Goto 1\n"
63 "BasicBlock 1, pred: 0, succ: 2\n"
64 " 2: Goto 2\n"
65 "BasicBlock 2, pred: 1, succ: 3\n"
66 " 3: ReturnVoid\n"
67 "BasicBlock 3, pred: 2\n"
68 " 4: Exit\n";
69
70 const std::vector<uint16_t> data =
71 ZERO_REGISTER_CODE_ITEM(
72 Instruction::GOTO | 0x100,
73 Instruction::RETURN_VOID);
74
75 TestCode(data, expected);
76 }
77
TEST_F(PrettyPrinterTest,CFG2)78 TEST_F(PrettyPrinterTest, CFG2) {
79 const char* expected =
80 "BasicBlock 0, succ: 1\n"
81 " 0: SuspendCheck\n"
82 " 1: Goto 1\n"
83 "BasicBlock 1, pred: 0, succ: 2\n"
84 " 2: Goto 2\n"
85 "BasicBlock 2, pred: 1, succ: 3\n"
86 " 3: Goto 3\n"
87 "BasicBlock 3, pred: 2, succ: 4\n"
88 " 4: ReturnVoid\n"
89 "BasicBlock 4, pred: 3\n"
90 " 5: Exit\n";
91
92 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
93 Instruction::GOTO | 0x100,
94 Instruction::GOTO | 0x100,
95 Instruction::RETURN_VOID);
96
97 TestCode(data, expected);
98 }
99
TEST_F(PrettyPrinterTest,CFG3)100 TEST_F(PrettyPrinterTest, CFG3) {
101 const char* expected =
102 "BasicBlock 0, succ: 1\n"
103 " 0: SuspendCheck\n"
104 " 1: Goto 1\n"
105 "BasicBlock 1, pred: 0, succ: 3\n"
106 " 2: Goto 3\n"
107 "BasicBlock 2, pred: 3, succ: 4\n"
108 " 4: ReturnVoid\n"
109 "BasicBlock 3, pred: 1, succ: 2\n"
110 " 3: Goto 2\n"
111 "BasicBlock 4, pred: 2\n"
112 " 5: Exit\n";
113
114 const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
115 Instruction::GOTO | 0x200,
116 Instruction::RETURN_VOID,
117 Instruction::GOTO | 0xFF00);
118
119 TestCode(data1, expected);
120
121 const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
122 Instruction::GOTO_16, 3,
123 Instruction::RETURN_VOID,
124 Instruction::GOTO_16, 0xFFFF);
125
126 TestCode(data2, expected);
127
128 const std::vector<uint16_t> data3 = ZERO_REGISTER_CODE_ITEM(
129 Instruction::GOTO_32, 4, 0,
130 Instruction::RETURN_VOID,
131 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
132
133 TestCode(data3, expected);
134 }
135
TEST_F(PrettyPrinterTest,CFG4)136 TEST_F(PrettyPrinterTest, CFG4) {
137 const char* expected =
138 "BasicBlock 0, succ: 3\n"
139 " 1: SuspendCheck\n"
140 " 2: Goto 3\n"
141 "BasicBlock 1, pred: 3, 1, succ: 1\n"
142 " 3: SuspendCheck\n"
143 " 4: Goto 1\n"
144 "BasicBlock 3, pred: 0, succ: 1\n"
145 " 0: Goto 1\n";
146
147 const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
148 Instruction::NOP,
149 Instruction::GOTO | 0xFF00);
150
151 TestCode(data1, expected);
152
153 const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
154 Instruction::GOTO_32, 0, 0);
155
156 TestCode(data2, expected);
157 }
158
TEST_F(PrettyPrinterTest,CFG5)159 TEST_F(PrettyPrinterTest, CFG5) {
160 const char* expected =
161 "BasicBlock 0, succ: 1\n"
162 " 0: SuspendCheck\n"
163 " 1: Goto 1\n"
164 "BasicBlock 1, pred: 0, succ: 3\n"
165 " 2: ReturnVoid\n"
166 "BasicBlock 3, pred: 1\n"
167 " 3: Exit\n";
168
169 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
170 Instruction::RETURN_VOID,
171 Instruction::GOTO | 0x100,
172 Instruction::GOTO | 0xFE00);
173
174 TestCode(data, expected);
175 }
176
TEST_F(PrettyPrinterTest,CFG6)177 TEST_F(PrettyPrinterTest, CFG6) {
178 const char* expected =
179 "BasicBlock 0, succ: 1\n"
180 " 3: IntConstant [4, 4]\n"
181 " 1: SuspendCheck\n"
182 " 2: Goto 1\n"
183 "BasicBlock 1, pred: 0, succ: 5, 2\n"
184 " 4: Equal(3, 3) [5]\n"
185 " 5: If(4)\n"
186 "BasicBlock 2, pred: 1, succ: 3\n"
187 " 6: Goto 3\n"
188 "BasicBlock 3, pred: 5, 2, succ: 4\n"
189 " 7: ReturnVoid\n"
190 "BasicBlock 4, pred: 3\n"
191 " 8: Exit\n"
192 "BasicBlock 5, pred: 1, succ: 3\n"
193 " 0: Goto 3\n";
194
195 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
196 Instruction::CONST_4 | 0 | 0,
197 Instruction::IF_EQ, 3,
198 Instruction::GOTO | 0x100,
199 Instruction::RETURN_VOID);
200
201 TestCode(data, expected);
202 }
203
TEST_F(PrettyPrinterTest,CFG7)204 TEST_F(PrettyPrinterTest, CFG7) {
205 const char* expected =
206 "BasicBlock 0, succ: 1\n"
207 " 4: IntConstant [5, 5]\n"
208 " 2: SuspendCheck\n"
209 " 3: Goto 1\n"
210 "BasicBlock 1, pred: 0, succ: 5, 6\n"
211 " 5: Equal(4, 4) [6]\n"
212 " 6: If(5)\n"
213 "BasicBlock 2, pred: 6, 3, succ: 3\n"
214 " 11: Goto 3\n"
215 "BasicBlock 3, pred: 5, 2, succ: 2\n"
216 " 8: SuspendCheck\n"
217 " 9: Goto 2\n"
218 "BasicBlock 5, pred: 1, succ: 3\n"
219 " 0: Goto 3\n"
220 "BasicBlock 6, pred: 1, succ: 2\n"
221 " 1: Goto 2\n";
222
223 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
224 Instruction::CONST_4 | 0 | 0,
225 Instruction::IF_EQ, 3,
226 Instruction::GOTO | 0x100,
227 Instruction::GOTO | 0xFF00);
228
229 TestCode(data, expected);
230 }
231
TEST_F(PrettyPrinterTest,IntConstant)232 TEST_F(PrettyPrinterTest, IntConstant) {
233 const char* expected =
234 "BasicBlock 0, succ: 1\n"
235 " 2: IntConstant\n"
236 " 0: SuspendCheck\n"
237 " 1: Goto 1\n"
238 "BasicBlock 1, pred: 0, succ: 2\n"
239 " 3: ReturnVoid\n"
240 "BasicBlock 2, pred: 1\n"
241 " 4: Exit\n";
242
243 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
244 Instruction::CONST_4 | 0 | 0,
245 Instruction::RETURN_VOID);
246
247 TestCode(data, expected);
248 }
249 } // namespace art
250