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 "base/stringprintf.h" 18#include "builder.h" 19#include "dex_file.h" 20#include "dex_instruction.h" 21#include "nodes.h" 22#include "optimizing_unit_test.h" 23#include "pretty_printer.h" 24#include "utils/arena_allocator.h" 25 26#include "gtest/gtest.h" 27 28namespace art { 29 30static void TestCode(const uint16_t* data, const char* expected) { 31 ArenaPool pool; 32 ArenaAllocator allocator(&pool); 33 HGraphBuilder builder(&allocator); 34 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data); 35 HGraph* graph = builder.BuildGraph(*item); 36 ASSERT_NE(graph, nullptr); 37 StringPrettyPrinter printer(graph); 38 printer.VisitInsertionOrder(); 39 ASSERT_STREQ(expected, printer.str().c_str()); 40} 41 42TEST(PrettyPrinterTest, ReturnVoid) { 43 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 44 Instruction::RETURN_VOID); 45 46 const char* expected = 47 "BasicBlock 0, succ: 1\n" 48 " 2: Goto 1\n" 49 "BasicBlock 1, pred: 0, succ: 2\n" 50 " 0: ReturnVoid\n" 51 "BasicBlock 2, pred: 1\n" 52 " 1: Exit\n"; 53 54 TestCode(data, expected); 55} 56 57TEST(PrettyPrinterTest, CFG1) { 58 const char* expected = 59 "BasicBlock 0, succ: 1\n" 60 " 3: Goto 1\n" 61 "BasicBlock 1, pred: 0, succ: 2\n" 62 " 0: Goto 2\n" 63 "BasicBlock 2, pred: 1, succ: 3\n" 64 " 1: ReturnVoid\n" 65 "BasicBlock 3, pred: 2\n" 66 " 2: Exit\n"; 67 68 const uint16_t data[] = 69 ZERO_REGISTER_CODE_ITEM( 70 Instruction::GOTO | 0x100, 71 Instruction::RETURN_VOID); 72 73 TestCode(data, expected); 74} 75 76TEST(PrettyPrinterTest, CFG2) { 77 const char* expected = 78 "BasicBlock 0, succ: 1\n" 79 " 4: Goto 1\n" 80 "BasicBlock 1, pred: 0, succ: 2\n" 81 " 0: Goto 2\n" 82 "BasicBlock 2, pred: 1, succ: 3\n" 83 " 1: Goto 3\n" 84 "BasicBlock 3, pred: 2, succ: 4\n" 85 " 2: ReturnVoid\n" 86 "BasicBlock 4, pred: 3\n" 87 " 3: Exit\n"; 88 89 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 90 Instruction::GOTO | 0x100, 91 Instruction::GOTO | 0x100, 92 Instruction::RETURN_VOID); 93 94 TestCode(data, expected); 95} 96 97TEST(PrettyPrinterTest, CFG3) { 98 const char* expected = 99 "BasicBlock 0, succ: 1\n" 100 " 4: Goto 1\n" 101 "BasicBlock 1, pred: 0, succ: 3\n" 102 " 0: Goto 3\n" 103 "BasicBlock 2, pred: 3, succ: 4\n" 104 " 1: ReturnVoid\n" 105 "BasicBlock 3, pred: 1, succ: 2\n" 106 " 2: Goto 2\n" 107 "BasicBlock 4, pred: 2\n" 108 " 3: Exit\n"; 109 110 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 111 Instruction::GOTO | 0x200, 112 Instruction::RETURN_VOID, 113 Instruction::GOTO | 0xFF00); 114 115 TestCode(data1, expected); 116 117 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 118 Instruction::GOTO_16, 3, 119 Instruction::RETURN_VOID, 120 Instruction::GOTO_16, 0xFFFF); 121 122 TestCode(data2, expected); 123 124 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM( 125 Instruction::GOTO_32, 4, 0, 126 Instruction::RETURN_VOID, 127 Instruction::GOTO_32, 0xFFFF, 0xFFFF); 128 129 TestCode(data3, expected); 130} 131 132TEST(PrettyPrinterTest, CFG4) { 133 const char* expected = 134 "BasicBlock 0, succ: 1\n" 135 " 2: Goto 1\n" 136 "BasicBlock 1, pred: 0, 1, succ: 1\n" 137 " 0: Goto 1\n" 138 "BasicBlock 2\n" 139 " 1: Exit\n"; 140 141 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM( 142 Instruction::NOP, 143 Instruction::GOTO | 0xFF00); 144 145 TestCode(data1, expected); 146 147 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM( 148 Instruction::GOTO_32, 0, 0); 149 150 TestCode(data2, expected); 151} 152 153TEST(PrettyPrinterTest, CFG5) { 154 const char* expected = 155 "BasicBlock 0, succ: 1\n" 156 " 3: Goto 1\n" 157 "BasicBlock 1, pred: 0, 2, succ: 3\n" 158 " 0: ReturnVoid\n" 159 "BasicBlock 2, succ: 1\n" 160 " 1: Goto 1\n" 161 "BasicBlock 3, pred: 1\n" 162 " 2: Exit\n"; 163 164 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM( 165 Instruction::RETURN_VOID, 166 Instruction::GOTO | 0x100, 167 Instruction::GOTO | 0xFE00); 168 169 TestCode(data, expected); 170} 171 172TEST(PrettyPrinterTest, CFG6) { 173 const char* expected = 174 "BasicBlock 0, succ: 1\n" 175 " 0: Local [4, 3, 2]\n" 176 " 1: IntConstant [2]\n" 177 " 10: Goto 1\n" 178 "BasicBlock 1, pred: 0, succ: 3, 2\n" 179 " 2: StoreLocal(0, 1)\n" 180 " 3: LoadLocal(0) [5]\n" 181 " 4: LoadLocal(0) [5]\n" 182 " 5: Equal(3, 4) [6]\n" 183 " 6: If(5)\n" 184 "BasicBlock 2, pred: 1, succ: 3\n" 185 " 7: Goto 3\n" 186 "BasicBlock 3, pred: 1, 2, succ: 4\n" 187 " 8: ReturnVoid\n" 188 "BasicBlock 4, pred: 3\n" 189 " 9: Exit\n"; 190 191 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 192 Instruction::CONST_4 | 0 | 0, 193 Instruction::IF_EQ, 3, 194 Instruction::GOTO | 0x100, 195 Instruction::RETURN_VOID); 196 197 TestCode(data, expected); 198} 199 200TEST(PrettyPrinterTest, CFG7) { 201 const char* expected = 202 "BasicBlock 0, succ: 1\n" 203 " 0: Local [4, 3, 2]\n" 204 " 1: IntConstant [2]\n" 205 " 10: Goto 1\n" 206 "BasicBlock 1, pred: 0, succ: 3, 2\n" 207 " 2: StoreLocal(0, 1)\n" 208 " 3: LoadLocal(0) [5]\n" 209 " 4: LoadLocal(0) [5]\n" 210 " 5: Equal(3, 4) [6]\n" 211 " 6: If(5)\n" 212 "BasicBlock 2, pred: 1, 3, succ: 3\n" 213 " 7: Goto 3\n" 214 "BasicBlock 3, pred: 1, 2, succ: 2\n" 215 " 8: Goto 2\n" 216 "BasicBlock 4\n" 217 " 9: Exit\n"; 218 219 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 220 Instruction::CONST_4 | 0 | 0, 221 Instruction::IF_EQ, 3, 222 Instruction::GOTO | 0x100, 223 Instruction::GOTO | 0xFF00); 224 225 TestCode(data, expected); 226} 227 228TEST(PrettyPrinterTest, IntConstant) { 229 const char* expected = 230 "BasicBlock 0, succ: 1\n" 231 " 0: Local [2]\n" 232 " 1: IntConstant [2]\n" 233 " 5: Goto 1\n" 234 "BasicBlock 1, pred: 0, succ: 2\n" 235 " 2: StoreLocal(0, 1)\n" 236 " 3: ReturnVoid\n" 237 "BasicBlock 2, pred: 1\n" 238 " 4: Exit\n"; 239 240 const uint16_t data[] = ONE_REGISTER_CODE_ITEM( 241 Instruction::CONST_4 | 0 | 0, 242 Instruction::RETURN_VOID); 243 244 TestCode(data, expected); 245} 246} // namespace art 247