1 package Analysis.Disjoint;
4 import java.util.Map.Entry;
9 import Analysis.Pointer.Edge;
10 import Analysis.Pointer.AllocFactory.AllocNode;
12 /////////////////////////////////////////////
14 // Effects analysis computes read/write/strong
15 // update and other sorts of effects for the
16 // scope of a method or rblock. The effects
17 // are associated with the heap roots through
18 // which a reference to the effect target was
21 // The effects analysis piggy-backs
22 // on the disjoint reachability analysis,
23 // if requested, to support OoOJava and
24 // potentially other analysis clients.
26 /////////////////////////////////////////////
28 public class EffectsAnalysis {
30 // the effects analysis should combine taints
31 // that match except for predicates--preds just
32 // support interprocedural analysis
33 private Hashtable<Taint, Set<Effect>> taint2effects;
35 // redundant views of the effect set for
36 // efficient retrieval
37 private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
38 private Hashtable<FlatNode, Hashtable<Taint, Set<Effect>> > stallSite2te;
40 public static State state;
41 public static BuildStateMachines buildStateMachines;
44 public EffectsAnalysis() {
45 taint2effects = new Hashtable<Taint, Set<Effect>>();
47 sese2te = new Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> >();
48 stallSite2te = new Hashtable<FlatNode, Hashtable<Taint, Set<Effect>> >();
52 public Set<Effect> getEffects(Taint t) {
53 Taint tNoPreds = Canonical.changePredsTo(t,
56 return taint2effects.get(tNoPreds);
59 public Iterator iteratorTaintEffectPairs() {
60 return taint2effects.entrySet().iterator();
63 protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
64 Taint tNoPreds = Canonical.changePredsTo(t,
69 buildStateMachines.addToStateMachine(t, e, currentProgramPoint);
72 // add to the global bag
73 Set<Effect> effectSet = taint2effects.get(tNoPreds);
74 if (effectSet == null) {
75 effectSet = new HashSet<Effect>();
78 taint2effects.put(tNoPreds, effectSet);
80 // add to the alternate retrieval bags
81 if( t.getSESE() != null ) {
82 FlatSESEEnterNode sese = t.getSESE();
84 Hashtable<Taint, Set<Effect>> te = sese2te.get(sese);
86 te = new Hashtable<Taint, Set<Effect>>();
89 Set<Effect> effects = te.get(tNoPreds);
90 if (effects == null) {
91 effects = new HashSet<Effect>();
94 te.put(tNoPreds, effects);
96 sese2te.put(sese, te);
99 assert t.getStallSite() != null;
100 FlatNode stallSite = t.getStallSite();
102 Hashtable<Taint, Set<Effect>> te = stallSite2te.get(stallSite);
104 te = new Hashtable<Taint, Set<Effect>>();
107 Set<Effect> effects = te.get(tNoPreds);
108 if (effects == null) {
109 effects = new HashSet<Effect>();
112 te.put(tNoPreds, effects);
113 stallSite2te.put(stallSite, te);
118 public Hashtable<Taint, Set<Effect>> get(FlatSESEEnterNode sese) {
119 return sese2te.get(sese);
122 public Hashtable<Taint, Set<Effect>> get(FlatNode stallSite) {
123 return stallSite2te.get(stallSite);
128 public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld, FlatNode currentProgramPoint) {
130 VariableNode vn = rg.td2vn.get(rhs);
135 for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext(); ) {
136 RefEdge edge = iterator.next();
137 TaintSet taintSet = edge.getTaints();
138 AllocSite affectedAlloc = edge.getDst().getAllocSite();
139 Effect effect = new Effect(affectedAlloc, Effect.read, fld, currentProgramPoint);
141 for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
142 Taint taint = taintSetIter.next();
143 add(taint, effect, currentProgramPoint);
148 public void analyzeFlatFieldNode(Set<Edge> sources, FieldDescriptor fld, FlatNode currentProgramPoint) {
149 for (Edge edge:sources) {
150 TaintSet taintSet = edge.getTaints();
151 Alloc affectedAlloc = edge.getDst().getAllocSite();
152 Effect effect = new Effect(affectedAlloc, Effect.read, fld, currentProgramPoint);
155 for (Taint taint : taintSet.getTaints()) {
156 add(taint, effect, currentProgramPoint);
161 public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, FlatNode currentProgramPoint, boolean strongUpdate) {
163 VariableNode vn = rg.td2vn.get(lhs);
168 for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext(); ) {
169 RefEdge edge = iterator.next();
170 TaintSet taintSet = edge.getTaints();
171 AllocSite affectedAlloc = edge.getDst().getAllocSite();
172 Effect effect = new Effect(affectedAlloc, Effect.write, fld, currentProgramPoint);
173 Effect effectSU = null;
176 effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld, currentProgramPoint);
179 for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
180 Taint taint = taintSetIter.next();
181 add(taint, effect, currentProgramPoint);
184 add(taint, effectSU, currentProgramPoint);
191 public void analyzeFlatSetFieldNode(Set<Edge> dstedges, FieldDescriptor fld, FlatNode currentProgramPoint) {
192 for (Edge edge : dstedges) {
193 TaintSet taintSet = edge.getTaints();
194 Alloc affectedAlloc = edge.getDst().getAllocSite();
195 Effect effect = new Effect(affectedAlloc, Effect.write, fld, currentProgramPoint);
197 for (Taint taint : taintSet.getTaints()) {
198 add(taint, effect, currentProgramPoint);
204 public String toString() {
205 return taint2effects.toString();
208 public void writeEffects(String outfile) {
210 BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
212 bw.write("Effects\n---------------\n\n");
214 Iterator meItr = taint2effects.entrySet().iterator();
215 while( meItr.hasNext() ) {
216 Map.Entry me = (Map.Entry)meItr.next();
217 Taint taint = (Taint) me.getKey();
218 Set<Effect> effects = (Set<Effect>)me.getValue();
220 Iterator<Effect> eItr = effects.iterator();
221 while( eItr.hasNext() ) {
222 Effect e = eItr.next();
224 bw.write(taint+"-->"+e+"\n");
229 } catch( IOException e ) {
234 * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
235 * return mapMethodContextToMethodEffects.get(mc); }
237 * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
238 * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
239 * MethodEffects meNew = new MethodEffects();
240 * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
244 * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
245 * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
246 * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
247 * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
248 * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
249 * mapMethodContextToMethodEffects.put(callerMC, me); }
253 * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
254 * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
255 * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
256 * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
257 * mapMethodContextToMethodEffects.put(mc, me); }
259 * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
260 * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
261 * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
262 * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
263 * mapMethodContextToMethodEffects.put(mc, me); }
265 * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
266 * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
267 * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
268 * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
269 * mapMethodContextToMethodEffects.put(mc, me); }
271 * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
272 * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
273 * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
274 * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
275 * mapMethodContextToMethodEffects.put(mc, me); }
278 * public void writeMethodEffectsResult() throws IOException {
280 * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
281 * "MethodEffects_report.txt"));
283 * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
284 * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
285 * { MethodContext mc = mcIter.next(); MethodDescriptor md =
286 * (MethodDescriptor) mc.getDescriptor();
288 * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
290 * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
291 * effectsSet = me.getEffects();
293 * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
294 * md.numParameters() + startIdx; i++) {
296 * String paramName = md.getParamName(i - startIdx);
298 * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
299 * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
300 * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
301 * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
302 * bw.write(" Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
304 * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
305 * (effectSet != null) { Iterator<EffectsKey> effectIter =
306 * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
307 * effectIter.next(); keyStr += " " + key; } }
309 * keyStr += " }"; bw.write(" Paramter " + paramName + " WritingngSet=" +
316 * bw.close(); } catch (IOException e) { System.err.println(e); }
321 public Hashtable<Taint, Set<Effect>> getAllEffects() {
322 return taint2effects;