1 19 20 25 26 27 package soot.toolkits.graph; 28 29 import java.util.*; 30 31 import soot.*; 32 import soot.util.Chain; 33 34 35 50 public abstract class BlockGraph implements DirectedGraph 51 { 52 Body mBody; 53 Chain mUnits; 54 List mBlocks; 55 List mHeads = new ArrayList(); 56 List mTails = new ArrayList(); 57 58 59 67 protected BlockGraph(UnitGraph unitGraph) 68 { 69 mBody = unitGraph.getBody(); 70 mUnits = mBody.getUnits(); 71 Set leaders = computeLeaders(unitGraph); 72 buildBlocks(leaders, unitGraph); 73 } 74 75 76 119 protected Set computeLeaders(UnitGraph unitGraph) { 120 Body body = unitGraph.getBody(); 121 if (body != mBody) { 122 throw new RuntimeException ("BlockGraph.computeLeaders() called with a UnitGraph that doesn't match its mBody."); 123 } 124 Set leaders = new HashSet(); 125 126 Chain traps = body.getTraps(); 129 for (Iterator trapIt = traps.iterator(); trapIt.hasNext(); ) { 130 Trap trap = (Trap) trapIt.next(); 131 leaders.add(trap.getHandlerUnit()); 132 } 133 134 for (Iterator unitIt = body.getUnits().iterator(); unitIt.hasNext(); ) { 135 Unit u = (Unit) unitIt.next(); 136 List predecessors = unitGraph.getPredsOf(u); 137 int predCount = predecessors.size(); 138 List successors = unitGraph.getSuccsOf(u); 139 int succCount = successors.size(); 140 141 if (predCount != 1) { leaders.add(u); } if ((succCount > 1) || (u.branches())) { 145 for (Iterator it = successors.iterator(); it.hasNext(); ) { 146 leaders.add((Unit) it.next()); } } 149 } 150 return leaders; 151 } 152 153 154 180 protected Map buildBlocks(Set leaders, UnitGraph unitGraph) { 181 List blockList = new ArrayList(leaders.size()); 182 Map unitToBlock = new HashMap(); Unit blockHead = null; 186 int blockLength = 0; 187 Iterator unitIt = mUnits.iterator(); 188 if (unitIt.hasNext()) { 189 blockHead = (Unit) unitIt.next(); 190 if (! leaders.contains(blockHead)) { 191 throw new RuntimeException ("BlockGraph: first unit not a leader!"); 192 } 193 blockLength++; 194 } 195 Unit blockTail = blockHead; 196 int indexInMethod = 0; 197 198 while (unitIt.hasNext()) { 199 Unit u = (Unit) unitIt.next(); 200 if (leaders.contains(u)) { 201 addBlock(blockHead, blockTail, indexInMethod, blockLength, 202 blockList, unitToBlock); 203 indexInMethod++; 204 blockHead = u; 205 blockLength = 0; 206 } 207 blockTail = u; 208 blockLength++; 209 } 210 if (blockLength > 0) { 211 addBlock(blockHead, blockTail, indexInMethod, blockLength, 213 blockList, unitToBlock); 214 } 215 216 for (Iterator it = unitGraph.getHeads().iterator(); it.hasNext(); ) { 218 Unit headUnit = (Unit) it.next(); 219 Block headBlock = (Block) unitToBlock.get(headUnit); 220 if (headBlock.getHead() == headUnit) { 221 mHeads.add(headBlock); 222 } else { 223 throw new RuntimeException ("BlockGraph(): head Unit is not the first unit in the corresponding Block!"); 224 } 225 } 226 for (Iterator it = unitGraph.getTails().iterator(); it.hasNext(); ) { 227 Unit tailUnit = (Unit) it.next(); 228 Block tailBlock = (Block) unitToBlock.get(tailUnit); 229 if (tailBlock.getTail() == tailUnit) { 230 mTails.add(tailBlock); 231 } else { 232 throw new RuntimeException ("BlockGraph(): tail Unit is not the last unit in the corresponding Block!"); 233 } 234 } 235 236 for (Iterator blockIt = blockList.iterator(); blockIt.hasNext(); ) { 237 Block block = (Block) blockIt.next(); 238 239 List predUnits = unitGraph.getPredsOf(block.getHead()); 240 List predBlocks = new ArrayList(predUnits.size()); 241 for (Iterator predIt = predUnits.iterator(); predIt.hasNext(); ) { 242 Unit predUnit = (Unit) predIt.next(); 243 Block predBlock = (Block) unitToBlock.get(predUnit); 244 if (predBlock == null) { 245 throw new RuntimeException ("BlockGraph(): block head mapped to null block!"); 246 } 247 predBlocks.add(predBlock); 248 } 249 250 if (predBlocks.size() == 0) { 251 block.setPreds(Collections.EMPTY_LIST); 252 253 264 } else { 265 block.setPreds(Collections.unmodifiableList(predBlocks)); 266 if (block.getHead() == mUnits.getFirst()) { 267 mHeads.add(block); } 270 } 271 272 List succUnits = unitGraph.getSuccsOf(block.getTail()); 273 List succBlocks = new ArrayList(succUnits.size()); 274 for (Iterator succIt = succUnits.iterator(); succIt.hasNext(); ) { 275 Unit succUnit = (Unit) succIt.next(); 276 Block succBlock = (Block) unitToBlock.get(succUnit); 277 if (succBlock == null) { 278 throw new RuntimeException ("BlockGraph(): block tail mapped to null block!"); 279 } 280 succBlocks.add(succBlock); 281 } 282 if (succBlocks.size() == 0) { 283 block.setSuccs(Collections.EMPTY_LIST); 284 if (! mTails.contains(block)) { 285 throw new RuntimeException ("Block with no successors is not a tail!: " + block.toString()); 286 } 289 } else { 290 block.setSuccs(Collections.unmodifiableList(succBlocks)); 291 } 292 } 293 mBlocks = Collections.unmodifiableList(blockList); 294 mHeads = Collections.unmodifiableList(mHeads); 295 if (mTails.size() == 0) { 296 mTails = Collections.EMPTY_LIST; 297 } else { 298 mTails = Collections.unmodifiableList(mTails); 299 } 300 return unitToBlock; 301 } 302 303 317 private void addBlock(Unit head, Unit tail, int index, int length, 318 List blockList, Map unitToBlock) { 319 Block block = new Block(head, tail, mBody, index, length, this); 320 blockList.add(block); 321 unitToBlock.put(tail, block); 322 unitToBlock.put(head, block); 323 } 324 325 329 public Body getBody() 330 { 331 return mBody; 332 } 333 334 341 public List getBlocks() 342 { 343 return mBlocks; 344 } 345 346 347 public String toString() { 348 349 Iterator it = mBlocks.iterator(); 350 StringBuffer buf = new StringBuffer (); 351 while(it.hasNext()) { 352 Block someBlock = (Block) it.next(); 353 354 buf.append(someBlock.toString() + '\n'); 355 } 356 357 return buf.toString(); 358 } 359 360 361 public List getHeads() 362 { 363 return mHeads; 364 } 365 366 public List getTails() 367 { 368 return mTails; 369 } 370 371 public List getPredsOf(Object o) 372 { 373 Block b = (Block) o; 374 return b.getPreds(); 375 } 376 377 public List getSuccsOf(Object o) 378 { 379 Block b = (Block) o; 380 return b.getSuccs(); 381 } 382 383 public int size() 384 { 385 return mBlocks.size(); 386 } 387 388 public Iterator iterator() 389 { 390 return mBlocks.iterator(); 391 } 392 } 393 | Popular Tags |