1 19 20 25 26 27 package soot.toolkits.graph; 28 29 30 31 import soot.*; 32 import soot.util.*; 33 import java.util.*; 34 35 import soot.options.Options; 36 37 38 48 49 public abstract class UnitGraph implements DirectedGraph 50 { 51 List heads; 52 List tails; 53 54 protected Map unitToSuccs; 55 protected Map unitToPreds; 56 protected SootMethod method; 57 protected Body body; 58 protected Chain unitChain; 59 60 67 protected UnitGraph( Body body) { 68 this.body = body; 69 unitChain = body.getUnits(); 70 method = body.getMethod(); 71 if(Options.v().verbose()) 72 G.v().out.println("[" + method.getName() + "] Constructing " + 73 this.getClass().getName() + "..."); 74 75 } 76 77 78 96 protected void buildUnexceptionalEdges(Map unitToSuccs, Map unitToPreds) { 97 98 for (Iterator unitIt = unitChain.iterator(); unitIt.hasNext(); ) { 100 unitToPreds.put(unitIt.next(), new ArrayList()); 101 } 102 103 Iterator unitIt = unitChain.iterator(); 104 Unit currentUnit, nextUnit; 105 106 nextUnit = unitIt.hasNext() ? (Unit) unitIt.next(): null; 107 108 while(nextUnit != null) { 109 currentUnit = nextUnit; 110 nextUnit = unitIt.hasNext() ? (Unit) unitIt.next(): null; 111 112 List successors = new ArrayList(); 113 114 if( currentUnit.fallsThrough() ) { 115 if(nextUnit != null) { 117 successors.add(nextUnit); 118 ((List) unitToPreds.get(nextUnit)).add(currentUnit); 119 } 120 } 121 122 if( currentUnit.branches() ) { 123 for (Iterator targetIt = currentUnit.getUnitBoxes().iterator(); 124 targetIt.hasNext(); ) { 125 Unit target = ((UnitBox) targetIt.next()).getUnit(); 126 if (! successors.contains(target)) { 129 successors.add(target); 130 ((List) unitToPreds.get(target)).add(currentUnit); 131 } 132 } 133 } 134 135 unitToSuccs.put(currentUnit, successors); 137 } 138 } 139 140 141 155 protected void buildHeadsAndTails() { 156 List tailList = new ArrayList(); 157 List headList = new ArrayList(); 158 159 for (Iterator unitIt = unitChain.iterator(); unitIt.hasNext(); ) { 160 Unit s = (Unit) unitIt.next(); 161 List succs = (List) unitToSuccs.get(s); 162 if(succs.size() == 0) { 163 tailList.add(s); 164 } 165 List preds = (List) unitToPreds.get(s); 166 if(preds.size() == 0) { 167 headList.add(s); 168 } 169 } 170 171 Unit entryPoint = (Unit) unitChain.getFirst(); 174 if (! headList.contains(entryPoint)) { 175 headList.add(entryPoint); 176 } 177 178 tails = Collections.unmodifiableList(tailList); 179 heads = Collections.unmodifiableList(headList); 180 } 181 182 183 190 protected static void makeMappedListsUnmodifiable(Map map) { 191 for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { 192 Map.Entry entry = (Map.Entry) it.next(); 193 List value = (List) entry.getValue(); 194 if (value.size() == 0) { 195 entry.setValue(Collections.EMPTY_LIST); 196 } else { 197 entry.setValue(Collections.unmodifiableList(value)); 198 } 199 } 200 } 201 202 203 216 protected Map combineMapValues(Map mapA, Map mapB) { 217 Map result = new HashMap(mapA.size() * 2 + 1, 0.7f); 219 for (Iterator chainIt = unitChain.iterator(); chainIt.hasNext(); ) { 220 Unit unit = (Unit) chainIt.next(); 221 List listA = (List) mapA.get(unit); 222 if (listA == null) { 223 listA = Collections.EMPTY_LIST; 224 } 225 List listB = (List) mapB.get(unit); 226 if (listB == null) { 227 listB = Collections.EMPTY_LIST; 228 } 229 230 int resultSize = listA.size() + listB.size(); 231 if (resultSize == 0) { 232 result.put(unit, Collections.EMPTY_LIST); 233 } else { 234 List resultList = new ArrayList(resultSize); 235 Iterator listIt = null; 236 if (listA.size() >= listB.size()) { 239 resultList.addAll(listA); 240 listIt = listB.iterator(); 241 } else { 242 resultList.addAll(listB); 243 listIt = listA.iterator(); 244 } 245 while (listIt.hasNext()) { 246 Object element = listIt.next(); 247 if (! resultList.contains(element)) { 255 resultList.add(element); 256 } 257 } 258 result.put(unit, Collections.unmodifiableList(resultList)); 259 } 260 } 261 return result; 262 } 263 264 265 278 protected void addEdge(Map unitToSuccs, Map unitToPreds, 279 Unit head, Unit tail) { 280 List headsSuccs = (List) unitToSuccs.get(head); 281 if (headsSuccs == null) { 282 headsSuccs = new ArrayList(3); unitToSuccs.put(head, headsSuccs); 285 } 286 if (! headsSuccs.contains(tail)) { 287 headsSuccs.add(tail); 288 List tailsPreds = (List) unitToPreds.get(tail); 289 if (tailsPreds == null) { 290 tailsPreds = new ArrayList(); 291 unitToPreds.put(tail, tailsPreds); 292 } 293 tailsPreds.add(head); 294 } 295 } 296 297 298 303 public Body getBody() 304 { 305 return body; 306 } 307 308 309 310 320 public List getExtendedBasicBlockPathBetween(Unit from, Unit to) 321 { 322 UnitGraph g = this; 323 324 if (g.getPredsOf(to).size() > 1) 326 return null; 327 328 LinkedList pathStack = new LinkedList(); 331 LinkedList pathStackIndex = new LinkedList(); 332 333 pathStack.add(from); 334 pathStackIndex.add(new Integer (0)); 335 336 int psiMax = (g.getSuccsOf((Unit)pathStack.get(0))).size(); 337 int level = 0; 338 while (((Integer )pathStackIndex.get(0)).intValue() != psiMax) 339 { 340 int p = ((Integer )(pathStackIndex.get(level))).intValue(); 341 342 List succs = g.getSuccsOf((Unit)(pathStack.get(level))); 343 if (p >= succs.size()) 344 { 345 347 pathStack.remove(level); 348 pathStackIndex.remove(level); 349 350 level--; 351 int q = ((Integer )pathStackIndex.get(level)).intValue(); 352 pathStackIndex.set(level, new Integer (q+1)); 353 continue; 354 } 355 356 Unit betweenUnit = (Unit)(succs.get(p)); 357 358 if (betweenUnit == to) 360 { 361 pathStack.add(to); 362 return pathStack; 363 } 364 365 if (g.getPredsOf(betweenUnit).size() > 1) 367 { 368 pathStackIndex.set(level, new Integer (p+1)); 369 continue; 370 } 371 372 level++; 374 pathStackIndex.add(new Integer (0)); 375 pathStack.add(betweenUnit); 376 } 377 return null; 378 } 379 380 381 382 public List getHeads() 383 { 384 return heads; 385 } 386 387 public List getTails() 388 { 389 return tails; 390 } 391 392 public List getPredsOf(Object u) 393 { 394 if(!unitToPreds.containsKey(u)) 395 throw new NoSuchElementException("Invalid unit " + u); 396 397 return (List) unitToPreds.get(u); 398 } 399 400 public List getSuccsOf(Object u) 401 { 402 if(!unitToSuccs.containsKey(u)) 403 throw new NoSuchElementException("Invalid unit " + u); 404 405 return (List) unitToSuccs.get(u); 406 } 407 408 public int size() 409 { 410 return unitChain.size(); 411 } 412 413 public Iterator iterator() 414 { 415 return unitChain.iterator(); 416 } 417 418 public String toString() 419 { 420 Iterator it = unitChain.iterator(); 421 StringBuffer buf = new StringBuffer (); 422 while(it.hasNext()) { 423 Unit u = (Unit) it.next(); 424 buf.append("// preds: "+getPredsOf(u)+"\n"); 425 buf.append(u.toString() + '\n'); 426 buf.append("// succs "+getSuccsOf(u)+"\n"); 427 } 428 return buf.toString(); 429 } 430 } 431 | Popular Tags |