commit hacks to effect analysis...interfaces to allow disjoint/pointer analysis to...
[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
193     for (Edge edge:dstedges) {
194       TaintSet  taintSet      = edge.getTaints();
195       Alloc affectedAlloc = edge.getDst();
196       Effect    effect        = new Effect(affectedAlloc, Effect.write, fld);       
197       if (taintSet!=null)
198         for (Taint taint:taintSet.getTaints()) {
199           add( taint, effect, currentProgramPoint );
200         }
201     }
202   }
203
204
205   public String toString() {
206     return taint2effects.toString();    
207   }
208
209   public void writeEffects( String outfile ) {
210     try {
211       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
212       
213       bw.write( "Effects\n---------------\n\n" );
214
215       Iterator meItr = taint2effects.entrySet().iterator();
216       while( meItr.hasNext() ) {
217         Map.Entry   me      = (Map.Entry)   meItr.next();
218         Taint       taint   = (Taint)       me.getKey();
219         Set<Effect> effects = (Set<Effect>) me.getValue();
220
221         Iterator<Effect> eItr = effects.iterator();
222         while( eItr.hasNext() ) {
223           Effect e = eItr.next();
224             
225           bw.write( taint+"-->"+e+"\n" );          
226         }
227       }
228
229       bw.close();
230     } catch( IOException e ) {}
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 }