more changes
authorbdemsky <bdemsky>
Tue, 25 Jan 2011 00:37:09 +0000 (00:37 +0000)
committerbdemsky <bdemsky>
Tue, 25 Jan 2011 00:37:09 +0000 (00:37 +0000)
Robust/src/Analysis/Pointer/AllocFactory.java
Robust/src/Analysis/Pointer/Delta.java
Robust/src/Analysis/Pointer/Graph.java
Robust/src/Analysis/Pointer/Pointer.java
Robust/src/Analysis/Pointer/Util.java [new file with mode: 0644]

index 74a4f20e33749db34094ae074dd9c51fcf7dd99c..98b130e70dc3f44fe15253d18b673ba97c99fbc5 100644 (file)
@@ -30,7 +30,8 @@ public class AllocFactory {
   }
 
   public AllocFactory(State state, TypeUtil typeUtil) {
-    allocMap=new HashMap<FlatNode, Integer>();
+    allocMap=new HashMap<FlatNew, Integer>();
+    allocNodeMap=new HashMap<AllocNode, AllocNode>();
     this.typeUtil=typeUtil;
     ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.StringClass);
     TypeDescriptor stringtd=new TypeDescriptor(stringcd);
@@ -38,8 +39,27 @@ public class AllocFactory {
     StringArray=new AllocNode(0, stringarraytd, false);
     Strings=new AllocNode(1, stringtd, true);
   }
-  
-  HashMap<FlatNode, Integer> allocMap;
+
+  public int getSiteNumber(FlatNew node) {
+    if (allocMap.containsKey(node))
+      return allocMap.get(node);
+    int index=siteCounter++;
+    allocMap.put(node, index);
+    return index;
+  }
+
+  public AllocNode getAllocNode(FlatNew node, boolean isSummary) {
+    int site=getSiteNumber();
+    AllocNode key=new AllocNode(site, node.getType(), isSummary);
+    if (!allocNodeMap.containsKey(key)) {
+      allocNodeMap.put(key, key);
+      return key;
+    } else
+      return allocNodeMap.get(key);
+  }
+
+  HashMap<AllocNode, AllocNode> allocNodeMap;
+  HashMap<FlatNew, Integer> allocMap;
   TypeUtil typeUtil;
   int siteCounter=2;
 
index 67b94143400711cb69c4179ddb5c794218b71fc2..e7e7be70808fbda346e67138b8fe7d56016c4b39 100644 (file)
@@ -5,36 +5,27 @@ import Analysis.Pointer.BasicBlock.BBlock;
 import IR.Flat.*;
 
 public class Delta {
-  HashMap<AllocNode, Vector<Edge>> heapedgeremove;
-  HashMap<TempDescriptor, Vector<Edge>> varedgeremove;
-  HashMap<AllocNode, Vector<Edge>> heapedgeadd;
-  HashMap<TempDescriptor, Vector<Edge>> varedgeadd;
+  HashMap<AllocNode, HashSet<Edge>> heapedgeremove;
+  HashMap<AllocNode, HashSet<Edge>> heapedgeadd;
+  HashMap<TempDescriptor, HashSet<Edge>> varedgeadd;
+  HashMap<TempDescriptor, HashSet<Edge>> varedgeremove;
+  HashMap<AllocNode, HashSet<Edge>> baseheapedge;
+  HashMap<TempDescriptor, HashSet<Edge>> basevaredge;
 
   boolean init;
   BBlock block;
 
+  /* Init is set for false for delta propagations inside of one basic block.
+   */
+  
   public Delta(BBlock block, boolean init) {
-    this.heapedgeadd=new HashMap<AllocNode, Vector<Edge>>();
-    this.varedgeadd=new HashMap<TempDescriptor, Vector<Edge>>();
-    this.heapedgeremove=new HashMap<AllocNode, Vector<Edge>>();
-    this.varedgeremove=new HashMap<TempDescriptor, Vector<Edge>>();
     this.init=init;
-    this.block=block;
-  }
-
-  public void addHeapEdge(AllocNode node, Edge e) {
-    if (!heapedgeadd.containsKey(node))
-      heapedgeadd.put(node, new Vector<Edge>());
-    heapedgeadd.get(node).add(e);
-  }
-
-  public void addVarEdge(TempDescriptor tmp, Edge e) {
-    if (!varedgeadd.containsKey(tmp))
-      varedgeadd.put(tmp, new Vector<Edge>());
-    varedgeadd.get(tmp).add(e);
-  }
-
-  public void setBlock(BBlock block) {
+    this.baseheapedge=new HashMap<AllocNode, HashSet<Edge>>();
+    this.basevaredge=new HashMap<TempDescriptor, HashSet<Edge>>();
+    this.heapedgeadd=new HashMap<AllocNode, HashSet<Edge>>();
+    this.heapedgeremove=new HashMap<AllocNode, HashSet<Edge>>();
+    this.varedgeadd=new HashMap<TempDescriptor, HashSet<Edge>>();
+    this.varedgeremove=new HashMap<TempDescriptor, HashSet<Edge>>();
     this.block=block;
   }
 
@@ -45,4 +36,8 @@ public class Delta {
   public boolean getInit() {
     return init;
   }
+
+  public void setInit(boolean init) {
+    this.init=init;
+  }
 }
\ No newline at end of file
index d4969e9b7464d9d2b9b1ca50aeade123fa79b376..6f01836a094381c544948205fd6dfad2f685cdf7 100644 (file)
@@ -10,20 +10,24 @@ public class Graph {
    * graph. */
 
   Graph parent;
-  HashSet<TempDescriptor> tempset;
-  HashSet<AllocNode> allocset;
-
-  HashMap<AllocNode, Vector<Edge>> nodeMap;
-  HashMap<TempDescriptor, Vector<Edge>> tmpMap;
+  HashMap<AllocNode, HashSet<Edge>> nodeMap;
+  HashMap<TempDescriptor, HashSet<Edge>> varMap;
+  HashMap<AllocNode, HashSet<Edge>> backMap;
 
   public Graph(Graph parent) {
-    nodeMap=new HashMap<AllocNode, Vector<Edge>>();
-    tmpMap=new HashMap<TempDescriptor, Vector<Edge>>();
-    tempset=new HashSet<TempDescriptor>();
-    allocset=new HashSet<AllocNode>();
-    
+    nodeMap=new HashMap<AllocNode, HashSet<Edge>>();
+    backMap=new HashMap<AllocNode, HashSet<Edge>>();
+    varMap=new HashMap<TempDescriptor, HashSet<Edge>>();
     this.parent=parent;
   }
 
-  
+  public HashSet<Edge> getEdges(AllocNode node) {
+    if (nodeMap.containsKey(node))
+      return nodeMap.get(node);
+    else if (parent!=null&&parent.nodeMap.containsKey(node))
+      return parent.nodeMap.get(node);
+    else return emptySet;
+  }
+
+  public static HashSet<Edge> emptySet=new HashSet<Edge>();
 }
\ No newline at end of file
index 4987ac80524708b14445abae27813f3e661f1d28..5769bd53cbec61c81ba1823cdf29901eff971f8c 100644 (file)
@@ -7,6 +7,7 @@ import Analysis.Pointer.AllocFactory.AllocNode;
 
 public class Pointer {
   HashMap<FlatMethod, BasicBlock> blockMap;
+  HashMap<BBlock, Graph> bbgraphMap;
   HashMap<FlatNode, Graph> graphMap;
   State state;
   TypeUtil typeUtil;
@@ -16,6 +17,7 @@ public class Pointer {
   public Pointer(State state, TypeUtil typeUtil) {
     this.state=state;
     this.blockMap=new HashMap<FlatMethod, BasicBlock>();
+    this.bbgraphMap=new HashMap<BBlock, Graph>();
     this.graphMap=new HashMap<FlatNode, Graph>();
     this.typeUtil=typeUtil;
     this.allocFactory=new AllocFactory(state, typeUtil);
@@ -46,36 +48,255 @@ public class Pointer {
       Delta delta=toprocess.remove();
       BBlock bblock=delta.getBlock();
       Vector<FlatNode> nodes=bblock.nodes();
-      FlatNode firstNode=nodes.get(0);
 
-      //Get graph for first node
-      if (!graphMap.containsKey(firstNode)) {
-       graphMap.put(firstNode, new Graph(null));
+      //Build base graph for entrance to this basic block
+      delta=applyInitDelta(delta, bblock);
+
+      Graph prevGraph=graph;
+      //Compute delta at exit of each node
+      for(int i=0; i<nodes.size();i++) {
+       FlatNode currNode=nodes.get(i);
+       if (!graphMap.containsKey(currNode)) {
+         graphMap.put(currNode, new Graph(graph));
+       }
+       Graph nodeGraph=graphMap.get(currNode);
+       delta=processNode(currNode, delta, prevGraph, nodeGraph);
+       prevgraph=nodeGraph;
+      }
+      //XXXX: Need to generate new delta
+    }    
+  }
+
+  Delta processNode(FlatNode node, Delta delta, Graph newgraph) {
+    switch(node.kind()) {
+    case FKind.FlatNew:
+      return processNewNode(node, delta, newgraph);
+      break;
+    case FKind.FlatCall:
+    case FKind.FlatFieldNode:
+    case FKind.FlatSetFieldNode:
+    case FKind.FlatReturnNode:
+    case FKind.FlatElementNode:
+    case FKind.FlatSetElementNode:
+    case FKind.FlatMethod:
+    case FKind.FlatExit:
+    case FKind.FlatSESEEnterNode:
+    case FKind.FlatSESEExitNode:
+    case FKind.FlatCastNode:
+    case FKind.FlatOpNode:
+      throw new Error("Unimplemented node:"+node);
+      break;
+    default:
+      throw new Error("Unrecognized node:"+node);
+    }
+  }
+
+  void applyDiffs(Graph graph, Delta delta) {
+    //Add hidden base edges
+    for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.baseheapedge) {
+      AllocNode node=e.getKey();
+      HashSet<Edge> edges=e.getValue();
+      if (graph.nodeMap.containsKey(node)) {
+       HashSet<Edge> nodeEdges=graph.nodeMap.get(node);
+       nodeEdges.addAll(edges);
+      }
+    }
+
+    //Remove heap edges
+    for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.heapedgeremove) {
+      AllocNode node=e.getKey();
+      HashSet<Edge> edgestoremove=e.getValue();
+      if (graph.nodeMap.containsKey(node)) {
+       //Just apply diff to current map
+       graph.nodeMap.get(node).removeAll(edgestoremove);
+      } else {
+       //Generate diff from parent graph
+       HashSet<Edge> parentedges=graph.parent.nodeMap.get(node);
+       HashSet<Edge> newedgeset=Util.setSubstract(parentedges, edgestoremove);
+       graph.nodeMap.put(node, newedgeset);
       }
-      Graph graph=graphMap.get(firstNode);
+    }
 
-      //First entrance is special...
-      if (delta.getInit()) {
-       applyInit(delta, graph);
+    //Add heap edges
+    for(Map.Entry<AllocNode, HashSet<Edge>> e: delta.heapedgeadd) {
+      AllocNode node=e.getKey();
+      HashSet<Edge> edgestoadd=e.getValue();
+      //If we have not done a subtract, then 
+      if (!graph.nodeMap.containsKey(node)) {
+       //Copy the parent entry
+       graph.nodeMap.put(node, graph.parent.nodeMap.get(node).clone());
+      }
+      graph.nodeMap.get(node).addAll(edgestoadd);
+    }
+
+    //Remove var edges
+    for(Map.Entry<TempDescriptor, HashSet<Edge>> e: delta.varedgeremove) {
+      TempDescriptor tmp=e.getKey();
+      HashSet<Edge> edgestoremove=e.getValue();
+
+      if (graph.varMap.containsKey(tmp)) {
+       //Just apply diff to current map
+       graph.varMap.get(tmp).removeAll(edgestoremove);
       } else {
-       applyDelta(delta, graph);
+       //Generate diff from parent graph
+       HashSet<Edge> parentedges=graph.parent.varMap.get(node);
+       HashSet<Edge> newedgeset=Util.setSubstract(parentedges, edgestoremove);
+       graph.varMap.put(tmp, newedgeset);
       }
+    }
+
+    //Add var edges
+    for(Map.Entry<TempDescriptor, HashSet<Edge>> e: delta.varedgeadd) {
+      TempDescriptor tmp=e.getKey();
+      HashSet<Edge> edgestoadd=e.getValue();
+      graph.varmap.put(tmp, edgestoadd.clone());
+    }
+  }
+
+  Delta processNewNode(FlatNew node, Delta delta, Graph newgraph) {
+    AllocNode summary=allocFactory.getAllocNode(node, true);
+    AllocNode single=allocFactory.getAllocNode(node, false);
+    TempDescriptor tmp=node.getDst();
       
-      Graph nodeGraph=null;
-      for(int i=1; i<nodes.size();i++) {
-       FlatNode currNode=nodes.get(i);
-       if (!graphMap.containsKey(currNode)) {
-         graphMap.put(currNode, new Graph(graph, nodeGraph));
+    if (delta.getInit()) {
+      //Apply incoming diffs to graph
+      applyDiffs(graph, delta);
+      //Build new Edge
+      Edge e=new Edge(tmp, single);
+      //Build new Edge set
+      HashSet<Edge> newedges=new HashSet<Edge>();
+      newedges.add(e);
+      //Add it into the graph
+      graph.varMap.put(tmp, newedges);
+      //Add it into the diffs
+      delta.varedgeadd.put(tmp, newedges);
+    } else {
+      //Filter var edge additions
+      for(Iterator<Map.Entry<TempDescriptor, HashSet<Edge>>> entryIt=delta.varedgeadd;entryIt.hasNext();) {
+       Map.Entry<TempDescriptor, HashSet<Edge>> entry=entryIt.next();
+       //Check first if this is the tmp we overwrite
+       //Check second if the edge is changed...
+       if (entry.getKey()==tmp)
+         entryIt.remove();
+       else for(Edge edge:entryIt.getValue()) {
+           if (edge.dst==single)
+             edge.dst=summary;
+         }
+      }
+
+      //Filter heap edge additions
+      for(Iterator<Map.Entry<AllocNode, HashSet<Edge>>> entryIt=delta.heapedgeadd;entryIt.hasNext();) {
+       Map.Entry<AllocNode, HashSet<Edge>> entry=entryIt.next();
+       
+      }
+
+      //Get relevant changes
+      HashSet<Edge> edgesadd=delta.heapedgeadd.get(single);
+      HashSet<Edge> edgesremove=delta.heapedgeremove.get(single);
+      HashSet<Edge> baseedges=delta.baseheapedge.get(single);
+      HashSet<Edge> basebackedges=delta.baseheapedge.get(single);
+
+      //Get summary node edges
+      HashSet<Edge> summarynewedgesadd;
+      if (!delta.heapedgeadd.containsKey(summary)) {
+       summarynewedgesadd=new HashSet<Edge>();
+       delta.heapedgeadd.put(summary, summarynewedgesadd);
+      } else
+       summarynewedgesadd=delta.heapedgeadd.get(summary);
+
+      
+
+      //Apply diffs
+      delta.heapedgeremove.put(single, baseedges.clone());
+      delta.heapedgeadd.remove(single);
+      delta.baseheapedge.remove(single);
+
+      //Apply incoming diffs to graph
+      applyDiffs(graph, delta);      
+    }
+  }
+
+  Delta applyInitDelta(Delta delta, BBlock block) {
+    //Apply delta to graph
+    boolean newGraph=false;
+    if (!bbgraphMap.containsKey(block)) {
+      bbgraphMap.put(block, new Graph(null));
+      newGraph=true;
+    }
+    Delta newdelta;
+    Graph graph=bbgraphMap.get(block);
+
+    if (newGraph) {
+      newdelta=new Delta(null, true);
+      //Add in heap edges and throw away original diff
+      graph.nodeMap.putAll(delta.heapedgeadd);
+      //Add in var edges and throw away original diff
+      graph.varMap.putAll(delta.varedgeadd);
+      //Record that this is initial set...
+    } else {
+      newdelta=new Delta(null, false);
+      //merge in heap edges and variables
+      mergeHeapEdges(graph, delta, newdelta);
+      mergeVarEdges(graph, delta, newdelta);
+      //Record that this is a diff
+      newdelta.setInit(false);
+    }
+    return newdelta;
+  }
+
+  /* This function merges in the heap edges.  It updates delta to be
+   * the difference */
+
+  void mergeHeapEdges(Graph graph, Delta delta, Delta newdelta) {
+    //Merge in edges
+    for(Map.Entry<AllocNode, HashSet<Edge>> heapedge:delta.heapedgeadd.entrySet()) {
+      AllocNode nsrc=heapedge.getKey();
+      HashSet<Edge> edges=heapedge.getValue();
+      if (!graph.nodeMap.containsKey(nsrc)) {
+       graph.nodeMap.put(nsrc, new HashSet<Edge>());
+      }
+      HashSet<Edge> dstedges=graph.nodeMap.get(nsrc);
+      HashSet<Edge> diffedges=new HashSet<Edge>();
+      for(Edge e:edges) {
+       if (!dstedges.contains(e)) {
+         //We have a new edge
+         diffedges.add(e);
+         dstedges.add(e);
        }
-       nodeGraph=graphMap.get(currNode);
+      }
+      //Done with edge set...
+      if (diffedges.size()>0) {
+       //completely new
+       newdelta.baseheap.put(nsrc, diffedges);
+      }
+    }
+  }
 
-       if (delta.getInit()) {
-         applyInitDiff(delta, nodeGraph);
-       } else {
-         applyDeltaDiff(delta, nodeGraph);       
+  /* This function merges in the var edges.  It updates delta to be
+   * the difference */
+
+  void mergeVarEdges(Graph graph, Delta delta, Delta newdelta) {
+    //Merge in edges
+    for(Map.Entry<TempDescriptor, HashSet<Edge>> varedge:delta.varedgeadd.entrySet()) {
+      TempDescriptor tmpsrc=varedge.getKey();
+      HashSet<Edge> edges=varedge.getValue();
+      if (!graph.nodeMap.containsKey(tmpsrc)) {
+       graph.nodeMap.put(tmpsrc, new HashSet<Edge>());
+      }
+      HashSet<Edge> dstedges=graph.varMap.get(tmpsrc);
+      HashSet<Edge> diffedges=new HashSet<Edge>();
+      for(Edge e:edges) {
+       if (!dstedges.contains(e)) {
+         //We have a new edge
+         diffedges.add(e);
+         dstedges.add(e);
        }
       }
+      //Done with edge set...
+      if (diffedges.size()>=0) {
+       //completely new
+       newdelta.basevaredge.put(tmpsrc,diffedges);
+      }
     }
-    
   }
 }
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/Util.java b/Robust/src/Analysis/Pointer/Util.java
new file mode 100644 (file)
index 0000000..d9746da
--- /dev/null
@@ -0,0 +1,15 @@
+package Analysis.Pointer;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Util {
+  public static <T> HashSet<T> setSubtract(Set <T> orig, Set<T> sub) {
+    HashSet<T> newset=new HashSet<T>();
+    for(T e: orig) {
+      if (!sub.contains(e))
+       newset.add(e);
+    }
+    return newset;
+  }
+
+}
\ No newline at end of file