getting close to effects for new disjoint analysis
[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.FieldDescriptor;
8 import IR.Flat.FlatCall;
9 import IR.Flat.FlatMethod;
10 import IR.Flat.FlatNode;
11 import IR.Flat.TempDescriptor;
12 import IR.Flat.FlatSESEEnterNode;
13
14 /////////////////////////////////////////////
15 // 
16 //  Effects analysis computes read/write/strong
17 //  update and other sorts of effects for the
18 //  scope of a method or rblock.  The effects
19 //  are associated with the heap roots through
20 //  which a reference to the effect target was
21 //  obtained.
22 //
23 //  The effects analysis piggy-backs
24 //  on the disjoint reachability analysis,
25 //  if requested, to support OoOJava and
26 //  potentially other analysis clients.
27 //
28 /////////////////////////////////////////////
29
30 public class EffectsAnalysis {
31
32   // the effects analysis should combine taints
33   // that match except for predicates--preds just
34   // support interprocedural analysis
35   private Hashtable<Taint, Set<Effect>> taint2effects;
36
37   // redundant views of the effect set for
38   // efficient retrieval
39   private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
40   private Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> > stallSite2te;
41
42
43   public EffectsAnalysis() {
44     taint2effects = new Hashtable<Taint, Set<Effect>>();
45
46     sese2te      = new Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> >();
47     stallSite2te = new Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> >();
48   }
49
50
51   public Set<Effect> getEffects(Taint t) {
52     Taint tNoPreds = Canonical.changePredsTo( t,
53                                               ReachGraph.predsEmpty
54                                               );
55     return taint2effects.get(tNoPreds);
56   }
57
58   public Iterator iteratorTaintEffectPairs() {
59     return taint2effects.entrySet().iterator();
60   }
61
62   /*
63   public Hashtable<Taint, Set<Effect>> getSESEEffects(FlatSESEEnterNode sese){
64     
65     Hashtable<Taint, Set<Effect>> taint2Effects = new Hashtable<Taint, Set<Effect>>();
66     Iterator iter=iteratorTaintEffectPairs();
67     while (iter.hasNext()) {
68       Entry entry = (Entry) iter.next();
69       Taint taint = (Taint) entry.getKey();
70       Set<Effect> effects = (Set<Effect>) entry.getValue();
71       if (taint.getSESE().equals(sese)) {
72         Iterator<Effect> eIter = effects.iterator();
73         while (eIter.hasNext()) {
74           Effect effect = eIter.next();
75           if (taint.getSESE().equals(sese)) {
76             Set<Effect> effectSet = taint2Effects.get(taint);
77             if (effectSet == null) {
78               effectSet = new HashSet<Effect>();
79             }
80             effectSet.add(effect);
81             taint2Effects.put(taint, effectSet);
82           }
83         }
84       }
85     }
86     
87     return taint2Effects;
88     
89   }
90   */
91
92   public Hashtable<Taint, Set<Effect>> getStallSiteEffects(FlatNode fn, TempDescriptor td){
93     
94     Hashtable<Taint, Set<Effect>> taint2Effects = new Hashtable<Taint, Set<Effect>>();
95     Iterator iter=iteratorTaintEffectPairs();
96     while(iter.hasNext()){
97       Entry entry=(Entry)iter.next();
98       Taint taint=(Taint)entry.getKey();
99       Set<Effect> effects=(Set<Effect>)entry.getValue();
100       if(taint.getStallSite().equals(fn)){
101         Iterator<Effect> eIter=effects.iterator();        
102         while (eIter.hasNext()) {
103           Effect effect = eIter.next();
104           if( taint.getStallSite().equals(fn) && taint.getVar().equals(td) ){
105             Set<Effect> effectSet=taint2Effects.get(taint);
106             if(effectSet==null){
107               effectSet=new HashSet<Effect>();
108             }
109             effectSet.add(effect);
110             taint2Effects.put(taint, effectSet);
111           }
112         }
113       }
114     }
115     return taint2Effects; 
116   }
117
118
119   protected void add(Taint t, Effect e) {
120     if( t.getSESE() != null &&
121         t.getSESE().getIsCallerSESEplaceholder() ) {
122       return;
123     }
124
125     Taint tNoPreds = Canonical.changePredsTo( t,
126                                               ReachGraph.predsEmpty
127                                               );
128
129     // add to the global bag
130     Set<Effect> effectSet = taint2effects.get(tNoPreds);
131     if (effectSet == null) {
132       effectSet = new HashSet<Effect>();
133     }
134     effectSet.add(e);
135     taint2effects.put(tNoPreds, effectSet);
136
137     // add to the alternate retrieval bags
138     if( t.getSESE() != null ) {
139       FlatSESEEnterNode sese = t.getSESE();
140
141       Hashtable<Taint, Set<Effect>> te = sese2te.get( sese );
142       if( te == null ) {
143         te = new Hashtable<Taint, Set<Effect>>();
144       }
145
146       Set<Effect> effects = te.get(tNoPreds);
147       if (effects == null) {
148         effects = new HashSet<Effect>();
149       }
150       effects.add(e);
151       te.put(tNoPreds, effects);
152
153       sese2te.put(sese, te);
154
155     } else {
156       assert t.getStallSite() != null;
157       FlatNode stallSite = t.getStallSite();
158
159       Hashtable<Taint, Set<Effect>> te = stallSite2te.get( stallSite );
160       if( te == null ) {
161         te = new Hashtable<Taint, Set<Effect>>();
162       }
163
164       Set<Effect> effects = te.get(tNoPreds);
165       if (effects == null) {
166         effects = new HashSet<Effect>();
167       }
168       effects.add(e);
169       te.put(tNoPreds, effects);
170
171       stallSite2te.put(stallSite, te);
172     }    
173   }
174
175
176   public Hashtable<Taint, Set<Effect>> get( FlatSESEEnterNode sese ) {
177     return sese2te.get(sese);
178   }
179
180   public Hashtable<Taint, Set<Effect>> get( FlatNode stallSite ) {
181     return stallSite2te.get(stallSite);
182   }
183
184
185
186   public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
187
188     VariableNode vn = rg.td2vn.get(rhs);
189     if( vn == null ) {
190       return;
191     }
192
193     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
194       RefEdge   edge          = iterator.next();
195       TaintSet  taintSet      = edge.getTaints();
196       AllocSite affectedAlloc = edge.getDst().getAllocSite();
197       Effect    effect        = new Effect(affectedAlloc, Effect.read, fld);
198
199       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
200         Taint taint = taintSetIter.next();        
201         add(taint, effect);
202       }
203     }
204   }
205
206   public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
207
208     VariableNode vn = rg.td2vn.get(lhs);
209     if( vn == null ) {
210       return;
211     }
212
213     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
214       RefEdge   edge          = iterator.next();
215       TaintSet  taintSet      = edge.getTaints();
216       AllocSite affectedAlloc = edge.getDst().getAllocSite();
217       Effect    effect        = new Effect(affectedAlloc, Effect.write, fld);       
218       Effect    effectSU      = null;
219
220       if (strongUpdate) {
221         effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);
222       }
223
224       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
225         Taint taint = taintSetIter.next();
226         add( taint, effect );
227
228         if (strongUpdate) {
229           add( taint, effectSU );
230         }
231       }
232     }
233   }
234
235
236   public String toString() {
237     return taint2effects.toString();    
238   }
239
240   public void writeEffects( String outfile ) {
241     try {
242       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
243       
244       bw.write( "Effects\n---------------\n\n" );
245
246       Iterator meItr = taint2effects.entrySet().iterator();
247       while( meItr.hasNext() ) {
248         Map.Entry   me      = (Map.Entry)   meItr.next();
249         Taint       taint   = (Taint)       me.getKey();
250         Set<Effect> effects = (Set<Effect>) me.getValue();
251
252         Iterator<Effect> eItr = effects.iterator();
253         while( eItr.hasNext() ) {
254           Effect e = eItr.next();
255             
256           bw.write( taint+"-->"+e+"\n" );          
257         }
258       }
259
260       bw.close();
261     } catch( IOException e ) {}
262   }
263
264   /*
265    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
266    * return mapMethodContextToMethodEffects.get(mc); }
267    * 
268    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
269    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
270    * MethodEffects meNew = new MethodEffects();
271    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
272    */
273
274   /*
275    * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
276    * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
277    * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
278    * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
279    * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
280    * mapMethodContextToMethodEffects.put(callerMC, me); }
281    */
282
283   /*
284    * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
285    * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
286    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
287    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
288    * mapMethodContextToMethodEffects.put(mc, me); }
289    * 
290    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
291    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
292    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
293    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
294    * mapMethodContextToMethodEffects.put(mc, me); }
295    * 
296    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
297    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
298    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
299    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
300    * mapMethodContextToMethodEffects.put(mc, me); }
301    * 
302    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
303    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
304    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
305    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
306    * mapMethodContextToMethodEffects.put(mc, me); }
307    * 
308    * 
309    * public void writeMethodEffectsResult() throws IOException {
310    * 
311    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
312    * "MethodEffects_report.txt"));
313    * 
314    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
315    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
316    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
317    * (MethodDescriptor) mc.getDescriptor();
318    * 
319    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
320    * 
321    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
322    * effectsSet = me.getEffects();
323    * 
324    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
325    * md.numParameters() + startIdx; i++) {
326    * 
327    * String paramName = md.getParamName(i - startIdx);
328    * 
329    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
330    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
331    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
332    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
333    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
334    * 
335    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
336    * (effectSet != null) { Iterator<EffectsKey> effectIter =
337    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
338    * effectIter.next(); keyStr += " " + key; } }
339    * 
340    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
341    * keyStr + "\n");
342    * 
343    * } bw.write("\n");
344    * 
345    * }
346    * 
347    * bw.close(); } catch (IOException e) { System.err.println(e); }
348    * 
349    * }
350    */
351 }