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 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 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 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 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 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 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 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 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 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 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