1 19 20 25 26 27 42 43 44 package soot.toolkits.scalar; 45 46 import soot.*; 47 import soot.toolkits.graph.*; 48 import soot.util.*; 49 import java.util.*; 50 import soot.toolkits.graph.interaction.*; 51 import soot.options.*; 52 53 54 public abstract class ForwardBranchedFlowAnalysis extends BranchedFlowAnalysis 55 { 56 public ForwardBranchedFlowAnalysis(UnitGraph graph) 57 { 58 super(graph); 59 } 60 61 protected boolean isForward() 62 { 63 return true; 64 } 65 66 private void accumulateAfterFlowSets(Unit s, Object [] flowRepositories, List previousAfterFlows) 68 { 69 int repCount = 0; 70 71 previousAfterFlows.clear(); 72 if (s.fallsThrough()) 73 { 74 copy(((List) unitToAfterFallFlow.get(s)).get(0), flowRepositories[repCount]); 75 previousAfterFlows.add(flowRepositories[repCount++]); 76 } 77 78 if (s.branches()) 79 { 80 List l = (List)(unitToAfterBranchFlow.get(s)); 81 Iterator it = l.iterator(); 82 83 while (it.hasNext()) 84 { 85 Object fs = (Object ) (it.next()); 86 copy(fs, flowRepositories[repCount]); 87 previousAfterFlows.add(flowRepositories[repCount++]); 88 } 89 } 90 } 92 93 protected void doAnalysis() 94 { 95 final Map numbers = new HashMap(); 96 List orderedUnits = new PseudoTopologicalOrderer().newList(graph); 97 { 98 int i = 1; 99 for( Iterator uIt = orderedUnits.iterator(); uIt.hasNext(); ) { 100 final Unit u = (Unit) uIt.next(); 101 numbers.put(u, new Integer (i)); 102 i++; 103 } 104 } 105 106 TreeSet changedUnits = new TreeSet( new Comparator() { 107 public int compare(Object o1, Object o2) { 108 Integer i1 = (Integer ) numbers.get(o1); 109 Integer i2 = (Integer ) numbers.get(o2); 110 return (i1.intValue() - i2.intValue()); 111 } 112 } ); 113 114 Map unitToIncomingFlowSets = new HashMap(graph.size() * 2 + 1, 0.7f); 115 List heads = graph.getHeads(); 116 int numNodes = graph.size(); 117 int numComputations = 0; 118 int maxBranchSize = 0; 119 120 { 122 Iterator it = graph.iterator(); 123 124 while (it.hasNext()) 125 { 126 Unit s = (Unit) it.next(); 127 128 unitToIncomingFlowSets.put(s, new ArrayList()); 129 } 130 } 131 132 { 135 Chain sl = ((UnitGraph)graph).getBody().getUnits(); 136 Iterator it = graph.iterator(); 137 138 while(it.hasNext()) 139 { 140 Unit s = (Unit) it.next(); 141 142 changedUnits.add(s); 143 144 unitToBeforeFlow.put(s, newInitialFlow()); 145 146 if (s.fallsThrough()) 147 { 148 ArrayList fl = new ArrayList(); 149 150 fl.add((Object ) (newInitialFlow())); 151 unitToAfterFallFlow.put(s, fl); 152 153 Unit succ=(Unit) sl.getSuccOf(s); 154 if(succ!=null) { 157 List l = (List) 158 (unitToIncomingFlowSets.get(sl.getSuccOf(s))); 159 l.addAll(fl); 160 } 161 } 162 else 163 unitToAfterFallFlow.put(s, new ArrayList()); 164 165 if (s.branches()) 166 { 167 ArrayList l = new ArrayList(); 168 List incList; 169 Iterator boxIt = s.getUnitBoxes().iterator(); 170 171 while (boxIt.hasNext()) 172 { 173 Object f = (Object ) (newInitialFlow()); 174 175 l.add(f); 176 Unit ss = ((UnitBox) (boxIt.next())).getUnit(); 177 incList = (List) (unitToIncomingFlowSets.get(ss)); 178 179 incList.add(f); 180 } 181 unitToAfterBranchFlow.put(s, l); 182 } 183 else 184 unitToAfterBranchFlow.put(s, new ArrayList()); 185 186 if (s.getUnitBoxes().size() > maxBranchSize) 187 maxBranchSize = s.getUnitBoxes().size(); 188 } 189 } 190 191 { 194 Iterator it = heads.iterator(); 195 196 while (it.hasNext()) { 197 Object s = it.next(); 198 unitToBeforeFlow.put(s, entryInitialFlow()); 200 } 201 } 202 203 if (treatTrapHandlersAsEntries()) 204 { 205 Iterator trapIt = ((UnitGraph)graph).getBody(). 206 getTraps().iterator(); 207 while(trapIt.hasNext()) { 208 Trap trap = (Trap) trapIt.next(); 209 Unit handler = trap.getHandlerUnit(); 210 unitToBeforeFlow.put(handler, entryInitialFlow()); 211 } 212 } 213 214 { 216 List previousAfterFlows = new ArrayList(); 217 List afterFlows = new ArrayList(); 218 Object [] flowRepositories = new Object [maxBranchSize+1]; 219 for (int i = 0; i < maxBranchSize+1; i++) 220 flowRepositories[i] = (Object ) newInitialFlow(); 221 Object [] previousFlowRepositories = new Object [maxBranchSize+1]; 222 for (int i = 0; i < maxBranchSize+1; i++) 223 previousFlowRepositories[i] = (Object ) newInitialFlow(); 224 225 while(!changedUnits.isEmpty()) 226 { 227 Object beforeFlow; 228 229 Unit s = (Unit) changedUnits.first(); 230 changedUnits.remove(s); 231 boolean isHead = heads.contains(s); 232 233 accumulateAfterFlowSets(s, previousFlowRepositories, previousAfterFlows); 234 235 { 237 List preds = (List) (unitToIncomingFlowSets.get(s)); 238 239 beforeFlow = unitToBeforeFlow.get(s); 240 241 if(preds.size() == 1) 242 copy(preds.get(0), beforeFlow); 243 else if(preds.size() != 0) 244 { 245 Iterator predIt = preds.iterator(); 246 247 copy(predIt.next(), beforeFlow); 248 249 while(predIt.hasNext()) 250 { 251 Object otherBranchFlow = predIt.next(); 252 Object newBeforeFlow = newInitialFlow(); 253 merge(beforeFlow, otherBranchFlow, newBeforeFlow); 254 copy(newBeforeFlow, beforeFlow); 255 } 256 } 257 258 if(isHead && preds.size() != 0) 259 merge(beforeFlow, entryInitialFlow()); 260 } 261 262 { 264 Object afterFallFlow = unitToAfterFallFlow.get(s); 265 Object afterBranchFlow = unitToAfterBranchFlow.get(s); 266 if (Options.v().interactive_mode()){ 267 Object savedFlow = newInitialFlow(); 268 copy(beforeFlow, savedFlow); 269 FlowInfo fi = new FlowInfo(savedFlow, s, true); 270 if (InteractionHandler.v().getStopUnitList() != null && InteractionHandler.v().getStopUnitList().contains(s)){ 271 InteractionHandler.v().handleStopAtNodeEvent(s); 272 } 273 InteractionHandler.v().handleBeforeAnalysisEvent(fi); 274 } 275 flowThrough(beforeFlow, s, (List) afterFallFlow, (List) afterBranchFlow); 276 if (Options.v().interactive_mode()){ 277 ArrayList l = new ArrayList(); 278 if (!((List)afterFallFlow).isEmpty()){ 279 l.addAll((List)afterFallFlow); 280 } 281 if (!((List)afterBranchFlow).isEmpty()){ 282 l.addAll((List)afterBranchFlow); 283 } 284 285 292 FlowInfo fi = new FlowInfo(l, s, false); 293 InteractionHandler.v().handleAfterAnalysisEvent(fi); 294 } 295 numComputations++; 296 } 297 298 accumulateAfterFlowSets(s, flowRepositories, afterFlows); 299 300 if(!afterFlows.equals(previousAfterFlows)) 302 { 303 Iterator succIt = graph.getSuccsOf(s).iterator(); 304 305 while(succIt.hasNext()) 306 { 307 Unit succ = (Unit) succIt.next(); 308 309 changedUnits.add(succ); 310 } 311 } 312 } 313 } 314 315 318 Timers.v().totalFlowNodes += numNodes; 319 Timers.v().totalFlowComputations += numComputations; 320 321 } 323 } | Popular Tags |