52244a537e9b04b8a986852719509e5718023803
[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   public EffectsAnalysis() {
38     taint2effects = new Hashtable<Taint, Set<Effect>>();
39   }
40
41
42   public Set<Effect> getEffects(Taint t) {
43     Taint tNoPreds = Canonical.changePredsTo( t,
44                                               ReachGraph.predsEmpty
45                                               );
46     return taint2effects.get(tNoPreds);
47   }
48
49   public Iterator iteratorTaintEffectPairs() {
50     return taint2effects.entrySet().iterator();
51   }
52   
53   public Hashtable<Taint, Set<Effect>> getSESEEffects(FlatSESEEnterNode sese){
54     
55     Hashtable<Taint, Set<Effect>> taint2Effects = new Hashtable<Taint, Set<Effect>>();
56     Iterator iter=iteratorTaintEffectPairs();
57     while (iter.hasNext()) {
58       Entry entry = (Entry) iter.next();
59       Taint taint = (Taint) entry.getKey();
60       Set<Effect> effects = (Set<Effect>) entry.getValue();
61       if (taint.getSESE().equals(sese)) {
62         Iterator<Effect> eIter = effects.iterator();
63         while (eIter.hasNext()) {
64           Effect effect = eIter.next();
65           if (taint.getSESE().equals(sese)) {
66             Set<Effect> effectSet = taint2Effects.get(taint);
67             if (effectSet == null) {
68               effectSet = new HashSet<Effect>();
69             }
70             effectSet.add(effect);
71             taint2Effects.put(taint, effectSet);
72           }
73         }
74       }
75     }
76     
77     return taint2Effects;
78     
79   }
80   
81   public Hashtable<Taint, Set<Effect>> getStallSiteEffects(FlatNode fn, TempDescriptor td){
82     
83     Hashtable<Taint, Set<Effect>> taint2Effects = new Hashtable<Taint, Set<Effect>>();
84     Iterator iter=iteratorTaintEffectPairs();
85     while(iter.hasNext()){
86       Entry entry=(Entry)iter.next();
87       Taint taint=(Taint)entry.getKey();
88       Set<Effect> effects=(Set<Effect>)entry.getValue();
89       if(taint.getStallSite().equals(fn)){
90         Iterator<Effect> eIter=effects.iterator();        
91         while (eIter.hasNext()) {
92           Effect effect = eIter.next();
93           if( taint.getStallSite().equals(fn) && taint.getVar().equals(td) ){
94             Set<Effect> effectSet=taint2Effects.get(taint);
95             if(effectSet==null){
96               effectSet=new HashSet<Effect>();
97             }
98             effectSet.add(effect);
99             taint2Effects.put(taint, effectSet);
100           }
101         }
102       }
103     }
104     return taint2Effects; 
105   }
106
107
108   protected void add(Taint t, Effect e) {
109     if( t.getSESE() != null &&
110         t.getSESE().getIsCallerSESEplaceholder() ) {
111       return;
112     }
113
114     Taint tNoPreds = Canonical.changePredsTo( t,
115                                               ReachGraph.predsEmpty
116                                               );
117
118     Set<Effect> effectSet = taint2effects.get(tNoPreds);
119     if (effectSet == null) {
120       effectSet = new HashSet<Effect>();
121     }
122     effectSet.add(e);
123     taint2effects.put(tNoPreds, effectSet);
124   }
125
126
127   public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
128
129     VariableNode vn = rg.td2vn.get(rhs);
130     if( vn == null ) {
131       return;
132     }
133
134     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
135       RefEdge   edge          = iterator.next();
136       TaintSet  taintSet      = edge.getTaints();
137       AllocSite affectedAlloc = edge.getDst().getAllocSite();
138       Effect    effect        = new Effect(affectedAlloc, Effect.read, fld);
139
140       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
141         Taint taint = taintSetIter.next();        
142         add(taint, effect);
143       }
144     }
145   }
146
147   public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
148
149     VariableNode vn = rg.td2vn.get(lhs);
150     if( vn == null ) {
151       return;
152     }
153
154     for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
155       RefEdge   edge          = iterator.next();
156       TaintSet  taintSet      = edge.getTaints();
157       AllocSite affectedAlloc = edge.getDst().getAllocSite();
158       Effect    effect        = new Effect(affectedAlloc, Effect.write, fld);       
159       Effect    effectSU      = null;
160
161       if (strongUpdate) {
162         effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);
163       }
164
165       for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
166         Taint taint = taintSetIter.next();
167         add( taint, effect );
168
169         if (strongUpdate) {
170           add( taint, effectSU );
171         }
172       }
173     }
174   }
175
176
177   public String toString() {
178     return taint2effects.toString();    
179   }
180
181   public void writeEffects( String outfile ) {
182     try {
183       BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
184       
185       bw.write( "Effects\n---------------\n\n" );
186
187       Iterator meItr = taint2effects.entrySet().iterator();
188       while( meItr.hasNext() ) {
189         Map.Entry   me      = (Map.Entry)   meItr.next();
190         Taint       taint   = (Taint)       me.getKey();
191         Set<Effect> effects = (Set<Effect>) me.getValue();
192
193         Iterator<Effect> eItr = effects.iterator();
194         while( eItr.hasNext() ) {
195           Effect e = eItr.next();
196             
197           bw.write( taint+"-->"+e+"\n" );          
198         }
199       }
200
201       bw.close();
202     } catch( IOException e ) {}
203   }
204
205   /*
206    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
207    * return mapMethodContextToMethodEffects.get(mc); }
208    * 
209    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
210    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
211    * MethodEffects meNew = new MethodEffects();
212    * mapMethodContextToMethodEffects.put(mcNew, meNew); } }
213    */
214
215   /*
216    * public void analyzeFlatCall(OwnershipGraph calleeOG, MethodContext
217    * calleeMC, MethodContext callerMC, FlatCall fc) { if(!methodeffects) return;
218    * MethodEffects me = mapMethodContextToMethodEffects.get(callerMC);
219    * MethodEffects meFlatCall = mapMethodContextToMethodEffects .get(calleeMC);
220    * me.analyzeFlatCall(calleeOG, fc, callerMC, meFlatCall);
221    * mapMethodContextToMethodEffects.put(callerMC, me); }
222    */
223
224   /*
225    * public void analyzeFlatFieldNode(MethodContext mc, OwnershipGraph og,
226    * TempDescriptor srcDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
227    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
228    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
229    * mapMethodContextToMethodEffects.put(mc, me); }
230    * 
231    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
232    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
233    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
234    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
235    * mapMethodContextToMethodEffects.put(mc, me); }
236    * 
237    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
238    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
239    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
240    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
241    * mapMethodContextToMethodEffects.put(mc, me); }
242    * 
243    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
244    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
245    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
246    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
247    * mapMethodContextToMethodEffects.put(mc, me); }
248    * 
249    * 
250    * public void writeMethodEffectsResult() throws IOException {
251    * 
252    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
253    * "MethodEffects_report.txt"));
254    * 
255    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
256    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
257    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
258    * (MethodDescriptor) mc.getDescriptor();
259    * 
260    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
261    * 
262    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
263    * effectsSet = me.getEffects();
264    * 
265    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
266    * md.numParameters() + startIdx; i++) {
267    * 
268    * String paramName = md.getParamName(i - startIdx);
269    * 
270    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
271    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
272    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
273    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
274    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
275    * 
276    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
277    * (effectSet != null) { Iterator<EffectsKey> effectIter =
278    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
279    * effectIter.next(); keyStr += " " + key; } }
280    * 
281    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
282    * keyStr + "\n");
283    * 
284    * } bw.write("\n");
285    * 
286    * }
287    * 
288    * bw.close(); } catch (IOException e) { System.err.println(e); }
289    * 
290    * }
291    */
292 }