bb1331164151c6e445264beeaf860ef365a6c620
[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
10 /////////////////////////////////////////////
11 // 
12 //  Effects analysis computes read/write/strong
13 //  update and other sorts of effects for the
14 //  scope of a method or rblock.  The effects
15 //  are associated with the heap roots through
16 //  which a reference to the effect target was
17 //  obtained.
18 //
19 //  The effects analysis piggy-backs
20 //  on the disjoint reachability analysis,
21 //  if requested, to support OoOJava and
22 //  potentially other analysis clients.
23 //
24 /////////////////////////////////////////////
25
26 public class EffectsAnalysis {
27
28   // the effects analysis should combine taints
29   // that match except for predicates--preds just
30   // support interprocedural analysis
31   private Hashtable<Taint, Set<Effect>> taint2effects;
32
33   // redundant views of the effect set for
34   // efficient retrieval
35   private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
36   private Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> > stallSite2te;
37
38   public static State              state;
39   public static BuildStateMachines buildStateMachines;
40
41
42   public EffectsAnalysis() {
43     taint2effects = new Hashtable<Taint, Set<Effect>>();
44
45     sese2te      = new Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> >();
46     stallSite2te = new Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> >();
47   }
48
49
50   public Set<Effect> getEffects(Taint t) {
51     Taint tNoPreds = Canonical.changePredsTo( t,
52                                               ReachGraph.predsEmpty
53                                               );
54     return taint2effects.get(tNoPreds);
55   }
56
57   public Iterator iteratorTaintEffectPairs() {
58     return taint2effects.entrySet().iterator();
59   }
60
61   protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
62
63     Taint tNoPreds = Canonical.changePredsTo( t,
64                                               ReachGraph.predsEmpty
65                                               );
66
67     if( state.RCR ) {
68       buildStateMachines.addToStateMachine( t, e, currentProgramPoint );
69     }
70
71     // add to the global bag
72     Set<Effect> effectSet = taint2effects.get(tNoPreds);
73     if (effectSet == null) {
74       effectSet = new HashSet<Effect>();
75     }
76     effectSet.add(e);
77     taint2effects.put(tNoPreds, effectSet);
78
79     // add to the alternate retrieval bags
80     if( t.getSESE() != null ) {
81       FlatSESEEnterNode sese = t.getSESE();
82
83       Hashtable<Taint, Set<Effect>> te = sese2te.get( sese );
84       if( te == null ) {
85         te = new Hashtable<Taint, Set<Effect>>();
86       }
87
88       Set<Effect> effects = te.get(tNoPreds);
89       if (effects == null) {
90         effects = new HashSet<Effect>();
91       }
92       effects.add(e);
93       te.put(tNoPreds, effects);
94
95       sese2te.put(sese, te);
96
97     } else {
98       assert t.getStallSite() != null;
99       FlatNode stallSite = t.getStallSite();
100
101       Hashtable<Taint, Set<Effect>> te = stallSite2te.get( stallSite );
102       if( te == null ) {
103         te = new Hashtable<Taint, Set<Effect>>();
104       }
105
106       Set<Effect> effects = te.get(tNoPreds);
107       if (effects == null) {
108         effects = new HashSet<Effect>();
109       }
110       effects.add(e);
111       te.put(tNoPreds, effects);
112       stallSite2te.put(stallSite, te);
113     }    
114   }
115
116
117   public Hashtable<Taint, Set<Effect>> get( FlatSESEEnterNode sese ) {
118     return sese2te.get(sese);
119   }
120
121   public Hashtable<Taint, Set<Effect>> get( FlatNode stallSite ) {
122     return stallSite2te.get(stallSite);
123   }
124
125
126
127   public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld, FlatNode currentProgramPoint) {
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, currentProgramPoint);
143       }
144     }
145   }
146
147   public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, FlatNode currentProgramPoint, 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, currentProgramPoint );
168
169         if (strongUpdate) {
170           add( taint, effectSU, currentProgramPoint );
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   
293   public Hashtable<Taint, Set<Effect>> getAllEffects() {
294     return taint2effects;
295   }
296 }