more code changes
authorbdemsky <bdemsky>
Thu, 3 Mar 2011 09:10:19 +0000 (09:10 +0000)
committerbdemsky <bdemsky>
Thu, 3 Mar 2011 09:10:19 +0000 (09:10 +0000)
Robust/src/Analysis/Pointer/AllocFactory.java
Robust/src/Analysis/Pointer/Edge.java
Robust/src/Analysis/Pointer/Graph.java
Robust/src/Analysis/Pointer/MySet.java
Robust/src/Analysis/Pointer/Pointer.java

index 67f426ed7bfcaaf1551b7c8878faadae379ced38..46c8c6bd44c8a01d63141c418af020b13499d5dd 100644 (file)
@@ -66,6 +66,16 @@ public class AllocFactory {
       return allocNodeMap.get(key);
   }
 
+  public AllocNode getAllocNode(AllocNode node, boolean isSummary) {
+    int site=node.allocsite;
+    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;
index 41d79bb09a24991426e1292df2efdc8452c1cbc5..49884471179f469ac1b222b4ac35607948020596 100644 (file)
@@ -76,11 +76,28 @@ public class Edge {
     return e;
   }
 
+  public Edge rewrite(AllocNode single, AllocNode summary) {
+    Edge e=copy();
+    if (e.src==single)
+      e.src=summary;
+    if (e.dst==single)
+      e.dst=summary;
+    return e;
+  }
+
   public boolean statusDominates(Edge other) {
     return (statuspredicate==NEW)||
       ((other.statuspredicate|statuspredicate)==statuspredicate);
   }
 
+  public Edge makeStatus(AllocFactory factory) {
+    Edge e=new Edge();
+    e.fd=fd;
+    e.src=factory.getAllocNode(src, (statuspredicate|3)==0);
+    e.dst=factory.getAllocNode(dst, (statuspredicate|5)==0);
+    return e;
+  }
+
   public Edge makeOld() {
     Edge e=new Edge();
     e.fd=fd;
index 0efc690f3c98bcd329129e3e48489d145d71de46..a5b2d708c6110eb4a7ae60126fc04424639dafe2 100644 (file)
@@ -20,6 +20,10 @@ public class Graph {
   HashSet<AllocNode> nodeAges;
   HashMap<AllocNode, Boolean> oldNodes;
 
+  /* Need this information for mapping in callee results */
+  HashSet<AllocNode> callNodeAges;
+  HashSet<AllocNode> callOldNodes;
+
   public Graph(Graph parent) {
     nodeMap=new HashMap<AllocNode, MySet<Edge>>();
     varMap=new HashMap<TempDescriptor, MySet<Edge>>();
@@ -28,6 +32,13 @@ public class Graph {
     this.parent=parent;
   }
 
+  public MySet<Edge> getBackEdges(AllocNode node) {
+    MySet<Edge> edgeset=new MySet<Edge>();
+    edgeset.addAll(backMap.get(node));
+    edgeset.addAll(parent.backMap.get(node));
+    return edgeset;
+  }
+
   public boolean containsNode(AllocNode node) {
     return nodeAges.contains(node)||parent!=null&&parent.nodeAges.contains(node);
   }
index 3b813f19b2d0809a11e329962631838ca2b49f46..32b1bef40fe241499b12d5368964278ef682e197 100644 (file)
@@ -7,6 +7,11 @@ public class MySet<T> extends AbstractSet<T> {
     map=new HashMap<T,T>();
   }
 
+  public MySet(T obj) {
+    map=new HashMap<T,T>();
+    add(obj);
+  }
+
   public MySet(MySet base) {
     map=new HashMap<T,T>();
     addAll(base);
index ceca50bd3ace2691875b64ad857e8eb9b8ff64fd..1d1d30c5e45e90f5e395ff21b59d82a1c917368c 100644 (file)
@@ -314,6 +314,8 @@ public class Pointer {
     return targets;
   }
 
+      
+
 
   void fixMapping(FlatCall fcall, HashSet<MethodDescriptor> targets, MySet<Edge> oldedgeset, Delta newDelta, BBlock callblock, int callindex) {
     Delta basedelta=null;
@@ -513,6 +515,9 @@ public class Pointer {
       graph.reachNode=nodeset;
       graph.reachEdge=edgeset;
       
+      graph.callNodeAges=new HashSet<AllocNode>();
+      graph.callOldNodes=new HashSet<AllocNode>();
+
       //Apply diffs to graph
       applyDiffs(graph, delta, true);
     } else {
@@ -567,15 +572,115 @@ public class Pointer {
     return delta;
   }
 
+  
+
   Delta applyCallDelta(Delta delta, BBlock bblock) {
+    Delta newDelta=new Delta(null, false);
     Vector<FlatNode> nodes=bblock.nodes();
     PPoint ppoint=delta.getBlock();
     FlatCall fcall=(FlatCall)nodes.get(ppoint.getIndex());
     Graph graph=graphMap.get(fcall);
+    Graph oldgraph=(ppoint.getIndex()==0)?
+      bbgraphMap.get(bblock):
+      graphMap.get(nodes.get(ppoint.getIndex()-1));
+    
+    //Age outside edges if necessary
+    for(Iterator<AllocNode> nodeit=delta.addNodeAges.iterator();nodeit.hasNext();) {
+      AllocNode node=nodeit.next();
+      if (!graph.callNodeAges.contains(node)) {
+       graph.callNodeAges.add(node);
+      } else {
+       nodeit.remove();
+      }
+      if (!graph.reachNode.contains(node)&&!node.isSummary()) {
+       /* Need to age node in existing graph*/
+       summarizeInGraph(graph, newDelta, node);
+      }
+    }
+    
+    //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;
+       } 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;
+         }
+       }
+       if (edgetoadd!=null) {
+         if (newDelta.heapedgeadd.containsKey(edgetoadd.src)) 
+           newDelta.heapedgeadd.put(edgetoadd.src, new MySet<Edge>(edgetoadd));
+         else
+           newDelta.heapedgeadd.get(edgetoadd.src).add(edgetoadd);
+       }
+      }
+    }
     
+    
+    return newDelta;
+  }
+
+  /* Summarizes out of context nodes in graph */
+  void summarizeInGraph(Graph graph, Delta newDelta, AllocNode singleNode) {
+    AllocNode summaryNode=allocFactory.getAllocNode(singleNode, true);
+
+    //Handle outgoing heap edges
+    MySet<Edge> edgeset=graph.getEdges(singleNode);
+
+    for(Edge e:edgeset) {
+      Edge rewrite=e.rewrite(singleNode, summaryNode);
+      //Remove old edge
+      if (!newDelta.heapedgeremove.containsKey(singleNode))
+       newDelta.heapedgeremove.put(singleNode, new MySet<Edge>(e));
+      else
+       newDelta.heapedgeremove.get(singleNode).add(e);
 
+      //Add new edge
+      if (!newDelta.heapedgeremove.containsKey(summaryNode))
+       newDelta.heapedgeremove.put(summaryNode, new MySet<Edge>(rewrite));
+      else
+       newDelta.heapedgeremove.get(summaryNode).add(rewrite);
+    }
+    
+    //Handle incoming edges
+    MySet<Edge> backedges=graph.getBackEdges(singleNode);
+    for(Edge e:backedges) {
+      if (e.dst==singleNode) {
+       Edge rewrite=e.rewrite(singleNode, summaryNode);
+       if (e.src!=null) {
+         //Have heap edge
+         if (!newDelta.heapedgeremove.containsKey(e.src))
+           newDelta.heapedgeremove.put(e.src, new MySet<Edge>(e));
+         else
+           newDelta.heapedgeremove.get(e.src).add(e);
+
+         if (!newDelta.heapedgeadd.containsKey(summaryNode))
+           newDelta.heapedgeadd.put(summaryNode, new MySet<Edge>(rewrite));
+         else
+           newDelta.heapedgeadd.get(summaryNode).add(rewrite);
 
-    return null;
+       } else {
+         //Have var edge
+         if (!newDelta.varedgeremove.containsKey(e.srcvar))
+           newDelta.varedgeremove.put(e.srcvar, new MySet<Edge>(e));
+         else
+           newDelta.varedgeremove.get(e.srcvar).add(e);
+
+         if (!newDelta.varedgeadd.containsKey(e.srcvar))
+           newDelta.varedgeadd.put(e.srcvar, new MySet<Edge>(rewrite));
+         else
+           newDelta.varedgeadd.get(e.srcvar).add(rewrite);
+       }
+      }
+    }
   }
 
   void applyDiffs(Graph graph, Delta delta) {