run ooojava and rcrpointer that print out effects and annotate them with the source...
[IRC.git] / Robust / src / Analysis / Disjoint / EffectsAnalysis.java
index 70cf0fb16ad8c3de6e78662df8fbefd735c34978..90d2b8e342d2ed42cec4465e0597965a70d615ca 100644 (file)
@@ -1,16 +1,16 @@
 package Analysis.Disjoint;
 
 import java.util.*;
+import java.util.Map.Entry;
 import java.io.*;
 
-import IR.FieldDescriptor;
-import IR.Flat.FlatCall;
-import IR.Flat.FlatMethod;
-import IR.Flat.TempDescriptor;
-import IR.Flat.FlatSESEEnterNode;
+import IR.*;
+import IR.Flat.*;
+import Analysis.Pointer.Edge;
+import Analysis.Pointer.AllocFactory.AllocNode;
 
 /////////////////////////////////////////////
-// 
+//
 //  Effects analysis computes read/write/strong
 //  update and other sorts of effects for the
 //  scope of a method or rblock.  The effects
@@ -27,250 +27,213 @@ import IR.Flat.FlatSESEEnterNode;
 
 public class EffectsAnalysis {
 
-  private Hashtable<FlatMethod,        EffectSet> fm2effectSet;
-  private Hashtable<FlatSESEEnterNode, EffectSet> sese2effectSet;
+  // the effects analysis should combine taints
+  // that match except for predicates--preds just
+  // support interprocedural analysis
+  private Hashtable<Taint, Set<Effect>> taint2effects;
 
-  public EffectsAnalysis() {
-    fm2effectSet   = new Hashtable<FlatMethod,        EffectSet>();
-    sese2effectSet = new Hashtable<FlatSESEEnterNode, EffectSet>();
-  }
+  // redundant views of the effect set for
+  // efficient retrieval
+  private Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> > sese2te;
+  private Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> > stallSite2te;
 
-  public void analyzeFlatFieldNode(FlatMethod fmContaining, 
-                                   FlatSESEEnterNode seseContaining,
-                                   ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld) {
+  public static State state;
+  public static BuildStateMachines buildStateMachines;
 
-    VariableNode vn = rg.td2vn.get(rhs);
-    
-    for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
-      RefEdge edge = iterator.next();
-      TaintSet taintSet = edge.getTaints();
-      AllocSite affectedAlloc = edge.getDst().getAllocSite();
-      for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
-        Taint taint = taintSetIter.next();
 
-        EffectSet effectSet = fm2effectSet.get(fmContaining);
-        if (effectSet == null) {
-          effectSet = new EffectSet();
-        }
-        
-        Effect effect = new Effect(affectedAlloc, Effect.read, fld);
+  public EffectsAnalysis() {
+    taint2effects = new Hashtable<Taint, Set<Effect>>();
 
-        add( fmContaining,   taint, effect );
-        add( seseContaining, taint, effect );        
-      }
-    }
+    sese2te      = new Hashtable<FlatSESEEnterNode, Hashtable<Taint, Set<Effect>> >();
+    stallSite2te = new Hashtable<FlatNode,          Hashtable<Taint, Set<Effect>> >();
   }
 
-  public void analyzeFlatSetFieldNode(FlatMethod fmContaining,
-                                      FlatSESEEnterNode seseContaining,
-                                      ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, boolean strongUpdate) {
 
-    VariableNode vn = rg.td2vn.get(lhs);
+  public Set<Effect> getEffects(Taint t) {
+    Taint tNoPreds = Canonical.changePredsTo(t,
+                                             ReachGraph.predsEmpty
+                                             );
+    return taint2effects.get(tNoPreds);
+  }
 
-    for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext();) {
-      RefEdge edge = iterator.next();
-      TaintSet taintSet = edge.getTaints();
-      AllocSite affectedAlloc = edge.getDst().getAllocSite();
-      for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext();) {
-        Taint taint = taintSetIter.next();
-        
-        Effect effect = new Effect(affectedAlloc, Effect.write, fld);       
-        add( fmContaining,   taint, effect );       
-        add( seseContaining, taint, effect );
-        
-        if (strongUpdate) {
-          Effect effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld);          
-          add( fmContaining,   taint, effect );          
-          add( seseContaining, taint, effect );
-        }
-      }
-    }
+  public Iterator iteratorTaintEffectPairs() {
+    return taint2effects.entrySet().iterator();
   }
 
-  public void analyzeFlatCall(FlatMethod fmContaining, FlatSESEEnterNode seseContaining, 
-                              FlatMethod fmCallee, Hashtable<Taint, TaintSet> tCallee2tsCaller) {
-    
-    EffectSet esCaller = getEffectSet(fmContaining);
-    if( esCaller == null ) {
-      esCaller = new EffectSet();
-    }
-    
-    EffectSet esCallee = getEffectSet(fmCallee);
-    if( esCallee == null ) {
-      esCallee = new EffectSet();
-    }
+  protected void add(Taint t, Effect e, FlatNode currentProgramPoint) {
+    Taint tNoPreds = Canonical.changePredsTo(t,
+                                             ReachGraph.predsEmpty
+                                             );
 
-    Iterator meItr = esCallee.getAllEffectPairs();
-    while( meItr.hasNext() ) {
-      Map.Entry       me      = (Map.Entry)       meItr.next();
-      Taint           tCallee = (Taint)           me.getKey();
-      HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
+    if( state.RCR ) {
+      buildStateMachines.addToStateMachine(t, e, currentProgramPoint);
+    }
 
-      if( tCallee2tsCaller.containsKey( tCallee ) ) {
+    // add to the global bag
+    Set<Effect> effectSet = taint2effects.get(tNoPreds);
+    if (effectSet == null) {
+      effectSet = new HashSet<Effect>();
+    }
+    effectSet.add(e);
+    taint2effects.put(tNoPreds, effectSet);
 
-        Iterator<Taint> tItr = tCallee2tsCaller.get( tCallee ).iterator();
-        while( tItr.hasNext() ) {
-          Taint tCaller = tItr.next();
+    // add to the alternate retrieval bags
+    if( t.getSESE() != null ) {
+      FlatSESEEnterNode sese = t.getSESE();
 
-          Iterator<Effect> eItr = effects.iterator();
-          while( eItr.hasNext() ) {
-            Effect e = eItr.next();
-            
-            esCaller.addEffect( tCaller, e );
-          }
+      Hashtable<Taint, Set<Effect>> te = sese2te.get(sese);
+      if( te == null ) {
+        te = new Hashtable<Taint, Set<Effect>>();
+      }
 
-          add( fmContaining,   tCaller, esCaller );
-          add( seseContaining, tCaller, esCaller );
-        }
+      Set<Effect> effects = te.get(tNoPreds);
+      if (effects == null) {
+        effects = new HashSet<Effect>();
       }
-    }
-  }
+      effects.add(e);
+      te.put(tNoPreds, effects);
 
-  public EffectSet getEffectSet(FlatMethod fm) {
-    return fm2effectSet.get(fm);
-  }
+      sese2te.put(sese, te);
 
-  public void writeEffectsPerMethodAndRBlock( String outfile ) {
-    try {
-      BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
-      
-      bw.write( "Effects Per Method\n\n" );
-
-      Iterator meItr1 = fm2effectSet.entrySet().iterator();
-      while( meItr1.hasNext() ) {
-        Map.Entry  me1 = (Map.Entry)  meItr1.next();
-        FlatMethod fm  = (FlatMethod) me1.getKey();
-        EffectSet  es  = (EffectSet)  me1.getValue();
-
-        bw.write( "\n"+fm+"\n--------------\n" );
-
-        Iterator meItr2 = es.getAllEffectPairs();
-        while( meItr2.hasNext() ) {
-          Map.Entry       me2     = (Map.Entry)       meItr2.next();
-          Taint           taint   = (Taint)           me2.getKey();
-          HashSet<Effect> effects = (HashSet<Effect>) me2.getValue();
-
-          Iterator<Effect> eItr = effects.iterator();
-          while( eItr.hasNext() ) {
-            Effect e = eItr.next();
-            
-            bw.write( "  "+taint+"-->"+e+"\n" );
-          }
-        }
+    } else {
+      assert t.getStallSite() != null;
+      FlatNode stallSite = t.getStallSite();
+
+      Hashtable<Taint, Set<Effect>> te = stallSite2te.get(stallSite);
+      if( te == null ) {
+        te = new Hashtable<Taint, Set<Effect>>();
       }
 
-      
-      bw.write( "\n\nEffects Per RBlock\n\n" );
-
-      meItr1 = sese2effectSet.entrySet().iterator();
-      while( meItr1.hasNext() ) {
-        Map.Entry         me1  = (Map.Entry)         meItr1.next();
-        FlatSESEEnterNode sese = (FlatSESEEnterNode) me1.getKey();
-        EffectSet         es   = (EffectSet)         me1.getValue();
-
-        bw.write( "\n"+sese.toPrettyString()+"\n--------------\n" );
-
-        Iterator meItr2 = es.getAllEffectPairs();
-        while( meItr2.hasNext() ) {
-          Map.Entry       me2     = (Map.Entry)       meItr2.next();
-          Taint           taint   = (Taint)           me2.getKey();
-          HashSet<Effect> effects = (HashSet<Effect>) me2.getValue();
-
-          Iterator<Effect> eItr = effects.iterator();
-          while( eItr.hasNext() ) {
-            Effect e = eItr.next();
-            
-            bw.write( "  "+taint+"-->"+e+"\n" );
-          }
-        }
+      Set<Effect> effects = te.get(tNoPreds);
+      if (effects == null) {
+        effects = new HashSet<Effect>();
       }
+      effects.add(e);
+      te.put(tNoPreds, effects);
+      stallSite2te.put(stallSite, te);
+    }
+  }
 
-      bw.close();
-    } catch( IOException e ) {}
+
+  public Hashtable<Taint, Set<Effect>> get(FlatSESEEnterNode sese) {
+    return sese2te.get(sese);
   }
 
-  protected void add( FlatMethod fm, Taint t, Effect e ) {
-    EffectSet es = fm2effectSet.get( fm );    
-    if( es == null ) {
-      es = new EffectSet();
-    }
-    es.addEffect( t, e );
-    
-    fm2effectSet.put( fm, es );
+  public Hashtable<Taint, Set<Effect>> get(FlatNode stallSite) {
+    return stallSite2te.get(stallSite);
   }
 
-  protected void add( FlatSESEEnterNode sese, Taint t, Effect e ) {
 
-    if( sese.getIsCallerSESEplaceholder() ) {
+
+  public void analyzeFlatFieldNode(ReachGraph rg, TempDescriptor rhs, FieldDescriptor fld, FlatNode currentProgramPoint) {
+
+    VariableNode vn = rg.td2vn.get(rhs);
+    if( vn == null ) {
       return;
     }
 
-    EffectSet es = sese2effectSet.get( sese );    
-    if( es == null ) {
-      es = new EffectSet();
+    for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext(); ) {
+      RefEdge edge          = iterator.next();
+      TaintSet taintSet      = edge.getTaints();
+      AllocSite affectedAlloc = edge.getDst().getAllocSite();
+      Effect    effect        = new Effect(affectedAlloc, Effect.read, fld, currentProgramPoint);
+
+      for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
+        Taint taint = taintSetIter.next();
+        add(taint, effect, currentProgramPoint);
+      }
     }
-    es.addEffect( t, e );
-    
-    sese2effectSet.put( sese, es );
   }
 
-  protected void add( FlatMethod fm, Taint t, EffectSet es ) {
-    EffectSet esExisting = fm2effectSet.get( fm );    
-    if( esExisting == null ) {
-      esExisting = new EffectSet();
-    }
+  public void analyzeFlatFieldNode(Set<Edge> sources, FieldDescriptor fld, FlatNode currentProgramPoint) {
+    for (Edge edge:sources) {
+      TaintSet  taintSet      = edge.getTaints();
+      Alloc     affectedAlloc = edge.getDst().getAllocSite();
+      Effect    effect        = new Effect(affectedAlloc, Effect.read, fld, currentProgramPoint);
 
-    Iterator meItr = es.getAllEffectPairs();
-    while( meItr.hasNext() ) {
-      Map.Entry       me      = (Map.Entry)       meItr.next();
-      Taint           taint   = (Taint)           me.getKey();
-      HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
-      
-      Iterator<Effect> eItr = effects.iterator();
-      while( eItr.hasNext() ) {
-        Effect e = eItr.next();
-
-        esExisting.addEffect( taint, e );
-      }      
+      if (taintSet!=null)
+        for (Taint taint : taintSet.getTaints()) {
+          add(taint, effect, currentProgramPoint);
+        }
     }
-    
-    fm2effectSet.put( fm, esExisting );
   }
 
-  protected void add( FlatSESEEnterNode sese, Taint t, EffectSet es ) {
+  public void analyzeFlatSetFieldNode(ReachGraph rg, TempDescriptor lhs, FieldDescriptor fld, FlatNode currentProgramPoint, boolean strongUpdate) {
 
-    if( sese.getIsCallerSESEplaceholder() ) {
+    VariableNode vn = rg.td2vn.get(lhs);
+    if( vn == null ) {
       return;
     }
 
-    EffectSet esExisting = sese2effectSet.get( sese );    
+    for (Iterator<RefEdge> iterator = vn.iteratorToReferencees(); iterator.hasNext(); ) {
+      RefEdge edge          = iterator.next();
+      TaintSet taintSet      = edge.getTaints();
+      AllocSite affectedAlloc = edge.getDst().getAllocSite();
+      Effect    effect        = new Effect(affectedAlloc, Effect.write, fld, currentProgramPoint);
+      Effect    effectSU      = null;
+
+      if (strongUpdate) {
+        effectSU = new Effect(affectedAlloc, Effect.strongupdate, fld, currentProgramPoint);
+      }
+
+      for (Iterator<Taint> taintSetIter = taintSet.iterator(); taintSetIter.hasNext(); ) {
+        Taint taint = taintSetIter.next();
+        add(taint, effect, currentProgramPoint);
 
-    if( esExisting == null ) {
-      esExisting = new EffectSet();
+        if (strongUpdate) {
+          add(taint, effectSU, currentProgramPoint);
+        }
+      }
     }
+  }
 
-    Iterator meItr = es.getAllEffectPairs();
-    while( meItr.hasNext() ) {
-      Map.Entry       me      = (Map.Entry)       meItr.next();
-      Taint           taint   = (Taint)           me.getKey();
-      HashSet<Effect> effects = (HashSet<Effect>) me.getValue();
-      
-      Iterator<Effect> eItr = effects.iterator();
-      while( eItr.hasNext() ) {
-        Effect e = eItr.next();
-
-        esExisting.addEffect( taint, e );
-      }      
+
+  public void analyzeFlatSetFieldNode(Set<Edge> dstedges, FieldDescriptor fld, FlatNode currentProgramPoint) {
+    for (Edge edge : dstedges) {
+      TaintSet taintSet = edge.getTaints();
+      Alloc affectedAlloc = edge.getDst().getAllocSite();
+      Effect effect = new Effect(affectedAlloc, Effect.write, fld, currentProgramPoint);
+      if (taintSet!=null)
+        for (Taint taint : taintSet.getTaints()) {
+          add(taint, effect, currentProgramPoint);
+        }
     }
+  }
+
 
-    sese2effectSet.put( sese, esExisting );
+  public String toString() {
+    return taint2effects.toString();
   }
 
+  public void writeEffects(String outfile) {
+    try {
+      BufferedWriter bw = new BufferedWriter(new FileWriter(outfile));
+
+      bw.write("Effects\n---------------\n\n");
+
+      Iterator meItr = taint2effects.entrySet().iterator();
+      while( meItr.hasNext() ) {
+        Map.Entry me      = (Map.Entry)meItr.next();
+        Taint taint   = (Taint)       me.getKey();
+        Set<Effect> effects = (Set<Effect>)me.getValue();
+
+        Iterator<Effect> eItr = effects.iterator();
+        while( eItr.hasNext() ) {
+          Effect e = eItr.next();
+
+          bw.write(taint+"-->"+e+"\n");
+        }
+      }
+
+      bw.close();
+    } catch( IOException e ) {
+    }
+  }
 
   /*
    * public MethodEffects getMethodEffectsByMethodContext(MethodContext mc){
    * return mapMethodContextToMethodEffects.get(mc); }
-   * 
+   *
    * public void createNewMapping(MethodContext mcNew) { if(!methodeffects)
    * return; if (!mapMethodContextToMethodEffects.containsKey(mcNew)) {
    * MethodEffects meNew = new MethodEffects();
@@ -292,66 +255,70 @@ public class EffectsAnalysis {
    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
    * me.analyzeFlatFieldNode(og, srcDesc, fieldDesc);
    * mapMethodContextToMethodEffects.put(mc, me); }
-   * 
+   *
    * public void analyzeFlatSetFieldNode(MethodContext mc, OwnershipGraph og,
    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
    * me.analyzeFlatSetFieldNode(og, dstDesc, fieldDesc);
    * mapMethodContextToMethodEffects.put(mc, me); }
-   * 
+   *
    * public void analyzeFlatSetElementNode(MethodContext mc, OwnershipGraph og,
    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
    * me.analyzeFlatSetElementNode(og, dstDesc, fieldDesc);
    * mapMethodContextToMethodEffects.put(mc, me); }
-   * 
+   *
    * public void analyzeFlatElementNode(MethodContext mc, OwnershipGraph og,
    * TempDescriptor dstDesc, FieldDescriptor fieldDesc) { if(!methodeffects)
    * return; MethodEffects me = mapMethodContextToMethodEffects.get(mc);
    * me.analyzeFlatElementNode(og, dstDesc, fieldDesc);
    * mapMethodContextToMethodEffects.put(mc, me); }
-   * 
-   * 
+   *
+   *
    * public void writeMethodEffectsResult() throws IOException {
-   * 
+   *
    * try { BufferedWriter bw = new BufferedWriter(new FileWriter(
    * "MethodEffects_report.txt"));
-   * 
+   *
    * Set<MethodContext> mcSet = mapMethodContextToMethodEffects.keySet();
    * Iterator<MethodContext> mcIter = mcSet.iterator(); while (mcIter.hasNext())
    * { MethodContext mc = mcIter.next(); MethodDescriptor md =
    * (MethodDescriptor) mc.getDescriptor();
-   * 
+   *
    * int startIdx = 0; if (!md.isStatic()) { startIdx = 1; }
-   * 
+   *
    * MethodEffects me = mapMethodContextToMethodEffects.get(mc); EffectsSet
    * effectsSet = me.getEffects();
-   * 
+   *
    * bw.write("Method " + mc + " :\n"); for (int i = startIdx; i <
    * md.numParameters() + startIdx; i++) {
-   * 
+   *
    * String paramName = md.getParamName(i - startIdx);
-   * 
+   *
    * Set<EffectsKey> effectSet = effectsSet.getReadingSet(i); String keyStr =
    * "{"; if (effectSet != null) { Iterator<EffectsKey> effectIter =
    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
    * effectIter.next(); keyStr += " " + key; } } keyStr += " }";
    * bw.write("  Paramter " + paramName + " ReadingSet=" + keyStr + "\n");
-   * 
+   *
    * effectSet = effectsSet.getWritingSet(new Integer(i)); keyStr = "{"; if
    * (effectSet != null) { Iterator<EffectsKey> effectIter =
    * effectSet.iterator(); while (effectIter.hasNext()) { EffectsKey key =
    * effectIter.next(); keyStr += " " + key; } }
-   * 
+   *
    * keyStr += " }"; bw.write("  Paramter " + paramName + " WritingngSet=" +
    * keyStr + "\n");
-   * 
+   *
    * } bw.write("\n");
-   * 
+   *
    * }
-   * 
+   *
    * bw.close(); } catch (IOException e) { System.err.println(e); }
-   * 
+   *
    * }
    */
+
+  public Hashtable<Taint, Set<Effect>> getAllEffects() {
+    return taint2effects;
+  }
 }