changes towards making this work
authorbdemsky <bdemsky>
Wed, 2 Mar 2011 22:05:52 +0000 (22:05 +0000)
committerbdemsky <bdemsky>
Wed, 2 Mar 2011 22:05:52 +0000 (22:05 +0000)
Robust/src/Analysis/Pointer/BasicBlock.java
Robust/src/Analysis/Pointer/Delta.java
Robust/src/Analysis/Pointer/Graph.java
Robust/src/Analysis/Pointer/MySet.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/PPoint.java [new file with mode: 0644]
Robust/src/Analysis/Pointer/Pointer.java

index 4746bd74bd7980fe4b2f7ae11b106c30f9eba1e2..b58ae1e481c812da6ac45f78409f7c2cfabda31d 100644 (file)
@@ -24,6 +24,7 @@ public class BasicBlock {
     Vector<FlatNode> nodes;
     Vector<BBlock> prevb;
     Vector<BBlock> nextb;
+    boolean callReturn;
 
     public BBlock() {
       nodes=new Vector<FlatNode>();
@@ -42,7 +43,7 @@ public class BasicBlock {
     }
   }
 
-  public static BasicBlock getBBlock(FlatMethod fm, boolean breakcalls) {
+  public static BasicBlock getBBlock(FlatMethod fm) {
     BBlock exit=null;
     Stack<FlatNode> toprocess=new Stack<FlatNode>();
     HashMap<FlatNode, BBlock> map=new HashMap<FlatNode, BBlock>();
@@ -58,7 +59,7 @@ public class BasicBlock {
       if (fn.kind()==FKind.FlatExit)
        exit=block;
       do {
-       if (pm.numNext(fn)!=1||(fn.kind()==FKind.FlatCall&&breakcalls)) {
+       if (pm.numNext(fn)!=1) {
          for(int i=0;i<pm.numNext(fn);i++) {
            FlatNode fnext=pm.getNext(fn,i);
            if (!map.containsKey(fnext)) {
index 2616e5c827b27480d0cabe196c8423604625ff4b..4e1143103e4ae10340f7855a92453d5496db44a1 100644 (file)
@@ -11,15 +11,17 @@ public class Delta {
   HashMap<TempDescriptor, MySet<Edge>> varedgeremove;
   HashMap<AllocNode, MySet<Edge>> baseheapedge;
   HashMap<TempDescriptor, MySet<Edge>> basevaredge;
-  HashMap<AllocNode, Integer> addNodeAges;
+  HashSet<AllocNode> baseNodeAges;
+  HashSet<AllocNode> addNodeAges;
 
   boolean init;
-  BBlock block;
+  PPoint block;
+  boolean callStart;
 
   /* Init is set for false for delta propagations inside of one basic block.
    */
   
-  public Delta(BBlock block, boolean init) {
+  public Delta(PPoint block, boolean init) {
     this.init=init;
     this.baseheapedge=new HashMap<AllocNode, MySet<Edge>>();
     this.basevaredge=new HashMap<TempDescriptor, MySet<Edge>>();
@@ -27,22 +29,23 @@ public class Delta {
     this.heapedgeremove=new HashMap<AllocNode, MySet<Edge>>();
     this.varedgeadd=new HashMap<TempDescriptor, MySet<Edge>>();
     this.varedgeremove=new HashMap<TempDescriptor, MySet<Edge>>();
-    this.addNodeAges=new HashMap<AllocNode, Integer>();
+    this.baseNodeAges=new HashSet<AllocNode>();
+    this.addNodeAges=new HashSet<AllocNode>();
     this.block=block;
   }
 
   private Delta() {
   }
 
-  public BBlock getBlock() {
+  public PPoint getBlock() {
     return block;
   }
 
-  public void setBlock(BBlock block) {
+  public void setBlock(PPoint block) {
     this.block=block;
   }
 
-  public Delta changeParams(HashMap<TempDescriptor, TempDescriptor> tmpMap, BBlock bblock) {
+  public Delta changeParams(HashMap<TempDescriptor, TempDescriptor> tmpMap, PPoint bblock) {
     Delta newdelta=new Delta();
     newdelta.baseheapedge=baseheapedge;
     newdelta.basevaredge=basevaredge;
@@ -81,7 +84,7 @@ public class Delta {
     return newdelta;
   }
 
-  public Delta diffBlock(BBlock bblock) {
+  public Delta diffBlock(PPoint bblock) {
     Delta newdelta=new Delta();
     newdelta.baseheapedge=baseheapedge;
     newdelta.basevaredge=basevaredge;
index 7d61e985889f7fd9164284f07ba111ae0cdaf5bc..09adf72d36b43d7a4f7d8dc3d54cd9be37d7efcf 100644 (file)
@@ -17,19 +17,20 @@ public class Graph {
   HashSet<AllocNode> reachNode;
 
   /* Need this information for mapping in callee results */
-  HashMap<AllocNode, Integer> nodeAges;
-  public static final Integer OLD=new Integer(1); 
-  public static final Integer NEW=new Integer(2); 
-  public static final Integer EITHER=new Integer(3);
+  HashSet<AllocNode> nodeAges;
 
   public Graph(Graph parent) {
     nodeMap=new HashMap<AllocNode, MySet<Edge>>();
     backMap=new HashMap<AllocNode, MySet<Edge>>();
     varMap=new HashMap<TempDescriptor, MySet<Edge>>();
-    nodeAges=new HashMap<AllocNode, Integer>();
+    nodeAges=new HashSet<AllocNode>();
     this.parent=parent;
   }
 
+  public boolean containsNode(AllocNode node) {
+    return nodeAges.contains(node)||parent!=null&&parent.nodeAges.contains(node);
+  }
+
   public MySet<Edge> getEdges(TempDescriptor tmp) {
     if (varMap.containsKey(tmp))
       return varMap.get(tmp);
diff --git a/Robust/src/Analysis/Pointer/MySet.java b/Robust/src/Analysis/Pointer/MySet.java
new file mode 100644 (file)
index 0000000..26be393
--- /dev/null
@@ -0,0 +1,47 @@
+package Analysis.Pointer;
+import java.util.*;
+
+public class MySet<T> extends AbstractSet<T> {
+  HashMap<T,T> map;
+  public MySet() {
+    map=new HashMap<T,T>();
+  }
+
+  public int size() {
+    return map.size();
+  }
+
+  public void clear() {
+    map.clear();
+  }
+
+  public boolean remove(Object obj) {
+    return map.remove(obj)!=null; 
+  }
+  
+  public boolean add(T obj) {
+    return map.put(obj, obj)==null;
+  }
+
+  public boolean contains(Object obj) {
+    return map.containsKey(obj);
+  }
+
+  public T get(T obj) {
+    return map.get(obj);
+  }
+
+  public boolean isEmpty() {
+    return map.isEmpty();
+  }
+  
+  public Iterator<T> iterator() {
+    return map.keySet().iterator();
+  }
+
+  public Object clone() {
+    MySet<T> cl=new MySet<T>();
+    cl.map.putAll(this.map);
+    return cl;
+  }
+}
\ No newline at end of file
diff --git a/Robust/src/Analysis/Pointer/PPoint.java b/Robust/src/Analysis/Pointer/PPoint.java
new file mode 100644 (file)
index 0000000..da75eb0
--- /dev/null
@@ -0,0 +1,24 @@
+package Analysis.Pointer;
+import Analysis.Pointer.BasicBlock.BBlock;
+
+public class PPoint {
+  BBlock bblock;
+  int index;
+  public PPoint(BBlock bblock) {
+    this.bblock=bblock;
+    this.index=-1;
+  }
+
+  public PPoint(BBlock bblock, int index) {
+    this.bblock=bblock;
+    this.index=index;
+  }
+
+  public BBlock getBBlock() {
+    return bblock;
+  }
+
+  public int getIndex() {
+    return index;
+  }
+}
\ No newline at end of file
index 06ead04f301419a5e1c9aedff21d9c79c0bd24ac..aaa3e20749d38ce5721018d74dc17bd24cfd4690 100644 (file)
@@ -9,7 +9,8 @@ public class Pointer {
   HashMap<FlatMethod, BasicBlock> blockMap;
   HashMap<BBlock, Graph> bbgraphMap;
   HashMap<FlatNode, Graph> graphMap;
-  HashMap<BBlock, Set<BBlock>> callMap;
+  HashMap<FlatCall, Set<BBlock>> callMap;
+  HashMap<BBlock, Set<PPoint>> returnMap;
 
   State state;
   TypeUtil typeUtil;
@@ -22,7 +23,8 @@ public class Pointer {
     this.blockMap=new HashMap<FlatMethod, BasicBlock>();
     this.bbgraphMap=new HashMap<BBlock, Graph>();
     this.graphMap=new HashMap<FlatNode, Graph>();
-    this.callMap=new HashMap<BBlock, Set<BBlock>>();
+    this.callMap=new HashMap<FlatCall, Set<BBlock>>();
+    this.returnMap=new HashMap<BBlock, Set<PPoint>>();
     this.typeUtil=typeUtil;
     this.allocFactory=new AllocFactory(state, typeUtil);
     this.toprocess=new LinkedList<Delta>();
@@ -32,7 +34,7 @@ public class Pointer {
 
   public BasicBlock getBBlock(FlatMethod fm) {
     if (!blockMap.containsKey(fm))
-      blockMap.put(fm, BasicBlock.getBBlock(fm, true));
+      blockMap.put(fm, BasicBlock.getBBlock(fm));
     return blockMap.get(fm);
   }
   
@@ -41,7 +43,7 @@ public class Pointer {
     FlatMethod fm=state.getMethodFlat(md);
     BasicBlock bb=getBBlock(fm);
     BBlock start=bb.getStart();
-    Delta delta=new Delta(start, true);
+    Delta delta=new Delta(new PPoint(start), true);
     MySet<Edge> arrayset=new MySet<Edge>();
     MySet<Edge> varset=new MySet<Edge>();
     Edge arrayedge=new Edge(allocFactory.StringArray, null, allocFactory.Strings);
@@ -58,7 +60,8 @@ public class Pointer {
 
     while(!toprocess.isEmpty()) {
       Delta delta=toprocess.remove();
-      BBlock bblock=delta.getBlock();
+      PPoint ppoint=delta.getBlock();
+      BBlock bblock=ppoint.getBBlock();
       Vector<FlatNode> nodes=bblock.nodes();
 
       //Build base graph for entrance to this basic block
@@ -73,45 +76,55 @@ public class Pointer {
          graphMap.put(currNode, new Graph(graph));
        }
        nodeGraph=graphMap.get(currNode);
-       delta=processNode(currNode, delta, nodeGraph);
+       delta=processNode(bblock, i, currNode, delta, nodeGraph);
       }
       generateFinalDelta(bblock, delta, nodeGraph);
     }
   }
 
+  void buildInitDelta(Graph graph, Delta newDelta) {
+    //First compute the set of temps
+    HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
+    tmpSet.addAll(graph.varMap.keySet());
+    tmpSet.addAll(graph.parent.varMap.keySet());
+    
+    //Next build the temp map part of the delta
+    for(TempDescriptor tmp:tmpSet) {
+      MySet<Edge> edgeSet=new MySet<Edge>();
+      /* Get target set */
+      if (graph.varMap.containsKey(tmp))
+       edgeSet.addAll(graph.varMap.get(tmp));
+      else
+       edgeSet.addAll(graph.parent.varMap.get(tmp));
+      newDelta.varedgeadd.put(tmp, edgeSet);
+    }
+    
+    //Next compute the set of src allocnodes
+    HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
+    nodeSet.addAll(graph.nodeMap.keySet());
+    nodeSet.addAll(graph.parent.nodeMap.keySet());
+    
+    for(AllocNode node:nodeSet) {
+      MySet<Edge> edgeSet=new MySet<Edge>();
+      /* Get edge set */
+      if (graph.nodeMap.containsKey(node))
+       edgeSet.addAll(graph.nodeMap.get(node));
+      else
+       edgeSet.addAll(graph.parent.nodeMap.get(node));
+      newDelta.heapedgeadd.put(node, edgeSet);
+      
+      /* Compute ages */
+      if (graph.nodeAges.contains(node))
+       newDelta.addNodeAges.add(node);
+      else if (graph.parent.nodeAges.contains(node))
+       newDelta.addNodeAges.add(node);
+    }
+  }
+
   void generateFinalDelta(BBlock bblock, Delta delta, Graph graph) {
     Delta newDelta=new Delta(null, false);
     if (delta.getInit()) {
-      //First compute the set of temps
-      HashSet<TempDescriptor> tmpSet=new HashSet<TempDescriptor>();
-      tmpSet.addAll(graph.varMap.keySet());
-      tmpSet.addAll(graph.parent.varMap.keySet());
-
-      //Next build the temp map part of the delta
-      for(TempDescriptor tmp:tmpSet) {
-       MySet<Edge> edgeSet=new MySet<Edge>();
-       /* Get target set */
-       if (graph.varMap.containsKey(tmp))
-         edgeSet.addAll(graph.varMap.get(tmp));
-       else
-         edgeSet.addAll(graph.parent.varMap.get(tmp));
-       newDelta.varedgeadd.put(tmp, edgeSet);
-      }
-
-      //Next compute the set of src allocnodes
-      HashSet<AllocNode> nodeSet=new HashSet<AllocNode>();
-      nodeSet.addAll(graph.nodeMap.keySet());
-      nodeSet.addAll(graph.parent.nodeMap.keySet());
-
-      for(AllocNode node:nodeSet) {
-       MySet<Edge> edgeSet=new MySet<Edge>();
-       /* Get edge set */
-       if (graph.nodeMap.containsKey(node))
-         edgeSet.addAll(graph.nodeMap.get(node));
-       else
-         edgeSet.addAll(graph.parent.nodeMap.get(node));
-       newDelta.heapedgeadd.put(node, edgeSet);
-      }
+      buildInitDelta(graph, newDelta);
     } else {
       /* We can break the old delta...it is done being used */
       /* First we will build variable edges */
@@ -145,27 +158,33 @@ public class Pointer {
 
        /* Also need to subtract off some edges */
        MySet<Edge> removeset=delta.heapedgeremove.get(node);
+
        /* Remove the newly created edges..no need to propagate a diff for those */
        removeset.removeAll(delta.baseheapedge.get(node));
        newDelta.heapedgeremove.put(node, removeset);
       }
+
+      /* Compute new ages */
+      newDelta.addNodeAges.addAll(delta.baseNodeAges);
+      newDelta.addNodeAges.addAll(delta.addNodeAges);
     }
+
     /* Now we need to propagate newdelta */
-    if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()) {
+    if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()||!newDelta.addNodeAges.isEmpty()) {
       /* We have a delta to propagate */
       Vector<BBlock> blockvector=bblock.next();
       for(int i=0;i<blockvector.size();i++) {
        if (i==0) {
-         newDelta.setBlock(blockvector.get(i));
+         newDelta.setBlock(new PPoint(blockvector.get(i)));
          toprocess.add(newDelta);
        } else {
-         toprocess.add(newDelta.diffBlock(blockvector.get(i)));
+         toprocess.add(newDelta.diffBlock(new PPoint(blockvector.get(i))));
        }
       }
     }
   }
 
-  Delta processNode(FlatNode node, Delta delta, Graph newgraph) {
+  Delta processNode(BBlock bblock, int index, FlatNode node, Delta delta, Graph newgraph) {
     switch(node.kind()) {
     case FKind.FlatNew:
       return processNewNode((FlatNew)node, delta, newgraph);
@@ -183,7 +202,7 @@ public class Pointer {
     case FKind.FlatExit:
       return processFlatNop(node, delta, newgraph);
     case FKind.FlatCall:
-      return processFlatCall((FlatCall) node, delta, newgraph);
+      return processFlatCall(bblock, index, (FlatCall) node, delta, newgraph);
     case FKind.FlatSESEEnterNode:
     case FKind.FlatSESEExitNode:
       throw new Error("Unimplemented node:"+node);
@@ -192,7 +211,7 @@ public class Pointer {
     }
   }
 
-  Delta processFlatCall(FlatCall fcall, Delta delta, Graph graph) {
+  Delta processFlatCall(BBlock callblock, int callindex, FlatCall fcall, Delta delta, Graph graph) {
     Delta newDelta=new Delta(null, false);
 
     if (delta.getInit()) {
@@ -241,7 +260,7 @@ public class Pointer {
       while(!tovisit.isEmpty()) {
        AllocNode node=tovisit.pop();
        MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
-       newDelta.heapedgeadd.put(node, GraphManip.makeOld(edges));
+       newDelta.heapedgeadd.put(node, edges);
        edgeset.addAll(edges);
        for(Edge e:edges) {
          if (!nodeset.contains(e.dst)) {
@@ -266,6 +285,7 @@ public class Pointer {
        }
       }
 
+
       //Fix mapping
       for(MethodDescriptor calledmd:targets) {
        FlatMethod fm=state.getMethodFlat(calledmd);
@@ -285,23 +305,38 @@ public class Pointer {
        BasicBlock block=getBBlock(fm);
 
        //Build and enqueue delta
-       Delta d=newDelta.changeParams(tmpMap, block.getStart());
+       Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart()));
        toprocess.add(d);
 
        //Hook up exits
-       if (!callMap.containsKey(delta.getBlock())) {
-         callMap.put(delta.getBlock(), new HashSet<BBlock>());
+       if (!callMap.containsKey(fcall)) {
+         callMap.put(fcall, new HashSet<BBlock>());
        }
-       callMap.get(delta.getBlock()).add(block.getStart());
+       callMap.get(fcall).add(block.getStart());
        
-       //Hook up returns
-       for(BBlock retblock:delta.getBlock().next()) {
-         //Hook up exits
-         if (!callMap.containsKey(block.getExit())) {
-           callMap.put(block.getExit(), new HashSet<BBlock>());
+       //If we have an existing exit, build delta
+       Delta returnDelta=null;
+
+       //Hook up return
+       if (!returnMap.containsKey(block.getExit())) {
+         returnMap.put(block.getExit(), new HashSet<PPoint>());
+       }
+       returnMap.get(block.getExit()).add(new PPoint(callblock, callindex));
+       
+       if (bbgraphMap.containsKey(block.getExit())) {
+         //Need to push existing results to current node
+         if (returnDelta==null) {
+           returnDelta=new Delta(null, false);
+           buildInitDelta(bbgraphMap.get(block.getExit()), returnDelta);
+           if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
+             returnDelta.setBlock(new PPoint(callblock, callindex));
+             toprocess.add(returnDelta);
+           }
+         } else {
+           if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
+             toprocess.add(returnDelta.diffBlock(new PPoint(callblock, callindex)));
+           }
          }
-         callMap.get(block.getExit()).add(retblock);
-         //NOTE: Need to push deltas here probably
        }
       }
       graph.reachNode=nodeset;
@@ -369,7 +404,7 @@ public class Pointer {
        AllocNode node=tovisit.pop();
        MySet<Edge> edges=GraphManip.getEdges(graph, delta, node);
 
-       newDelta.heapedgeadd.put(node, GraphManip.makeOld(edges));
+       newDelta.heapedgeadd.put(node, edges);
        edgeset.addAll(edges);
        for(Edge e:edges) {
          if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) {
@@ -408,21 +443,36 @@ public class Pointer {
        BasicBlock block=getBBlock(fm);
 
        //Hook up exits
-       if (!callMap.containsKey(delta.getBlock())) {
-         callMap.put(delta.getBlock(), new HashSet<BBlock>());
+       if (!callMap.containsKey(fcall)) {
+         callMap.put(fcall, new HashSet<BBlock>());
        }
-       
-       if (!callMap.get(delta.getBlock()).contains(block.getStart())) {
-         callMap.get(delta.getBlock()).add(block.getStart());
+
+       Delta returnDelta=null;
+
+       if (!callMap.get(fcall).contains(block.getStart())) {
+         callMap.get(fcall).add(block.getStart());
          newmethod=true;
-         //Hook up returns
-         for(BBlock retblock:delta.getBlock().next()) {
-           //Hook up exits
-           if (!callMap.containsKey(block.getExit())) {
-             callMap.put(block.getExit(), new HashSet<BBlock>());
+
+         //Hook up exits
+         if (!returnMap.containsKey(block.getExit())) {
+           returnMap.put(block.getExit(), new HashSet<PPoint>());
+         }
+         returnMap.get(block.getExit()).add(new PPoint(callblock, callindex));
+         
+         if (bbgraphMap.containsKey(block.getExit())) {
+           //Need to push existing results to current node
+           if (returnDelta==null) {
+             returnDelta=new Delta(null, false);
+             buildInitDelta(bbgraphMap.get(block.getExit()), returnDelta);
+             if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
+               returnDelta.setBlock(new PPoint(callblock, callindex));
+               toprocess.add(returnDelta);
+             }
+           } else {
+             if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) {
+               toprocess.add(returnDelta.diffBlock(new PPoint(callblock, callindex)));
+             }
            }
-           callMap.get(block.getExit()).add(retblock);
-           //NOTE: Need to push deltas here probably
          }
        }
        
@@ -442,11 +492,11 @@ public class Pointer {
            basedelta=newDelta.buildBase(oldedgeset);
          }
          //Build and enqueue delta
-         Delta d=basedelta.changeParams(tmpMap, block.getStart());
+         Delta d=basedelta.changeParams(tmpMap, new PPoint(block.getStart()));
          toprocess.add(d);
        } else  {
          //Build and enqueue delta
-         Delta d=newDelta.changeParams(tmpMap, block.getStart());
+         Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart()));
          toprocess.add(d);
        }
       }
@@ -517,6 +567,11 @@ public class Pointer {
       MySet<Edge> edgestoadd=e.getValue();
       graph.varMap.put(tmp, (MySet<Edge>) edgestoadd.clone());
     }
+
+    //Add node additions
+    for(AllocNode node:delta.addNodeAges) {
+      graph.nodeAges.add(node);
+    }
   }
 
   Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) {
@@ -714,8 +769,13 @@ public class Pointer {
     AllocNode summary=allocFactory.getAllocNode(node, true);
     AllocNode single=allocFactory.getAllocNode(node, false);
     TempDescriptor tmp=node.getDst();
-      
+
     if (delta.getInit()) {
+      /* We don't have to deal with summarization here...  The
+       * intuition is that this is the only place where we generate
+       * nodes for this allocation site and this is the first time
+       * we've analyzed this site */
+
       //Build new Edge
       Edge e=new Edge(tmp, single);
       //Build new Edge set
@@ -727,6 +787,8 @@ public class Pointer {
       delta.varedgeremove.put(tmp, graph.getEdges(tmp));
       //Apply incoming diffs to graph
       applyDiffs(graph, delta);
+      //Note that we create a single node
+      delta.addNodeAges.add(single);
     } else {
       /* 1. Fix up the variable edge additions */
 
@@ -799,7 +861,15 @@ public class Pointer {
        Util.relationUpdate(delta.heapedgeadd, addnode, null, newset);
        Util.relationUpdate(delta.heapedgeremove, allocnode, null, removeset);
       }
-      
+
+      /* Update Node Ages...If the base or addNodeAges set contains a
+       * single node, it now should also contain a summary node...  No
+       * need to generate a single node as that has already been
+       * done. */
+      if (delta.baseNodeAges.contains(single)||delta.addNodeAges.contains(single)) {
+       delta.addNodeAges.add(summary);
+      }
+
       //Apply incoming diffs to graph
       applyDiffs(graph, delta);      
     }
@@ -882,13 +952,13 @@ public class Pointer {
       //Add in var edges and throw away original diff
       graph.varMap.putAll(delta.varedgeadd);
       //Record that this is initial set...
+      graph.nodeAges.addAll(delta.addNodeAges);
     } 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);
+      mergeAges(graph, delta, newdelta);
     }
     return newdelta;
   }
@@ -948,4 +1018,14 @@ public class Pointer {
       }
     }
   }
+
+  void mergeAges(Graph graph, Delta delta, Delta newDelta) {
+    //Merge in edges
+    for(AllocNode node:delta.addNodeAges) {
+      if (!graph.nodeAges.contains(node)) {
+       graph.nodeAges.add(node);
+       newDelta.baseNodeAges.add(node);
+      }
+    }
+  }
 }
\ No newline at end of file