switch to spaces only..
[IRC.git] / Robust / src / Analysis / Disjoint / EffectsAnalysis.java
1 package Analysis.Disjoint;
2
3 import java.util.*;
4 import java.util.Map.Entry;
5 import java.io.*;
6
7 import IR.*;
8 import IR.Flat.*;
9 import Analysis.Pointer.Edge;
10 import Analysis.Pointer.AllocFactory.AllocNode;
11
12 /////////////////////////////////////////////
13 //
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
19 //  obtained.
20 //
21 //  The effects analysis piggy-backs
22 //  on the disjoint reachability analysis,
23 //  if requested, to support OoOJava and
24 //  potentially other analysis clients.
25 //
26 /////////////////////////////////////////////
27
28 public class EffectsAnalysis {
29
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;
34
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;
39
40   public static State state;
41   public static BuildStateMachines buildStateMachines;
42
43
44   public EffectsAnalysis() {
45     taint2effects = new Hashtable<Taint, Set<Effect>>();
46
47     sese2te      = new Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> >();
48     stallSite2te = new Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> >();
49   }
50
51
52   public Set<Effect> getEffects(Taint t) {
53     Taint tNoPreds = Canonical.changePredsTo(t,
54                                              ReachGraph.predsEmpty
55                                              );
56     return taint2effects.get(tNoPreds);
57   }
58
59   public Iterator iteratorTaintEffectPairs() {
60     return taint2effects.entrySet().iterator();
61   }
62
63   protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
64     Taint tNoPreds = Canonical.changePredsTo(t,
65                                              ReachGraph.predsEmpty
66                                              );
67
68     if( state.RCR ) {
69       buildStateMachines.addToStateMachine(t, e, currentProgramPoint);
70     }
71
72     // add to the global bag
73     Set<Effect> effectSet = taint2effects.get(tNoPreds);
74     if (effectSet == null) {
75       effectSet = new HashSet<Effect>();
76     }
77     effectSet.add(e);
78     taint2effects.put(tNoPreds, effectSet);
79
80     // add to the alternate retrieval bags
81     if( t.getSESE() != null ) {
82       FlatSESEEnterNode sese = t.getSESE();
83
84       Hashtable<Taint, Set<Effect>> te = sese2te.get(sese);
85       if( te == null ) {
86         te = new Hashtable<Taint, Set<Effect>>();
87       }
88
89       Set<Effect> effects = te.get(tNoPreds);
90       if (effects == null) {
91         effects = new HashSet<Effect>();
92       }
93       effects.add(e);
94       te.put(tNoPreds, effects);
95
96       sese2te.put(sese, te);
97
98     } else {
99       assert t.getStallSite() != null;
100       FlatNode stallSite = t.getStallSite();
101
102       Hashtable<Taint, Set<Effect>> te = stallSite2te.get(stallSite);
103       if( te == null ) {
104         te = new Hashtable<Taint, Set<Effect>>();
105       }
106
107       Set<Effect> effects = te.get(tNoPreds);
108       if (effects == null) {
109         effects = new HashSet<Effect>();
110       }
111       effects.add(e);
112       te.put(tNoPreds, effects);
113       stallSite2te.put(stallSite, te);
114     }
115   }
116
117
118   public Hashtable<Taint, Set<Effect>> get(FlatSESEEnterNode sese) {
119     return sese2te.get(sese);
120   }
121
122   public Hashtable<Taint, Set<Effect>> get(FlatNode stallSite) {
123     return stallSite2te.get(stallSite);
124   }
125
126
127
128   public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld, FlatNode currentProgramPoint) {
129
130     VariableNode vn = rg.td2vn.get(rhs);
131     if( vn == null ) {
132       return;
133     }
134
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);
140
141       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
142         Taint taint = taintSetIter.next();
143         add(taint, effect, currentProgramPoint);
144       }
145     }
146   }
147
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);
153
154       if (taintSet!=null)
155         for (Taint taint : taintSet.getTaints()) {
156           add(taint, effect, currentProgramPoint);
157         }
158     }
159   }
160
161   public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, FlatNode currentProgramPoint, boolean strongUpdate) {
162
163     VariableNode vn = rg.td2vn.get(lhs);
164     if( vn == null ) {
165       return;
166     }
167
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);
173       Effect effectSU      = null;
174
175       if (strongUpdate) {
176         effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);
177       }
178
179       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
180         Taint taint = taintSetIter.next();
181         add(taint, effect, currentProgramPoint);
182
183         if (strongUpdate) {
184           add(taint, effectSU, currentProgramPoint);
185         }
186       }
187     }
188   }
189
190
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);
196       if (taintSet!=null)
197         for (Taint taint : taintSet.getTaints()) {
198           add(taint, effect, currentProgramPoint);
199         }
200     }
201   }
202
203
204   public String toString() {
205     return taint2effects.toString();
206   }
207
208   public void writeEffects(String outfile) {
209     try {
210       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
211
212       bw.write("Effects\n---------------\n\n");
213
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();
219
220         Iterator<Effect> eItr = effects.iterator();
221         while( eItr.hasNext() ) {
222           Effect e = eItr.next();
223
224           bw.write(taint+"-->"+e+"\n");
225         }
226       }
227
228       bw.close();
229     } catch( IOException e ) {
230     }
231   }
232
233   /*
234    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
235    * return mapMethodContextToMethodEffects.get(mc); }
236    *
237    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
238    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
239    * MethodEffects meNew = new MethodEffects();
240    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
241    */
242
243   /*
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); }
250    */
251
252   /*
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); }
258    *
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); }
264    *
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); }
270    *
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); }
276    *
277    *
278    * public void writeMethodEffectsResult() throws IOException {
279    *
280    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
281    * "MethodEffects_report.txt"));
282    *
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();
287    *
288    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
289    *
290    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
291    * effectsSet = me.getEffects();
292    *
293    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
294    * md.numParameters() + startIdx; i++) {
295    *
296    * String paramName = md.getParamName(i - startIdx);
297    *
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");
303    *
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; } }
308    *
309    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
310    * keyStr + "\n");
311    *
312    * } bw.write("\n");
313    *
314    * }
315    *
316    * bw.close(); } catch (IOException e) { System.err.println(e); }
317    *
318    * }
319    */
320
321   public Hashtable<Taint, Set<Effect>> getAllEffects() {
322     return taint2effects;
323   }
324 }