We fixed the bug of where to find the stallsite reachgraph. \n\n We found an even...
[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   protected void add(Taint t, Effect e) {
63     if( t.getSESE() != null &&
64         t.getSESE().getIsCallerSESEplaceholder() ) {
65       return;
66     }
67
68     Taint tNoPreds = Canonical.changePredsTo( t,
69                                               ReachGraph.predsEmpty
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) {
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);
144       }
145     }
146   }
147
148   public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
149
150     VariableNode vn = rg.td2vn.get(lhs);
151     if( vn == null ) {
152       return;
153     }
154
155     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
156       RefEdge   edge          = iterator.next();
157       TaintSet  taintSet      = edge.getTaints();
158       AllocSite affectedAlloc = edge.getDst().getAllocSite();
159       Effect    effect        = new Effect(affectedAlloc, Effect.write, fld);       
160       Effect    effectSU      = null;
161
162       if (strongUpdate) {
163         effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);
164       }
165
166       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
167         Taint taint = taintSetIter.next();
168         add( taint, effect );
169
170         if (strongUpdate) {
171           add( taint, effectSU );
172         }
173       }
174     }
175   }
176
177
178   public String toString() {
179     return taint2effects.toString();    
180   }
181
182   public void writeEffects( String outfile ) {
183     try {
184       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
185       
186       bw.write( "Effects\n---------------\n\n" );
187
188       Iterator meItr = taint2effects.entrySet().iterator();
189       while( meItr.hasNext() ) {
190         Map.Entry   me      = (Map.Entry)   meItr.next();
191         Taint       taint   = (Taint)       me.getKey();
192         Set<Effect> effects = (Set<Effect>) me.getValue();
193
194         Iterator<Effect> eItr = effects.iterator();
195         while( eItr.hasNext() ) {
196           Effect e = eItr.next();
197             
198           bw.write( taint+"-->"+e+"\n" );          
199         }
200       }
201
202       bw.close();
203     } catch( IOException e ) {}
204   }
205
206   /*
207    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
208    * return mapMethodContextToMethodEffects.get(mc); }
209    * 
210    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
211    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
212    * MethodEffects meNew = new MethodEffects();
213    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
214    */
215
216   /*
217    * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
218    * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
219    * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
220    * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
221    * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
222    * mapMethodContextToMethodEffects.put(callerMC, me); }
223    */
224
225   /*
226    * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
227    * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
228    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
229    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
230    * mapMethodContextToMethodEffects.put(mc, me); }
231    * 
232    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
233    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
234    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
235    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
236    * mapMethodContextToMethodEffects.put(mc, me); }
237    * 
238    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
239    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
240    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
241    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
242    * mapMethodContextToMethodEffects.put(mc, me); }
243    * 
244    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
245    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
246    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
247    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
248    * mapMethodContextToMethodEffects.put(mc, me); }
249    * 
250    * 
251    * public void writeMethodEffectsResult() throws IOException {
252    * 
253    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
254    * "MethodEffects_report.txt"));
255    * 
256    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
257    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
258    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
259    * (MethodDescriptor) mc.getDescriptor();
260    * 
261    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
262    * 
263    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
264    * effectsSet = me.getEffects();
265    * 
266    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
267    * md.numParameters() + startIdx; i++) {
268    * 
269    * String paramName = md.getParamName(i - startIdx);
270    * 
271    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
272    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
273    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
274    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
275    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
276    * 
277    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
278    * (effectSet != null) { Iterator<EffectsKey> effectIter =
279    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
280    * effectIter.next(); keyStr += " " + key; } }
281    * 
282    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
283    * keyStr + "\n");
284    * 
285    * } bw.write("\n");
286    * 
287    * }
288    * 
289    * bw.close(); } catch (IOException e) { System.err.println(e); }
290    * 
291    * }
292    */
293   
294   public Hashtable<Taint, Set<Effect>> getAllEffects() {
295     return taint2effects;
296   }
297 }