+ return delta;
+ }
+
+ void processSummarization(Graph graph, Delta delta) {
+ processSumHeapEdgeSet(delta.heapedgeadd, delta, graph);
+ processSumHeapEdgeSet(delta.baseheapedge, delta, graph);
+ processSumVarEdgeSet(delta.varedgeadd, delta, graph);
+ processSumVarEdgeSet(delta.basevaredge, delta, graph);
+ }
+
+ void processSumVarEdgeSet(HashMap<TempDescriptor, MySet<Edge>> map, Delta delta, Graph graph) {
+ MySet<Edge> edgestoadd=new MySet<Edge>();
+ MySet<Edge> edgestoremove=new MySet<Edge>();
+ for(Iterator<Map.Entry<TempDescriptor, MySet<Edge>>> eit=map.entrySet().iterator(); eit.hasNext(); ) {
+ Map.Entry<TempDescriptor, MySet<Edge>> entry=eit.next();
+ MySet<Edge> edgeset=entry.getValue();
+
+ for(Edge e : edgeset) {
+ Edge copy=e.copy();
+ boolean rewrite=false;
+ if (copy.dst!=null&&graph.callNodeAges.contains(copy.dst)) {
+ copy.dst=allocFactory.getAllocNode(copy.dst, true);
+ rewrite=true;
+ }
+ if (rewrite) {
+ edgestoremove.add(e);
+ edgestoadd.add(copy);
+ }
+ }
+ }
+ for(Edge e : edgestoremove) {
+ 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>();
+ for(Iterator<Map.Entry<AllocNode, MySet<Edge>>> eit=map.entrySet().iterator(); eit.hasNext(); ) {
+ Map.Entry<AllocNode, MySet<Edge>> entry=eit.next();
+ AllocNode node=entry.getKey();
+ MySet<Edge> edgeset=entry.getValue();
+
+ for(Edge e : edgeset) {
+ Edge copy=e.copy();
+ boolean rewrite=false;
+ if (copy.src!=null&&graph.callNodeAges.contains(copy.src)) {
+ copy.src=allocFactory.getAllocNode(copy.src, true);
+ rewrite=true;
+ }
+ if (copy.dst!=null&&graph.callNodeAges.contains(copy.dst)) {
+ copy.dst=allocFactory.getAllocNode(copy.dst, true);
+ rewrite=true;
+ }
+ if (rewrite) {
+ edgestoremove.add(e);
+ edgestoadd.add(copy);
+ }
+ }
+ }
+ for(Edge e : edgestoremove) {
+ if (!graph.callerEdges.contains(e))
+ delta.removeHeapEdge(e);
+ }
+ for(Edge e : edgestoadd) {
+ delta.addHeapEdge(e);
+ }
+ }
+
+ //Handle external edges
+ void processCallExternal(Graph graph, Delta newDelta, MySet<Edge> externalEdgeSet) {
+ //Add external edges in
+ for(Edge e : externalEdgeSet) {
+ //First did we age the source
+ Edge newedge=e.copy();
+ if (newedge.src!=null&&!e.src.isSummary()&&graph.callNodeAges.contains(e.src)) {
+ AllocNode summaryNode=allocFactory.getAllocNode(newedge.src, true);
+ newedge.src=summaryNode;
+ }
+ //Compute target
+ if (graph.callNodeAges.contains(e.dst)&&!e.dst.isSummary()) {
+ if (graph.callOldNodes.contains(e.dst)) {
+ //Need two edges
+ Edge copy=newedge.copy();
+ mergeEdge(graph, newDelta, copy);
+ }
+ //Now add summarized node
+ newedge.dst=allocFactory.getAllocNode(newedge.dst, true);
+ mergeCallEdge(graph, newDelta, newedge);
+ } else {
+ //Add edge to single node
+ mergeEdge(graph, newDelta, newedge);
+ }
+ }
+ }
+
+ /* This function applies callee deltas to the caller heap. */
+
+ 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));
+ Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
+
+ //Age outside nodes if necessary
+ for(Iterator<AllocNode> nodeit=delta.addNodeAges.iterator(); nodeit.hasNext(); ) {
+ AllocNode node=nodeit.next();
+ if (!graph.callNodeAges.contains(node)) {
+ graph.callNodeAges.add(node);
+ newDelta.addNodeAges.add(node);
+ }
+ AllocNode summaryAdd=null;
+ if (!graph.reachNode.contains(node)&&!node.isSummary()) {
+ /* Need to age node in existing graph*/
+
+ AllocNode summaryNode=allocFactory.getAllocNode(node, true);
+
+ if (!graph.callNodeAges.contains(summaryNode)) {
+ graph.callNodeAges.add(summaryNode);
+ newDelta.addNodeAges.add(summaryNode);
+ summaryAdd=summaryNode;
+ }
+ summarizeInGraph(graph, newDelta, node);
+ }
+ do {
+ 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);
+ }
+ }
+ }
+ //do the summary node if we added that also...
+ node=summaryAdd;
+ summaryAdd=null;
+ } while(node!=null);
+ }
+
+ //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) {
+ 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[] 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);
+ }
+ }
+
+ processCallExternal(graph, newDelta, graph.externalEdgeSet);
+
+ //Add edge for return value
+ if (fcall.getReturnTemp()!=null) {
+ MySet<Edge> returnedge=delta.varedgeadd.get(returntmp);
+ if (returnedge!=null)
+ for(Edge e : returnedge) {
+ //skip the edge if types don't allow it...
+ if (!typeUtil.isSuperorType(fcall.getReturnTemp().getType(), e.dst.getType()))
+ continue;
+ Edge newedge=e.copy();
+ newedge.srcvar=fcall.getReturnTemp();
+ if (seseCallers!=null)
+ newedge.taintModify(seseCallers);
+ mergeEdge(graph, newDelta, newedge);
+ }
+ }
+ applyDiffs(graph, newDelta);