rblock effects dont collect over method call, but its close
[IRC.git] / Robust / src / Analysis / Disjoint / EffectsAnalysis.java
1 package Analysis.Disjoint;
2
3 import java.util.*;
4 import java.io.*;
5
6 import IR.FieldDescriptor;
7 import IR.Flat.FlatCall;
8 import IR.Flat.FlatMethod;
9 import IR.Flat.TempDescriptor;
10 import IR.Flat.FlatSESEEnterNode;
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   private Hashtable<FlatMethod,        EffectSet> fm2effectSet;
31   private Hashtable<FlatSESEEnterNode, EffectSet> sese2effectSet;
32
33   public EffectsAnalysis() {
34     fm2effectSet   = new Hashtable<FlatMethod,        EffectSet>();
35     sese2effectSet = new Hashtable<FlatSESEEnterNode, EffectSet>();
36   }
37
38   public void analyzeFlatFieldNode(FlatMethod fmContaining, 
39                                    FlatSESEEnterNode seseContaining,
40                                    ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
41
42     VariableNode vn = rg.td2vn.get(rhs);
43     
44     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
45       RefEdge edge = iterator.next();
46       TaintSet taintSet = edge.getTaints();
47       AllocSite affectedAlloc = edge.getDst().getAllocSite();
48       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
49         Taint taint = taintSetIter.next();
50
51         EffectSet effectSet = fm2effectSet.get(fmContaining);
52         if (effectSet == null) {
53           effectSet = new EffectSet();
54         }
55         
56         Effect effect = new Effect(affectedAlloc, Effect.read, fld);
57
58         add( fmContaining,   taint, effect );
59         add( seseContaining, taint, effect );        
60       }
61     }
62   }
63
64   public void analyzeFlatSetFieldNode(FlatMethod fmContaining,
65                                       FlatSESEEnterNode seseContaining,
66                                       ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
67
68     VariableNode vn = rg.td2vn.get(lhs);
69
70     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
71       RefEdge edge = iterator.next();
72       TaintSet taintSet = edge.getTaints();
73       AllocSite affectedAlloc = edge.getDst().getAllocSite();
74       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
75         Taint taint = taintSetIter.next();
76         
77         Effect effect = new Effect(affectedAlloc, Effect.write, fld);       
78         add( fmContaining,   taint, effect );       
79         add( seseContaining, taint, effect );
80         
81         if (strongUpdate) {
82           Effect effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);          
83           add( fmContaining,   taint, effect );          
84           add( seseContaining, taint, effect );
85         }
86       }
87     }
88   }
89
90   public void analyzeFlatCall(FlatMethod fmContaining, FlatSESEEnterNode seseContaining, 
91                               FlatMethod fmCallee, Hashtable<Taint, TaintSet> tCallee2tsCaller) {
92     
93     EffectSet esCaller = getEffectSet(fmContaining);
94     if( esCaller == null ) {
95       esCaller = new EffectSet();
96     }
97     
98     EffectSet esCallee = getEffectSet(fmCallee);
99     if( esCallee == null ) {
100       esCallee = new EffectSet();
101     }
102
103     Iterator meItr = esCallee.getAllEffectPairs();
104     while( meItr.hasNext() ) {
105       Map.Entry       me      = (Map.Entry)       meItr.next();
106       Taint           tCallee = (Taint)           me.getKey();
107       HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
108
109       if( tCallee2tsCaller.containsKey( tCallee ) ) {
110
111         Iterator<Taint> tItr = tCallee2tsCaller.get( tCallee ).iterator();
112         while( tItr.hasNext() ) {
113           Taint tCaller = tItr.next();
114
115           Iterator<Effect> eItr = effects.iterator();
116           while( eItr.hasNext() ) {
117             Effect e = eItr.next();
118             
119             esCaller.addEffect( tCaller, e );
120           }
121
122           add( fmContaining,   tCaller, esCaller );
123           add( seseContaining, tCaller, esCaller );
124         }
125       }
126     }
127   }
128
129   public EffectSet getEffectSet(FlatMethod fm) {
130     return fm2effectSet.get(fm);
131   }
132
133   public void writeEffectsPerMethodAndRBlock( String outfile ) {
134     try {
135       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
136       
137       bw.write( "Effects Per Method\n\n" );
138
139       Iterator meItr1 = fm2effectSet.entrySet().iterator();
140       while( meItr1.hasNext() ) {
141         Map.Entry  me1 = (Map.Entry)  meItr1.next();
142         FlatMethod fm  = (FlatMethod) me1.getKey();
143         EffectSet  es  = (EffectSet)  me1.getValue();
144
145         bw.write( "\n"+fm+"\n--------------\n" );
146
147         Iterator meItr2 = es.getAllEffectPairs();
148         while( meItr2.hasNext() ) {
149           Map.Entry       me2     = (Map.Entry)       meItr2.next();
150           Taint           taint   = (Taint)           me2.getKey();
151           HashSet<Effect> effects = (HashSet<Effect>) me2.getValue();
152
153           Iterator<Effect> eItr = effects.iterator();
154           while( eItr.hasNext() ) {
155             Effect e = eItr.next();
156             
157             bw.write( "  "+taint+"-->"+e+"\n" );
158           }
159         }
160       }
161
162       
163       bw.write( "\n\nEffects Per RBlock\n\n" );
164
165       meItr1 = sese2effectSet.entrySet().iterator();
166       while( meItr1.hasNext() ) {
167         Map.Entry         me1  = (Map.Entry)         meItr1.next();
168         FlatSESEEnterNode sese = (FlatSESEEnterNode) me1.getKey();
169         EffectSet         es   = (EffectSet)         me1.getValue();
170
171         bw.write( "\n"+sese.toPrettyString()+"\n--------------\n" );
172
173         Iterator meItr2 = es.getAllEffectPairs();
174         while( meItr2.hasNext() ) {
175           Map.Entry       me2     = (Map.Entry)       meItr2.next();
176           Taint           taint   = (Taint)           me2.getKey();
177           HashSet<Effect> effects = (HashSet<Effect>) me2.getValue();
178
179           Iterator<Effect> eItr = effects.iterator();
180           while( eItr.hasNext() ) {
181             Effect e = eItr.next();
182             
183             bw.write( "  "+taint+"-->"+e+"\n" );
184           }
185         }
186       }
187
188       bw.close();
189     } catch( IOException e ) {}
190   }
191
192   protected void add( FlatMethod fm, Taint t, Effect e ) {
193     EffectSet es = fm2effectSet.get( fm );    
194     if( es == null ) {
195       es = new EffectSet();
196     }
197     es.addEffect( t, e );
198     
199     fm2effectSet.put( fm, es );
200   }
201
202   protected void add( FlatSESEEnterNode sese, Taint t, Effect e ) {
203
204     if( sese.getIsCallerSESEplaceholder() ) {
205       return;
206     }
207
208     EffectSet es = sese2effectSet.get( sese );    
209     if( es == null ) {
210       es = new EffectSet();
211     }
212     es.addEffect( t, e );
213     
214     sese2effectSet.put( sese, es );
215   }
216
217   protected void add( FlatMethod fm, Taint t, EffectSet es ) {
218     EffectSet esExisting = fm2effectSet.get( fm );    
219     if( esExisting == null ) {
220       esExisting = new EffectSet();
221     }
222
223     Iterator meItr = es.getAllEffectPairs();
224     while( meItr.hasNext() ) {
225       Map.Entry       me      = (Map.Entry)       meItr.next();
226       Taint           taint   = (Taint)           me.getKey();
227       HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
228       
229       Iterator<Effect> eItr = effects.iterator();
230       while( eItr.hasNext() ) {
231         Effect e = eItr.next();
232
233         esExisting.addEffect( taint, e );
234       }      
235     }
236     
237     fm2effectSet.put( fm, esExisting );
238   }
239
240   protected void add( FlatSESEEnterNode sese, Taint t, EffectSet es ) {
241
242     if( sese.getIsCallerSESEplaceholder() ) {
243       return;
244     }
245
246     EffectSet esExisting = sese2effectSet.get( sese );    
247
248     if( esExisting == null ) {
249       esExisting = new EffectSet();
250     }
251
252     Iterator meItr = es.getAllEffectPairs();
253     while( meItr.hasNext() ) {
254       Map.Entry       me      = (Map.Entry)       meItr.next();
255       Taint           taint   = (Taint)           me.getKey();
256       HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
257       
258       Iterator<Effect> eItr = effects.iterator();
259       while( eItr.hasNext() ) {
260         Effect e = eItr.next();
261
262         esExisting.addEffect( taint, e );
263       }      
264     }
265
266     sese2effectSet.put( sese, esExisting );
267   }
268
269
270   /*
271    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
272    * return mapMethodContextToMethodEffects.get(mc); }
273    * 
274    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
275    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
276    * MethodEffects meNew = new MethodEffects();
277    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
278    */
279
280   /*
281    * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
282    * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
283    * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
284    * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
285    * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
286    * mapMethodContextToMethodEffects.put(callerMC, me); }
287    */
288
289   /*
290    * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
291    * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
292    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
293    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
294    * mapMethodContextToMethodEffects.put(mc, me); }
295    * 
296    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
297    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
298    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
299    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
300    * mapMethodContextToMethodEffects.put(mc, me); }
301    * 
302    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
303    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
304    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
305    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
306    * mapMethodContextToMethodEffects.put(mc, me); }
307    * 
308    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
309    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
310    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
311    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
312    * mapMethodContextToMethodEffects.put(mc, me); }
313    * 
314    * 
315    * public void writeMethodEffectsResult() throws IOException {
316    * 
317    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
318    * "MethodEffects_report.txt"));
319    * 
320    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
321    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
322    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
323    * (MethodDescriptor) mc.getDescriptor();
324    * 
325    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
326    * 
327    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
328    * effectsSet = me.getEffects();
329    * 
330    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
331    * md.numParameters() + startIdx; i++) {
332    * 
333    * String paramName = md.getParamName(i - startIdx);
334    * 
335    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
336    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
337    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
338    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
339    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
340    * 
341    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
342    * (effectSet != null) { Iterator<EffectsKey> effectIter =
343    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
344    * effectIter.next(); keyStr += " " + key; } }
345    * 
346    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
347    * keyStr + "\n");
348    * 
349    * } bw.write("\n");
350    * 
351    * }
352    * 
353    * bw.close(); } catch (IOException e) { System.err.println(e); }
354    * 
355    * }
356    */
357 }