X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FFlowGraph.java;h=2031460dd48cc983a8bd974aabfa0d93b6ce4314;hb=ddac34bb8ed87db61d32630e714e7f006a077c8e;hp=ded0837339adba1482e09dcef5ee047fa8c91584;hpb=c4e15379352959519956d9b77b723f441aa237b3;p=IRC.git diff --git a/Robust/src/Analysis/SSJava/FlowGraph.java b/Robust/src/Analysis/SSJava/FlowGraph.java index ded08373..2031460d 100644 --- a/Robust/src/Analysis/SSJava/FlowGraph.java +++ b/Robust/src/Analysis/SSJava/FlowGraph.java @@ -13,7 +13,9 @@ import IR.ClassDescriptor; import IR.Descriptor; import IR.FieldDescriptor; import IR.MethodDescriptor; +import IR.NameDescriptor; import IR.VarDescriptor; +import IR.Tree.MethodInvokeNode; public class FlowGraph { @@ -22,6 +24,7 @@ public class FlowGraph { Set returnNodeSet; FlowNode thisVarNode; + Map> mapFlowNodeToInEdgeSet; Map> mapFlowNodeToOutEdgeSet; Map, FlowNode> mapLocTupleToFlowNode; @@ -36,6 +39,10 @@ public class FlowGraph { // DS for the lattice generation Map mapIdxToFlowNode; + Map mapMethodInvokeNodeToFlowReturnNode; + + Map mapIntersectionDescToEnclosingDescriptor; + public static int interseed = 0; boolean debug = true; @@ -50,6 +57,9 @@ public class FlowGraph { this.returnNodeSet = new HashSet(); this.mapIdxToFlowNode = new HashMap(); this.mapFlowNodeToOutEdgeSet = new HashMap>(); + this.mapFlowNodeToInEdgeSet = new HashMap>(); + this.mapMethodInvokeNodeToFlowReturnNode = new HashMap(); + this.mapIntersectionDescToEnclosingDescriptor = new HashMap(); if (!md.isStatic()) { // create a node for 'this' varialbe @@ -67,6 +77,15 @@ public class FlowGraph { } + public void addMapInterLocNodeToEnclosingDescriptor(Descriptor interDesc, ClassDescriptor desc) { + System.out.println("##### INTERLOC=" + interDesc + " enclosing desc=" + desc); + mapIntersectionDescToEnclosingDescriptor.put(interDesc, desc); + } + + public ClassDescriptor getEnclosingDescriptor(Descriptor interDesc) { + return mapIntersectionDescToEnclosingDescriptor.get(interDesc); + } + public Map, FlowNode> getMapDescTupleToInferNode() { return mapDescTupleToInferNode; } @@ -112,6 +131,25 @@ public class FlowGraph { return newNode; } + public FlowReturnNode getFlowReturnNode(MethodInvokeNode min) { + return mapMethodInvokeNodeToFlowReturnNode.get(min); + } + + public FlowReturnNode createReturnNode(MethodInvokeNode min) { + NTuple tuple = new NTuple(); + NameDescriptor n = new NameDescriptor("RETURNLOC" + (LocationInference.locSeed++)); + tuple.add(n); + + FlowReturnNode newNode = new FlowReturnNode(tuple, min); + mapDescTupleToInferNode.put(tuple, newNode); + mapMethodInvokeNodeToFlowReturnNode.put(min, newNode); + // nodeSet.add(newNode); + + System.out.println("create new set node= " + newNode); + + return newNode; + } + private void setupMapIdxToDesc() { Set descSet = mapParamDescToIdx.keySet(); @@ -143,13 +181,20 @@ public class FlowGraph { FlowNode flowNode = (FlowNode) iterator.next(); edgeSet.addAll(getOutEdgeSet(flowNode)); } - + System.out.println("EDGESET=" + edgeSet); return edgeSet; } + public Set getParamFlowNodeSet() { + Set setParamFlowNode = new HashSet(); + setParamFlowNode.addAll(mapIdxToFlowNode.values()); + return setParamFlowNode; + } + public Set getNodeSet() { Set set = new HashSet(); set.addAll(mapDescTupleToInferNode.values()); + System.out.println("NODESET=" + set); return set; } @@ -217,11 +262,22 @@ public class FlowGraph { return mapFlowNodeToOutEdgeSet.get(node); } + public Set getInEdgeSet(FlowNode node) { + if (!mapFlowNodeToInEdgeSet.containsKey(node)) { + mapFlowNodeToInEdgeSet.put(node, new HashSet()); + } + return mapFlowNodeToInEdgeSet.get(node); + } + public void addValueFlowEdge(NTuple fromDescTuple, NTuple toDescTuple) { FlowNode fromNode = getFlowNode(fromDescTuple); FlowNode toNode = getFlowNode(toDescTuple); + if (toNode.getDescTuple().get(0).equals(LocationInference.LITERALDESC)) { + return; + } + // System.out.println("create an edge from " + fromNode + " to " + toNode); int fromTupleSize = fromDescTuple.size(); @@ -261,10 +317,15 @@ public class FlowGraph { FlowEdge edge = new FlowEdge(fromNode, toNode, initTuple, endTuple); addOutEdge(fromNode, edge); + addInEdge(toNode, edge); // System.out.println("add a new edge=" + edge); } + private void addInEdge(FlowNode toNode, FlowEdge edge) { + getInEdgeSet(toNode).add(edge); + } + private void addOutEdge(FlowNode fromNode, FlowEdge edge) { if (!mapFlowNodeToOutEdgeSet.containsKey(fromNode)) { mapFlowNodeToOutEdgeSet.put(fromNode, new HashSet()); @@ -272,6 +333,10 @@ public class FlowGraph { mapFlowNodeToOutEdgeSet.get(fromNode).add(edge); } + public boolean contains(NTuple descTuple) { + return mapDescTupleToInferNode.containsKey(descTuple); + } + public FlowNode getFlowNode(NTuple descTuple) { if (!mapDescTupleToInferNode.containsKey(descTuple)) { FlowNode node = createNewFlowNode(descTuple); @@ -286,6 +351,7 @@ public class FlowGraph { public FlowNode createNewFlowNode(NTuple tuple) { + // System.out.println("createNewFlowNode=" + tuple); if (!mapDescTupleToInferNode.containsKey(tuple)) { FlowNode node = new FlowNode(tuple); mapDescTupleToInferNode.put(tuple, node); @@ -313,8 +379,6 @@ public class FlowGraph { } FlowNode node = mapDescTupleToInferNode.get(tuple); - node.setReturn(true); - returnNodeSet.add(node); } @@ -333,12 +397,29 @@ public class FlowGraph { Set outEdgeSet = getOutEdgeSet(fn); for (Iterator iterator = outEdgeSet.iterator(); iterator.hasNext();) { FlowEdge edge = (FlowEdge) iterator.next(); - FlowNode dstNode = edge.getDst(); + FlowNode originalDstNode = edge.getDst(); + + Set dstNodeSet = new HashSet(); + if (originalDstNode instanceof FlowReturnNode) { + FlowReturnNode rnode = (FlowReturnNode) originalDstNode; + Set> rtupleSetFromRNode = rnode.getReturnTupleSet(); + Set> rtupleSet = getReturnTupleSet(rtupleSetFromRNode); + for (Iterator iterator2 = rtupleSet.iterator(); iterator2.hasNext();) { + NTuple rtuple = (NTuple) iterator2.next(); + dstNodeSet.add(getFlowNode(rtuple)); + } + } else { + dstNodeSet.add(originalDstNode); + } - if (!visited.contains(dstNode)) { - visited.add(dstNode); - recurLocalReachFlowNodeSet(dstNode, visited); + for (Iterator iterator2 = dstNodeSet.iterator(); iterator2.hasNext();) { + FlowNode dstNode = (FlowNode) iterator2.next(); + if (!visited.contains(dstNode)) { + visited.add(dstNode); + recurLocalReachFlowNodeSet(dstNode, visited); + } } + } } @@ -371,15 +452,47 @@ public class FlowGraph { Set nodeSet = getNodeSet(); for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { - FlowNode flowNode = (FlowNode) iterator.next(); - if (flowNode.getCurrentDescTuple().startsWith(prefix)) { - recurReachableSetFrom(flowNode, reachableSet); + FlowNode originalSrcNode = (FlowNode) iterator.next(); + + Set srcNodeSet = new HashSet(); + if (originalSrcNode instanceof FlowReturnNode) { + FlowReturnNode rnode = (FlowReturnNode) originalSrcNode; + Set> rtupleSetFromRNode = rnode.getReturnTupleSet(); + Set> rtupleSet = getReturnTupleSet(rtupleSetFromRNode); + // System.out.println("#rnode=" + rnode + " rtupleSet=" + rtupleSet); + for (Iterator iterator2 = rtupleSet.iterator(); iterator2.hasNext();) { + NTuple rtuple = (NTuple) iterator2.next(); + if (rtuple.startsWith(prefix)) { + // System.out.println("rtuple=" + rtuple + " give it to recur=" + originalSrcNode); + recurReachableSetFrom(originalSrcNode, reachableSet); + } + } + } else { + if (originalSrcNode.getCurrentDescTuple().startsWith(prefix)) { + recurReachableSetFrom(originalSrcNode, reachableSet); + } } + } return reachableSet; } + public Set> getReturnTupleSet(Set> in) { + + Set> normalTupleSet = new HashSet>(); + for (Iterator iterator2 = in.iterator(); iterator2.hasNext();) { + NTuple tuple = (NTuple) iterator2.next(); + FlowNode tupleNode = getFlowNode(tuple); + if (tupleNode instanceof FlowReturnNode) { + normalTupleSet.addAll(getReturnTupleSet(((FlowReturnNode) tupleNode).getReturnTupleSet())); + } else { + normalTupleSet.add(tuple); + } + } + return normalTupleSet; + } + // private void getReachFlowNodeSetFrom(FlowNode fn, Set visited) { // // for (Iterator iterator = fn.getOutEdgeSet().iterator(); @@ -447,11 +560,11 @@ public class FlowGraph { Descriptor localDesc = fn.getDescTuple().get(0); - if (fn.isIntermediate()) { + if (fn.isIntermediate() && fn.getDescTuple().size() == 1) { Location interLoc = new Location(md, localDesc.getSymbol()); interLoc.setLocDescriptor(localDesc); locTuple.add(interLoc); - } else if (localDesc.getSymbol().equals(LocationInference.TOPLOC)) { + } else if (localDesc.getSymbol().equals(SSJavaAnalysis.TOP)) { Location topLoc = new Location(md, Location.TOP); topLoc.setLocDescriptor(LocationInference.TOPDESC); locTuple.add(topLoc); @@ -467,15 +580,25 @@ public class FlowGraph { if (i == 0) { loc = new Location(md, curDesc.getSymbol()); loc.setLocDescriptor(curDesc); - cd = ((VarDescriptor) curDesc).getType().getClassDesc(); + if (curDesc instanceof VarDescriptor) { + cd = ((VarDescriptor) curDesc).getType().getClassDesc(); + } else if (curDesc instanceof InterDescriptor) { + cd = mapIntersectionDescToEnclosingDescriptor.get(curDesc); + } else { + // otherwise it should be the last element + cd = null; + } } else { loc = new Location(cd, curDesc.getSymbol()); loc.setLocDescriptor(curDesc); if (curDesc instanceof FieldDescriptor) { cd = ((FieldDescriptor) curDesc).getType().getClassDesc(); - } else { + } else if (curDesc instanceof LocationDescriptor) { cd = ((LocationDescriptor) curDesc).getEnclosingClassDesc(); + } else { + // otherwise it should be the last element of the tuple + cd = null; } } @@ -506,50 +629,29 @@ public class FlowGraph { if (node.equals(getFlowNode(flowEdge.getEndTuple()))) { FlowNode incomingNode = getFlowNode(flowEdge.getInitTuple()); - if (!visited.contains(incomingNode)) { - visited.add(incomingNode); - getIncomingFlowNodeSet(incomingNode, visited); - } - } - } - } - - } - - public Set> getIncomingFlowTupleSet(FlowNode fn) { - - NTuple dstTuple = fn.getDescTuple(); - - Set> set = new HashSet>(); - - ClassDescriptor cd = null; - - for (Iterator iterator = getNodeSet().iterator(); iterator.hasNext();) { - FlowNode node = (FlowNode) iterator.next(); - - Set edgeSet = getOutEdgeSet(node); - for (Iterator iterator2 = edgeSet.iterator(); iterator2.hasNext();) { - FlowEdge flowEdge = (FlowEdge) iterator2.next(); - if (dstTuple.equals(flowEdge.getEndTuple())) { - NTuple initTuple = flowEdge.getInitTuple(); - NTuple locTuple = new NTuple(); - for (int i = 0; i < initTuple.size(); i++) { - Descriptor d = initTuple.get(i); - Location loc; - if (i == 0) { - loc = new Location(md, d.getSymbol()); - cd = ((VarDescriptor) d).getType().getClassDesc(); - } else { - loc = new Location(cd, d.getSymbol()); - cd = ((FieldDescriptor) d).getType().getClassDesc(); + if (incomingNode instanceof FlowReturnNode) { + FlowReturnNode rnode = (FlowReturnNode) incomingNode; + Set> nodeTupleSet = rnode.getReturnTupleSet(); + Set> rtupleSet = getReturnTupleSet(nodeTupleSet); + for (Iterator iterator3 = rtupleSet.iterator(); iterator3.hasNext();) { + NTuple nodeTuple = (NTuple) iterator3.next(); + FlowNode fn = getFlowNode(nodeTuple); + if (!visited.contains(fn)) { + visited.add(fn); + getIncomingFlowNodeSet(fn, visited); + } + } + } else { + if (!visited.contains(incomingNode)) { + visited.add(incomingNode); + getIncomingFlowNodeSet(incomingNode, visited); } - locTuple.add(loc); } - set.add(locTuple); + } } } - return set; + } public boolean isParameter(NTuple tuple) { @@ -590,6 +692,46 @@ public class FlowGraph { return mapFlowNodeToOutEdgeSet; } + public Set getIncomingNodeSetByPrefix(Descriptor prefix) { + + Set incomingNodeSet = new HashSet(); + + for (Iterator iterator = getNodeSet().iterator(); iterator.hasNext();) { + FlowNode curNode = (FlowNode) iterator.next(); + Set outEdgeSet = getOutEdgeSet(curNode); + + for (Iterator iterator2 = outEdgeSet.iterator(); iterator2.hasNext();) { + FlowEdge outEdge = (FlowEdge) iterator2.next(); + + if (outEdge.getEndTuple().startsWith(prefix)) { + incomingNodeSet.add(curNode); + recurIncomingNodeSetByPrefix(prefix, curNode, incomingNodeSet); + + } + + } + } + + return incomingNodeSet; + + } + + private void recurIncomingNodeSetByPrefix(Descriptor prefix, FlowNode node, Set visited) { + + Set inEdgeSet = getInEdgeSet(node); + + for (Iterator iterator = inEdgeSet.iterator(); iterator.hasNext();) { + FlowEdge inEdge = (FlowEdge) iterator.next(); + + FlowNode inNode = getFlowNode(inEdge.getInitTuple()); + if (!inEdge.getInitTuple().startsWith(prefix) && !visited.contains(inNode)) { + visited.add(inNode); + recurIncomingNodeSetByPrefix(prefix, inNode, visited); + } + } + + } + public void setMapFlowNodeToOutEdgeSet(Map> inMap) { Set keySet = inMap.keySet(); for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { @@ -636,7 +778,13 @@ public class FlowGraph { } private void drawNode(FlowNode node, BufferedWriter bw) throws IOException { - bw.write(node.getID() + " [label=\"" + node.getPrettyID() + "\"]" + ";\n"); + if (node instanceof FlowReturnNode) { + FlowReturnNode rnode = (FlowReturnNode) node; + bw.write(node.getID() + " [label=\"" + node.getPrettyID() + "\"]" + ";\n"); + } else { + bw.write(node.getID() + " [label=\"" + node.getPrettyID() + "\"]" + ";\n"); + } + } public void writeGraph() throws java.io.IOException { @@ -712,5 +860,78 @@ public class FlowGraph { bw.write("}\n"); } - + public void removeEdge(NTuple from, NTuple to) { + + Set toberemoved = new HashSet(); + Set edgeSet = getOutEdgeSet(getFlowNode(from)); + + for (Iterator iterator = edgeSet.iterator(); iterator.hasNext();) { + FlowEdge flowEdge = (FlowEdge) iterator.next(); + if (flowEdge.getInitTuple().equals(from) && flowEdge.getEndTuple().equals(to)) { + toberemoved.add(flowEdge); + } + } + + edgeSet.removeAll(toberemoved); + + } + + public void removeNode(FlowNode node) { + + NTuple tuple = node.getCurrentDescTuple(); + + Set inEdgeSet = getInEdgeSet(node); + for (Iterator iterator = inEdgeSet.iterator(); iterator.hasNext();) { + FlowEdge flowEdge = (FlowEdge) iterator.next(); + if (flowEdge.getEndTuple().equals(tuple)) { + + Set outSet = getOutEdgeSet(getFlowNode(flowEdge.getInitTuple())); + Set toberemoved = new HashSet(); + for (Iterator iterator2 = outSet.iterator(); iterator2.hasNext();) { + FlowEdge outEdge = (FlowEdge) iterator2.next(); + if (outEdge.getEndTuple().equals(tuple)) { + toberemoved.add(outEdge); + } + } + outSet.removeAll(toberemoved); + } + } + + Set outEdgeSet = getOutEdgeSet(node); + for (Iterator iterator = outEdgeSet.iterator(); iterator.hasNext();) { + FlowEdge flowEdge = (FlowEdge) iterator.next(); + if (flowEdge.getInitTuple().equals(tuple)) { + + Set inSet = getInEdgeSet(getFlowNode(flowEdge.getEndTuple())); + Set toberemoved = new HashSet(); + for (Iterator iterator2 = inSet.iterator(); iterator2.hasNext();) { + FlowEdge inEdge = (FlowEdge) iterator2.next(); + if (inEdge.getInitTuple().equals(tuple)) { + toberemoved.add(inEdge); + } + } + inSet.removeAll(toberemoved); + } + } + + for (Iterator iterator = getNodeSet().iterator(); iterator.hasNext();) { + FlowNode flowNode = (FlowNode) iterator.next(); + Set outSet = getOutEdgeSet(flowNode); + Set toberemoved = new HashSet(); + for (Iterator iterator2 = outSet.iterator(); iterator2.hasNext();) { + FlowEdge flowEdge = (FlowEdge) iterator2.next(); + if (flowEdge.getInitTuple().equals(tuple) || flowEdge.getEndTuple().equals(tuple)) { + toberemoved.add(flowEdge); + } + } + outSet.removeAll(toberemoved); + } + + mapFlowNodeToOutEdgeSet.remove(node); + mapFlowNodeToInEdgeSet.remove(node); + System.out.println("REMOVING NODE=" + mapDescTupleToInferNode.get(tuple) + " from tuple=" + + tuple); + mapDescTupleToInferNode.remove(tuple); + System.out.println("mapDescTupleToInferNode=" + mapDescTupleToInferNode); + } } \ No newline at end of file