From: bdemsky <bdemsky> Date: Tue, 25 Jan 2011 00:37:09 +0000 (+0000) Subject: more changes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d7f673f895035256a386258245a9080723fbd6d5;p=IRC.git more changes --- diff --git a/Robust/src/Analysis/Pointer/AllocFactory.java b/Robust/src/Analysis/Pointer/AllocFactory.java index 74a4f20e..98b130e7 100644 --- a/Robust/src/Analysis/Pointer/AllocFactory.java +++ b/Robust/src/Analysis/Pointer/AllocFactory.java @@ -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; diff --git a/Robust/src/Analysis/Pointer/Delta.java b/Robust/src/Analysis/Pointer/Delta.java index 67b94143..e7e7be70 100644 --- a/Robust/src/Analysis/Pointer/Delta.java +++ b/Robust/src/Analysis/Pointer/Delta.java @@ -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 diff --git a/Robust/src/Analysis/Pointer/Graph.java b/Robust/src/Analysis/Pointer/Graph.java index d4969e9b..6f01836a 100644 --- a/Robust/src/Analysis/Pointer/Graph.java +++ b/Robust/src/Analysis/Pointer/Graph.java @@ -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 diff --git a/Robust/src/Analysis/Pointer/Pointer.java b/Robust/src/Analysis/Pointer/Pointer.java index 4987ac80..5769bd53 100644 --- a/Robust/src/Analysis/Pointer/Pointer.java +++ b/Robust/src/Analysis/Pointer/Pointer.java @@ -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 index 00000000..d9746dad --- /dev/null +++ b/Robust/src/Analysis/Pointer/Util.java @@ -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