changes
[IRC.git] / Robust / src / Analysis / Pointer / Pointer.java
index fcff4a50be00601138b0321d43422d9910d71ec5..13dd2844ff3f4bd0be105a997a9cb6d39727c301 100644 (file)
@@ -5,21 +5,53 @@ import IR.*;
 import Analysis.Liveness;
 import Analysis.Pointer.BasicBlock.BBlock;
 import Analysis.Pointer.AllocFactory.AllocNode;
+import Analysis.Disjoint.Alloc;
+import Analysis.Disjoint.Taint;
+import Analysis.Disjoint.TaintSet;
+import Analysis.Disjoint.Canonical;
+import Analysis.Disjoint.HeapAnalysis;
+import Analysis.CallGraph.CallGraph;
+import Analysis.OoOJava.RBlockRelationAnalysis;
+import Analysis.OoOJava.Accessible;
+import Analysis.Disjoint.ExistPred;
+import Analysis.Disjoint.ReachGraph;
+import Analysis.Disjoint.EffectsAnalysis;
+import Analysis.Disjoint.BuildStateMachines;
 import java.io.*;
 
-public class Pointer {
+
+public class Pointer implements HeapAnalysis{
   HashMap<FlatMethod, BasicBlock> blockMap;
   HashMap<BBlock, Graph> bbgraphMap;
   HashMap<FlatNode, Graph> graphMap;
   HashMap<FlatCall, Set<BBlock>> callMap;
   HashMap<BBlock, Set<PPoint>> returnMap;
   HashMap<BBlock, Set<TempDescriptor>> bblivetemps;
+  HashSet<FlatNode> mustProcess;
 
+  private boolean OoOJava=false;
+  CallGraph callGraph;
   State state;
   TypeUtil typeUtil;
   AllocFactory allocFactory;
   LinkedList<Delta> toprocess;
   TempDescriptor returntmp;
+  RBlockRelationAnalysis taskAnalysis;
+  EffectsAnalysis effectsAnalysis;
+  Accessible accessible;
+
+  public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis, Liveness liveness, BuildStateMachines bsm) {
+    this(state, typeUtil);
+    this.callGraph=callGraph;
+    this.OoOJava=true;
+    this.taskAnalysis=taskAnalysis;
+    this.effectsAnalysis=new EffectsAnalysis();
+    effectsAnalysis.state=state;
+    effectsAnalysis.buildStateMachines=bsm;
+    accessible=new Accessible(state, callGraph, taskAnalysis, liveness);
+    accessible.doAnalysis();
+    State.logEvent("Done Writing Accessible Analysis");
+  }
 
   public Pointer(State state, TypeUtil typeUtil) {
     this.state=state;
@@ -34,6 +66,11 @@ public class Pointer {
     this.toprocess=new LinkedList<Delta>();
     ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.ObjectClass);
     this.returntmp=new TempDescriptor("RETURNVAL", stringcd);
+    this.mustProcess=new HashSet<FlatNode>();
+  }
+
+  public EffectsAnalysis getEffectsAnalysis() {
+    return effectsAnalysis;
   }
 
   public BasicBlock getBBlock(FlatMethod fm) {
@@ -72,7 +109,13 @@ public class Pointer {
     return delta;
   }
 
+
+  public Graph getGraph(FlatNode fn) {
+    return graphMap.get(fn);
+  }
+
   public void doAnalysis() {
+
     toprocess.add(buildInitialContext());
     nextdelta:
     while(!toprocess.isEmpty()) {
@@ -104,23 +147,44 @@ public class Pointer {
       if (!init&&delta.isEmpty())
        continue nextdelta;
       
+      int lasti=-1;
       //Compute delta at exit of each node
       for(int i=startindex; i<nodes.size();i++) {
        FlatNode currNode=nodes.get(i);
        //System.out.println("Start Processing "+currNode);
+
        if (!graphMap.containsKey(currNode)) {
-         if (isNEEDED(currNode))
+         if (isNEEDED(currNode)) {
            graphMap.put(currNode, new Graph(graph));
-         else {
-           if (i==0) {
-             //base graph works for us
-             graphMap.put(currNode, new Graph(graph));
-           } else {
-             //just use previous graph
-             graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+         } else {
+           boolean fallthru=true;
+           if (isINACC(currNode)&&((lasti==-1)||(lasti==i))) {
+             if (lasti==-1) {
+               for(lasti=nodes.size()-1;lasti>=i;lasti--) {
+                 FlatNode scurrNode=nodes.get(lasti);
+                 if (isNEEDED(scurrNode)||isINACC(scurrNode)) {
+                   break;
+                 }
+               }
+             }
+             if (i==lasti) {
+               mustProcess.add(currNode);
+               graphMap.put(currNode, new Graph(graph));
+               fallthru=false;
+             }
+           }
+           if (fallthru) {
+             if (i==0) {
+               //base graph works for us
+               graphMap.put(currNode, new Graph(graph));
+             } else {
+               //just use previous graph
+               graphMap.put(currNode, graphMap.get(nodes.get(i-1)));
+             }
            }
          }
        }
+
        nodeGraph=graphMap.get(currNode);
        delta=processNode(bblock, i, currNode, delta, nodeGraph);
        //System.out.println("Processing "+currNode+" and generating delta:");
@@ -148,6 +212,14 @@ public class Pointer {
        debugindex++;
       } 
     }
+
+    State.logEvent("Done With Pointer Analysis");
+
+
+    if (OoOJava) {
+      effectsAnalysis.buildStateMachines.writeStateMachines();
+      State.logEvent("Done Writing State Machines");
+    }
   }
 
   void plotGraph(Graph g, String name) {
@@ -198,24 +270,14 @@ public class Pointer {
       
       /* Compute ages */
       if (graph.oldNodes.containsKey(node)) {
-
+       if (graph.oldNodes.get(node).booleanValue())
+         newDelta.addOldNodes.put(node, Boolean.TRUE);
       } else if (graph.parent.oldNodes.containsKey(node)) {
        //parent graphs only contain true...no need to check
        newDelta.addOldNodes.put(node, Boolean.TRUE);
       }
     }
     
-    for(AllocNode node:graph.oldNodes.keySet()) {
-      if (graph.oldNodes.get(node).booleanValue())
-       newDelta.addOldNodes.put(node, Boolean.TRUE);
-    }
-
-    for(AllocNode node:graph.parent.oldNodes.keySet()) {
-      //make sure child doesn't override
-      if (!graph.oldNodes.containsKey(node))
-       newDelta.addOldNodes.put(node, Boolean.TRUE);
-    }
-
     newDelta.addNodeAges.addAll(graph.nodeAges);
     newDelta.addNodeAges.addAll(graph.parent.nodeAges);
   }
@@ -373,12 +435,14 @@ public class Pointer {
     case FKind.FlatSetFieldNode:
     case FKind.FlatSetElementNode:
       return processSetFieldElementNode(node, delta, newgraph);
+    case FKind.FlatSESEEnterNode:
+      return processSESEEnterNode((FlatSESEEnterNode) node, delta, newgraph);
+    case FKind.FlatSESEExitNode:
+      return processSESEExitNode((FlatSESEExitNode) node, delta, newgraph);
     case FKind.FlatMethod:
     case FKind.FlatExit:
     case FKind.FlatBackEdge:
     case FKind.FlatGenReachNode:
-    case FKind.FlatSESEEnterNode:
-    case FKind.FlatSESEExitNode:
       return processFlatNop(node, delta, newgraph);
     case FKind.FlatCall:
       return processFlatCall(bblock, index, (FlatCall) node, delta, newgraph);
@@ -387,6 +451,156 @@ public class Pointer {
     }
   }
 
+  Delta processSESEEnterNode(FlatSESEEnterNode sese, Delta delta, Graph graph) {
+    if (!OoOJava)
+      return processFlatNop(sese, delta, graph);
+    if (delta.getInit()) {
+      removeInitTaints(null, delta, graph);
+      for (TempDescriptor tmp:sese.getInVarSet()) {
+       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       MySet<Edge> edges=GraphManip.getEdges(graph, delta, tmp);
+       for(Edge e:edges) {
+         Edge newe=e.addTaint(taint);
+         delta.addVarEdge(newe);
+       }
+      }
+    } else {
+      removeDiffTaints(null, delta);
+      for (TempDescriptor tmp:sese.getInVarSet()) {
+       Taint taint=Taint.factory(sese,  null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       MySet<Edge> edges=GraphManip.getDiffEdges(delta, tmp);
+       for(Edge e:edges) {
+         Edge newe=e.addTaint(taint);
+         delta.addVarEdge(newe);
+       }
+      }
+    }
+
+
+    applyDiffs(graph, delta);
+    return delta;
+  }
+  
+  private boolean isRecursive(FlatSESEEnterNode sese) {
+    MethodDescriptor md=sese.getmdEnclosing();
+    boolean isrecursive=callGraph.getCalleeSet(md).contains(md);
+    return isrecursive;
+  }
+
+  Delta processSESEExitNode(FlatSESEExitNode seseexit, Delta delta, Graph graph) {
+    if (!OoOJava)
+      return processFlatNop(seseexit, delta, graph);
+    FlatSESEEnterNode sese=seseexit.getFlatEnter();
+    //Strip Taints from this SESE
+    if (delta.getInit()) {
+      removeInitTaints(isRecursive(sese)?null:sese, delta, graph);
+    } else {
+      removeDiffTaints(isRecursive(sese)?null:sese, delta);
+    }
+    applyDiffs(graph, delta);
+    return delta;
+  }
+  
+  void removeDiffTaints(FlatSESEEnterNode sese, Delta delta) {
+    //Start with variable edges
+    {
+      MySet<Edge> edgestoadd=new MySet<Edge>();
+      MySet<Edge> edgestoremove=new MySet<Edge>();
+      
+      //Process base diff edges
+      processEdgeMap(sese, delta.basevaredge, null, delta.varedgeremove, edgestoremove, edgestoadd); 
+      //Process delta edges
+      processEdgeMap(sese, delta.varedgeadd, null, null, edgestoremove, edgestoadd); 
+      for(Edge e:edgestoremove) {
+       delta.removeVarEdge(e);
+      }
+      for(Edge e:edgestoadd) {
+       delta.addVarEdge(e);
+      }
+    }
+
+    //Now do heap edges
+    {
+      MySet<Edge> edgestoadd=new MySet<Edge>();
+      MySet<Edge> edgestoremove=new MySet<Edge>();
+
+      //Process base diff edges
+      processEdgeMap(sese, delta.baseheapedge, null, delta.heapedgeremove, edgestoremove, edgestoadd); 
+      //Process delta edges
+      processEdgeMap(sese, delta.heapedgeadd, null, null, edgestoremove, edgestoadd); 
+      for(Edge e:edgestoremove) {
+       delta.removeHeapEdge(e);
+      }
+      for(Edge e:edgestoadd) {
+       delta.addHeapEdge(e);
+      }
+    }
+  }
+
+  void removeInitTaints(FlatSESEEnterNode sese, Delta delta, Graph graph) {
+    //Start with variable edges
+    {
+      MySet<Edge> edgestoadd=new MySet<Edge>();
+      MySet<Edge> edgestoremove=new MySet<Edge>();
+      
+      //Process parent edges
+      processEdgeMap(sese, graph.parent.varMap, graph.varMap, delta.varedgeremove, edgestoremove, edgestoadd);
+      //Process graph edges
+      processEdgeMap(sese, graph.varMap, null, delta.varedgeremove, edgestoremove, edgestoadd); 
+      //Process delta edges
+      processEdgeMap(sese, delta.varedgeadd, null, null, edgestoremove, edgestoadd); 
+      for(Edge e:edgestoremove) {
+       delta.removeVarEdge(e);
+      }
+      for(Edge e:edgestoadd) {
+       delta.addVarEdge(e);
+      }
+    }
+
+    //Now do heap edges
+    {
+      MySet<Edge> edgestoadd=new MySet<Edge>();
+      MySet<Edge> edgestoremove=new MySet<Edge>();
+
+      //Process parent edges
+      processEdgeMap(sese, graph.parent.nodeMap, graph.nodeMap, delta.heapedgeremove, edgestoremove, edgestoadd);
+      //Process graph edges
+      processEdgeMap(sese, graph.nodeMap, null, delta.heapedgeremove, edgestoremove, edgestoadd); 
+      //Process delta edges
+      processEdgeMap(sese, delta.heapedgeadd, null, null, edgestoremove, edgestoadd); 
+      for(Edge e:edgestoremove) {
+       delta.removeHeapEdge(e);
+      }
+      for(Edge e:edgestoadd) {
+       delta.addHeapEdge(e);
+      }
+    }
+  }
+
+  void processEdgeMap(FlatSESEEnterNode sese, HashMap<?, MySet<Edge>> edgemap, HashMap<?, MySet<Edge>> childmap, HashMap<?, MySet<Edge>> removemap, MySet<Edge> edgestoremove, MySet<Edge> edgestoadd) {
+    for(Map.Entry<?, MySet<Edge>> entry:edgemap.entrySet()) {
+      //If the parent map exists and overrides this entry, skip it
+      if (childmap!=null&&childmap.containsKey(entry.getKey()))
+       continue;
+      for(Edge e:entry.getValue()) {
+       //check whether this edge has been removed
+       if (removemap!=null&&removemap.containsKey(entry.getKey())&&
+           removemap.get(entry.getKey()).contains(e))
+         continue;
+       //have real edge
+       TaintSet ts=e.getTaints();
+       TaintSet newts=null;
+       //update non-null taint set
+       if (ts!=null)
+         newts=Canonical.removeInContextTaintsNP(ts, sese);
+       if (newts!=null) {
+         edgestoremove.add(e);
+         edgestoadd.add(e.changeTaintSet(newts));
+       }
+      }
+    }
+  }
+
   /* This function compute the edges for the this variable for a
    * callee if it exists. */
 
@@ -438,7 +652,7 @@ public class Pointer {
        AllocNode node=tovisit.pop();
        MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
        if (!edges.isEmpty()) {
-         newDelta.heapedgeadd.put(node, edges);
+         newDelta.heapedgeadd.put(node, Edge.makeOld(edges));
          edgeset.addAll(edges);
          for(Edge e:edges) {
            if (!nodeset.contains(e.dst)&&(oldnodeset==null||!oldnodeset.contains(e.dst))) {
@@ -454,7 +668,7 @@ public class Pointer {
     TempDescriptor tmpthis=fcall.getThis();
     MethodDescriptor md=fcall.getMethod();
     HashSet<MethodDescriptor> targets=new HashSet<MethodDescriptor>();
-    if (md.isStatic()) {
+    if (md.isStatic()||fcall.getSuper()) {
       targets.add(md);
     } else {
       //Compute Edges
@@ -658,6 +872,8 @@ public class Pointer {
       graph.callTargets=newtargets;
       graph.callNodeAges=new HashSet<AllocNode>();
       graph.callOldNodes=new HashSet<AllocNode>();
+      graph.callNewEdges=new HashMap<AllocNode, MySet<Edge>>();
+      graph.callOldEdges=new HashMap<Edge,MySet<Edge>>();
 
       //Apply diffs to graph
       applyDiffs(graph, delta, true);
@@ -703,7 +919,7 @@ public class Pointer {
        if (!newDelta.heapedgeadd.containsKey(src)) {
          newDelta.heapedgeadd.put(src, new MySet<Edge>());
        }
-       newDelta.heapedgeadd.get(src).add(e);
+       newDelta.heapedgeadd.get(src).add(e.makeOld());
        if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) {
          nodeset.add(e.dst);
          tovisit.add(e.dst);
@@ -715,6 +931,7 @@ public class Pointer {
       //Compute call targets
       HashSet<MethodDescriptor> newtargets=computeTargets(fcall, newDelta);
       graph.callTargets.addAll(newtargets);
+
       //add in new nodeset and edgeset
       oldnodeset.addAll(nodeset);
       oldedgeset.addAll(edgeset);
@@ -731,7 +948,36 @@ public class Pointer {
 
       //Move new edges that should be summarized
       processSummarization(graph, delta);
-      
+
+      Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
+      //Check if the new nodes allow us to insert a new edge
+      for(AllocNode node:nodeset) {
+       if (graph.callNewEdges.containsKey(node)) {
+         for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+           Edge e=eit.next();
+           if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+               (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+             Edge edgetoadd=e.copy();//we need our own copy to modify below
+             eit.remove();
+             if (seseCallers!=null)
+               edgetoadd.taintModify(seseCallers);
+             mergeCallEdge(graph, delta, edgetoadd);
+           }
+         }
+       }
+      }
+
+      for(Edge e:edgeset) {
+       //See if these edges would allow an old edge to be added
+       if (graph.callOldEdges.containsKey(e)) {
+         for(Edge adde:graph.callOldEdges.get(e)) {
+           Edge ecopy=adde.copy();
+           ecopy.statuspredicate=e.statuspredicate;
+           mergeCallEdge(graph, delta, ecopy);
+         }
+       }
+      }
+
       //Add in new external edges
       graph.externalEdgeSet.addAll(externaledgeset);
       //Apply diffs to graph
@@ -768,13 +1014,18 @@ public class Pointer {
       }
     }
     for(Edge e:edgestoremove) {
-      delta.removeVarEdge(e);
+      if (!graph.callerEdges.contains(e))
+       delta.removeVarEdge(e);
     }
     for(Edge e:edgestoadd) {
       delta.addVarEdge(e);
     }
   }
   
+  public Alloc getAllocationSiteFromFlatNew(FlatNew node) {
+    return allocFactory.getAllocNode(node, false).getAllocSite();
+  }
   void processSumHeapEdgeSet(HashMap<AllocNode, MySet<Edge>> map, Delta delta, Graph graph) {
     MySet<Edge> edgestoadd=new MySet<Edge>();
     MySet<Edge> edgestoremove=new MySet<Edge>();
@@ -801,7 +1052,8 @@ public class Pointer {
       }
     }
     for(Edge e:edgestoremove) {
-      delta.removeHeapEdge(e);
+      if (!graph.callerEdges.contains(e))
+       delta.removeHeapEdge(e);
     }
     for(Edge e:edgestoadd) {
       delta.addHeapEdge(e);
@@ -846,6 +1098,7 @@ public class Pointer {
     Graph oldgraph=(ppoint.getIndex()==0)?
       bbgraphMap.get(bblock):
       graphMap.get(nodes.get(ppoint.getIndex()-1));
+    Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
 
     //Age outside nodes if necessary
     for(Iterator<AllocNode> nodeit=delta.addNodeAges.iterator();nodeit.hasNext();) {
@@ -858,24 +1111,62 @@ public class Pointer {
        /* Need to age node in existing graph*/
        summarizeInGraph(graph, newDelta, node);
       }
+      if (graph.callNewEdges.containsKey(node)) {
+       for(Iterator<Edge> eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) {
+         Edge e=eit.next();
+         if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+             (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+           Edge edgetoadd=e.copy();//we need our own copy to modify below
+           eit.remove();
+           if (seseCallers!=null)
+             edgetoadd.taintModify(seseCallers);
+           mergeCallEdge(graph, newDelta, edgetoadd);
+         }
+       }
+      }
     }
+
     //Add heap edges in
     for(Map.Entry<AllocNode, MySet<Edge>> entry:delta.heapedgeadd.entrySet()) {
       for(Edge e:entry.getValue()) {
        boolean addedge=false;
        Edge edgetoadd=null;
        if (e.statuspredicate==Edge.NEW) {
-         edgetoadd=e;
+         if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&&
+             (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) {
+           edgetoadd=e.copy();//we need our own copy to modify below
+         } else {
+           graph.addCallEdge(e);
+         }
        } else {
-         Edge origEdgeKey=e.makeStatus(allocFactory);
-         if (oldgraph.nodeMap.containsKey(origEdgeKey.src)&&
-             oldgraph.nodeMap.get(origEdgeKey.src).contains(origEdgeKey)) {
-           Edge origEdge=oldgraph.nodeMap.get(origEdgeKey.src).get(origEdgeKey);
-           //copy the predicate
-           origEdgeKey.statuspredicate=origEdge.statuspredicate;
-           edgetoadd=origEdgeKey;
+         Edge[] edgeArray=e.makeStatus(allocFactory);
+
+         int statuspredicate=0;
+         for(int i=0;i<edgeArray.length;i++) {
+           Edge origEdgeKey=edgeArray[i];
+           if (graph.reachEdge.contains(origEdgeKey)) {
+             Edge origEdge=graph.reachEdge.get(origEdgeKey);
+             //copy the predicate
+             statuspredicate=statuspredicate|origEdge.statuspredicate;
+           }
+           if (!graph.callOldEdges.containsKey(origEdgeKey)) {
+             graph.callOldEdges.put(origEdgeKey, new MySet<Edge>());
+           }
+           if (graph.callOldEdges.get(origEdgeKey).contains(e)) {
+             Edge olde=graph.callOldEdges.get(origEdgeKey).get(e);
+             graph.callOldEdges.get(origEdgeKey).add(olde.merge(e));
+           } else {
+             graph.callOldEdges.get(origEdgeKey).add(e);
+           }
+         }
+         if (statuspredicate!=0) {
+           Edge newe=e.copy();
+           newe.statuspredicate=statuspredicate;
+           edgetoadd=newe;
          }
        }
+       if (seseCallers!=null&&edgetoadd!=null)
+         edgetoadd.taintModify(seseCallers);
        mergeCallEdge(graph, newDelta, edgetoadd);
       }
     }
@@ -889,6 +1180,8 @@ public class Pointer {
        for(Edge e:returnedge) {
          Edge newedge=e.copy();
          newedge.srcvar=fcall.getReturnTemp();
+         if (seseCallers!=null)
+           newedge.taintModify(seseCallers);
          if (graph.getEdges(fcall.getReturnTemp())==null||!graph.getEdges(fcall.getReturnTemp()).contains(newedge))
            newDelta.addEdge(newedge);
        }
@@ -912,13 +1205,14 @@ public class Pointer {
 
   public void mergeCallEdge(Graph graph, Delta newDelta, Edge edgetoadd) {
     if (edgetoadd!=null) {
-      Edge match=graph.getMatch(edgetoadd);
+      newDelta.addEdgeClear(edgetoadd);
 
+      Edge match=graph.getMatch(edgetoadd);
+      
       if (match==null||!match.subsumes(edgetoadd)) {
        Edge mergededge=edgetoadd.merge(match);
        newDelta.addEdge(mergededge);
        graph.callerEdges.add(mergededge);
-       //System.out.println("ADDING: "+ mergededge);
       }
     }
   }
@@ -1019,7 +1313,7 @@ public class Pointer {
        else
          graph.nodeMap.put(node, new MySet<Edge>());
       }
-      graph.nodeMap.get(node).addAll(edgestoadd);
+      Edge.mergeEdgesInto(graph.nodeMap.get(node),edgestoadd);
       if (genbackwards) {
        for(Edge eadd:edgestoadd) {
          if (!graph.backMap.containsKey(eadd.dst))
@@ -1050,7 +1344,7 @@ public class Pointer {
       TempDescriptor tmp=e.getKey();
       MySet<Edge> edgestoadd=e.getValue();
       if (graph.varMap.containsKey(tmp)) {
-       graph.varMap.get(tmp).addAll(edgestoadd);
+       Edge.mergeEdgesInto(graph.varMap.get(tmp), edgestoadd);
       } else 
        graph.varMap.put(tmp, (MySet<Edge>) edgestoadd.clone());
       if (genbackwards) {
@@ -1074,6 +1368,30 @@ public class Pointer {
     }
   }
 
+  boolean isINACC(FlatNode node) {
+    if (!OoOJava)
+      return false;
+    switch(node.kind()) {
+    case FKind.FlatSetFieldNode: {
+      FlatSetFieldNode n=(FlatSetFieldNode)node;
+      return !accessible.isAccessible(n, n.getDst());
+    }
+    case FKind.FlatSetElementNode: {
+      FlatSetElementNode n=(FlatSetElementNode)node;
+      return !accessible.isAccessible(n, n.getDst());
+    }
+    case FKind.FlatFieldNode: {
+      FlatFieldNode n=(FlatFieldNode)node;
+      return !accessible.isAccessible(n, n.getSrc());
+    }
+    case FKind.FlatElementNode: {
+      FlatElementNode n=(FlatElementNode)node;
+      return !accessible.isAccessible(n, n.getSrc());
+    }
+    }
+    return false;
+  }
+
   Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
     TempDescriptor src;
     FieldDescriptor fd;
@@ -1089,46 +1407,92 @@ public class Pointer {
       fd=ffn.getField();
       dst=ffn.getDst();
     }
-    //Do nothing for non pointers
-    if (!src.getType().isPtr())
-      return delta;
 
     if (delta.getInit()) {
-      HashSet<AllocNode> srcNodes=GraphManip.getNodes(graph, delta, src);
-      HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
-      MySet<Edge> edgesToAdd=GraphManip.genEdges(dstNodes, fd, srcNodes);
+      MySet<Edge> dstEdges=GraphManip.getEdges(graph, delta, dst);
+
+      if (OoOJava&&!accessible.isAccessible(node, dst)) {
+       Taint dstStallTaint=Taint.factory(node,  dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       dstEdges=Edge.taintAll(dstEdges, dstStallTaint);
+       updateVarDelta(graph, delta, dst, dstEdges, null);
+      }
+      if (OoOJava) {
+       effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node);
+      }
+
+      //Do nothing for non pointers
+      if (!src.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
+      if (OoOJava&&!accessible.isAccessible(node, src)) {
+       Taint srcStallTaint=Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       srcEdges=Edge.taintAll(srcEdges, srcStallTaint);
+       updateVarDelta(graph, delta, src, srcEdges, null);
+      }
+
+      MySet<Edge> edgesToAdd=GraphManip.genEdges(dstEdges, fd, srcEdges);
       MySet<Edge> edgesToRemove=null;
-      if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()&&fd!=null) {
+      if (dstEdges.size()==1&&!dstEdges.iterator().next().dst.isSummary()&&fd!=null) {
        /* Can do a strong update */
-       edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
+       edgesToRemove=GraphManip.getEdges(graph, delta, dstEdges, fd);
        graph.strongUpdateSet=edgesToRemove;
       } else
        graph.strongUpdateSet=new MySet<Edge>();
+
       /* Update diff */
       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     } else {
-      /* First look at new sources */
+      MySet<Edge> newDstEdges=GraphManip.getDiffEdges(delta, dst);
+
+      if (OoOJava&&!accessible.isAccessible(node, dst)) {
+       Taint dstStallTaint=Taint.factory(node,  dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       newDstEdges=Edge.taintAll(newDstEdges, dstStallTaint);
+       updateVarDelta(graph, delta, dst, newDstEdges, null);
+      }
+
+      if (OoOJava) {
+       effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node);
+      }
+
+      if (!src.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      /* Next look at new sources */
+
       MySet<Edge> edgesToAdd=new MySet<Edge>();
-      HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
-      HashSet<AllocNode> srcNodes=GraphManip.getNodes(graph, delta, src);
+      MySet<Edge> newSrcEdges=GraphManip.getDiffEdges(delta, src);
+      MySet<Edge> srcEdges=GraphManip.getEdges(graph, delta, src);
       HashSet<AllocNode> dstNodes=GraphManip.getNodes(graph, delta, dst);
-      HashSet<AllocNode> newDstNodes=GraphManip.getDiffNodes(delta, dst);
 
+      if (OoOJava&&!accessible.isAccessible(node, src)) {
+       Taint srcStallTaint=Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty);
+       newSrcEdges=Edge.taintAll(newSrcEdges, srcStallTaint);
+       updateVarDelta(graph, delta, src, newSrcEdges, null);
+      }
 
       MySet<Edge> edgesToRemove=null;
-      if (newDstNodes.size()!=0) {
+      if (newDstEdges.size()!=0) {
        if (dstNodes.size()>1&&!dstNodes.iterator().next().isSummary()&&fd!=null) {
          /* Need to undo strong update */
          if (graph.strongUpdateSet!=null) {
            edgesToAdd.addAll(graph.strongUpdateSet);
            graph.strongUpdateSet=null; //Prevent future strong updates
          }
-       } else if (dstNodes.size()==1&&newDstNodes.size()==1&&!newDstNodes.iterator().next().isSummary()&&graph.strongUpdateSet!=null&&fd!=null) {
+       } else if (dstNodes.size()==1&&newDstEdges.size()==1&&!newDstEdges.iterator().next().dst.isSummary()&&graph.strongUpdateSet!=null&&fd!=null) {
          edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd);
          graph.strongUpdateSet.addAll(edgesToRemove);
        }
-       edgesToAdd.addAll(GraphManip.genEdges(newDstNodes, fd, srcNodes));
+       Edge.mergeEdgesInto(edgesToAdd, GraphManip.genEdges(newDstEdges, fd, srcEdges));
       }
 
       //Kill new edges
@@ -1142,7 +1506,7 @@ public class Pointer {
       }
 
       //Next look at new destinations
-      edgesToAdd.addAll(GraphManip.genEdges(dstNodes, fd, newSrcNodes));
+      Edge.mergeEdgesInto(edgesToAdd, GraphManip.genEdges(dstNodes, fd, newSrcEdges));
 
       /* Update diff */
       updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove);
@@ -1173,17 +1537,17 @@ public class Pointer {
       dst=fcn.getDst();
     }
     if (delta.getInit()) {
-      HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
-      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, srcnodes);
+      MySet<Edge> srcedges=GraphManip.getEdges(graph, delta, src);
+      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, srcedges);
       MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     } else {
       /* First compute new src nodes */
-      HashSet<AllocNode> newSrcNodes=GraphManip.getDiffNodes(delta, src);
+      MySet<Edge> newSrcEdges=GraphManip.getDiffEdges(delta, src);
 
       /* Compute the union, and then the set of edges */
-      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, newSrcNodes);
+      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, newSrcEdges);
       
       /* Compute set of edges to remove */
       MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
@@ -1199,6 +1563,8 @@ public class Pointer {
     TempDescriptor src;
     FieldDescriptor fd;
     TempDescriptor dst;
+    TaintSet taint=null;
+
     if (node.kind()==FKind.FlatElementNode) {
       FlatElementNode fen=(FlatElementNode) node;
       src=fen.getSrc();
@@ -1210,36 +1576,65 @@ public class Pointer {
       fd=ffn.getField();
       dst=ffn.getDst();
     }
+    if (OoOJava&&!accessible.isAccessible(node, src)) {
+      taint=TaintSet.factory(Taint.factory(node,  src, AllocFactory.dummySite, null, ReachGraph.predsEmpty));
+    }
+
     //Do nothing for non pointers
-    if (!dst.getType().isPtr())
-      return delta;
     if (delta.getInit()) {
-      HashSet<AllocNode> srcnodes=GraphManip.getNodes(graph, delta, src);
-      HashSet<AllocNode> fdnodes=GraphManip.getNodes(graph, delta, srcnodes, fd);
-      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, fdnodes);
+      MySet<Edge> srcedges=GraphManip.getEdges(graph, delta, src);
+      if (OoOJava) {
+       if (taint!=null) {
+         srcedges=Edge.taintAll(srcedges, taint);
+         updateVarDelta(graph, delta, src, srcedges, null);
+       }
+       effectsAnalysis.analyzeFlatFieldNode(srcedges, fd, node);
+      }
+      if (!dst.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
+
+      MySet<Edge> edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node);
       MySet<Edge> edgesToRemove=GraphManip.getEdges(graph, delta, dst);
+
       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     } else {
+      MySet<Edge> newsrcedges=GraphManip.getDiffEdges(delta, src);
+      if (OoOJava) {
+       if (taint!=null) {
+         newsrcedges=Edge.taintAll(newsrcedges, taint);
+         updateVarDelta(graph, delta, src, newsrcedges, null);
+       }
+       effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node);
+      }
+      if (!dst.getType().isPtr()) {
+       if (mustProcess.contains(node)) {
+         applyDiffs(graph, delta);
+       }
+       return delta;
+      }
       /* First compute new objects we read fields of */
-      HashSet<AllocNode> allsrcnodes=GraphManip.getNodes(graph, delta, src);
-      HashSet<AllocNode> difffdnodes=GraphManip.getDiffNodes(delta, allsrcnodes, fd);     
+      MySet<Edge> allsrcedges=GraphManip.getEdges(graph, delta, src);
+      MySet<Edge> edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node);
       /* Next compute new targets of fields */
-      HashSet<AllocNode> newsrcnodes=GraphManip.getDiffNodes(delta, src);
-      HashSet<AllocNode> newfdnodes=GraphManip.getNodes(graph, delta, newsrcnodes, fd);
+      MySet<Edge> newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node);
+
       /* Compute the union, and then the set of edges */
-      HashSet<AllocNode> newTargets=new HashSet<AllocNode>();
-      newTargets.addAll(newfdnodes);
-      newTargets.addAll(difffdnodes);
-      MySet<Edge> edgesToAdd=GraphManip.genEdges(dst, newTargets);      
+      Edge.mergeEdgesInto(edgesToAdd, newfdedges);
       
       /* Compute set of edges to remove */
       MySet<Edge> edgesToRemove=GraphManip.getDiffEdges(delta, dst);      
 
+      
       /* Update diff */
       updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove);
       applyDiffs(graph, delta);
     }
+
     return delta;
   }
 
@@ -1247,21 +1642,31 @@ public class Pointer {
     MySet<Edge> edgeAdd=delta.varedgeadd.get(tmp);
     MySet<Edge> edgeRemove=delta.varedgeremove.get(tmp);
     MySet<Edge> existingEdges=graph.getEdges(tmp);
-    for(Edge e: edgestoRemove) {
-      //remove edge from delta
-      if (edgeAdd!=null)
-       edgeAdd.remove(e);
-      //if the edge is already in the graph, add an explicit remove to the delta
-      if (existingEdges.contains(e))
-       delta.removeVarEdge(e);
-    }
+    if (edgestoRemove!=null)
+      for(Edge e: edgestoRemove) {
+       //remove edge from delta
+       if (edgeAdd!=null)
+         edgeAdd.remove(e);
+       //if the edge is already in the graph, add an explicit remove to the delta
+       if (existingEdges.contains(e))
+         delta.removeVarEdge(e);
+      }
     for(Edge e: edgestoAdd) {
       //Remove the edge from the remove set
       if (edgeRemove!=null)
        edgeRemove.remove(e);
       //Explicitly add it to the add set unless it is already in the graph
-      if (!existingEdges.contains(e)&&typeUtil.isSuperorType(tmp.getType(),e.dst.getType()))
-       delta.addVarEdge(e);
+      if (typeUtil.isSuperorType(tmp.getType(), e.dst.getType())) {
+       if (!existingEdges.contains(e)) {
+         delta.addVarEdge(e);
+       } else {
+         //See if the old edge subsumes the new one
+         Edge olde=existingEdges.get(e);
+         if (!olde.subsumes(e)) {
+           delta.addVarEdge(olde.merge(e));
+         }
+       }
+      }
     }
   }
 
@@ -1288,8 +1693,14 @@ public class Pointer {
        if (edgeRemove!=null)
          edgeRemove.remove(e);
        //Explicitly add it to the add set unless it is already in the graph
-       if (!existingEdges.contains(e)||!existingEdges.get(e).isNew()) {
+       if (!existingEdges.contains(e)) {
          delta.addHeapEdge(e);
+       } else {
+         //See if the old edge subsumes the new one
+         Edge olde=existingEdges.get(e);
+         if (!olde.subsumes(e)) {
+           delta.addHeapEdge(olde.merge(e));
+         }
        }
       }
   }
@@ -1415,9 +1826,10 @@ public class Pointer {
        delta.addOldNodes.put(single, Boolean.FALSE);
       }
       
-      //Apply incoming diffs to graph
-      applyDiffs(graph, delta);      
     }
+    //Apply incoming diffs to graph
+    applyDiffs(graph, delta);      
+
     return delta;
   }
 
@@ -1596,6 +2008,13 @@ public class Pointer {
            //We have a new edge
            diffedges.add(e);
            dstedges.add(e);
+         } else {
+           Edge origedge=dstedges.get(e);
+           if (!origedge.subsumes(e)) {
+             Edge mergededge=origedge.merge(e);
+             diffedges.add(mergededge);
+             dstedges.add(mergededge);
+           }
          }
        }
        //Done with edge set...