more changes...
[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
11 /////////////////////////////////////////////
12 // 
13 //  Effects analysis computes read/write/strong
14 //  update and other sorts of effects for the
15 //  scope of a method or rblock.  The effects
16 //  are associated with the heap roots through
17 //  which a reference to the effect target was
18 //  obtained.
19 //
20 //  The effects analysis piggy-backs
21 //  on the disjoint reachability analysis,
22 //  if requested, to support OoOJava and
23 //  potentially other analysis clients.
24 //
25 /////////////////////////////////////////////
26
27 public class EffectsAnalysis {
28
29   // the effects analysis should combine taints
30   // that match except for predicates--preds just
31   // support interprocedural analysis
32   private Hashtable<Taint, Set<Effect>> taint2effects;
33
34   // redundant views of the effect set for
35   // efficient retrieval
36   private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
37   private Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> > stallSite2te;
38
39   public static State              state;
40   public static BuildStateMachines buildStateMachines;
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   protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
63
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();
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();
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    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
234    * return mapMethodContextToMethodEffects.get(mc); }
235    * 
236    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
237    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
238    * MethodEffects meNew = new MethodEffects();
239    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
240    */
241
242   /*
243    * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
244    * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
245    * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
246    * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
247    * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
248    * mapMethodContextToMethodEffects.put(callerMC, me); }
249    */
250
251   /*
252    * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
253    * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
254    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
255    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
256    * mapMethodContextToMethodEffects.put(mc, me); }
257    * 
258    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
259    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
260    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
261    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
262    * mapMethodContextToMethodEffects.put(mc, me); }
263    * 
264    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
265    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
266    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
267    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
268    * mapMethodContextToMethodEffects.put(mc, me); }
269    * 
270    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
271    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
272    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
273    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
274    * mapMethodContextToMethodEffects.put(mc, me); }
275    * 
276    * 
277    * public void writeMethodEffectsResult() throws IOException {
278    * 
279    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
280    * "MethodEffects_report.txt"));
281    * 
282    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
283    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
284    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
285    * (MethodDescriptor) mc.getDescriptor();
286    * 
287    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
288    * 
289    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
290    * effectsSet = me.getEffects();
291    * 
292    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
293    * md.numParameters() + startIdx; i++) {
294    * 
295    * String paramName = md.getParamName(i - startIdx);
296    * 
297    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
298    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
299    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
300    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
301    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
302    * 
303    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
304    * (effectSet != null) { Iterator<EffectsKey> effectIter =
305    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
306    * effectIter.next(); keyStr += " " + key; } }
307    * 
308    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
309    * keyStr + "\n");
310    * 
311    * } bw.write("\n");
312    * 
313    * }
314    * 
315    * bw.close(); } catch (IOException e) { System.err.println(e); }
316    * 
317    * }
318    */
319   
320   public Hashtable<Taint, Set<Effect>> getAllEffects() {
321     return taint2effects;
322   }
323 }