X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FSSJava%2FHierarchyGraph.java;h=4e7c4b57a6a52e3e6e8c7680d70095be7b49a240;hb=094082ca4819e86104232cd3a8010323fcac95dc;hp=f9bb5e904d40f5e8625e1b8b845e87025e7b55e7;hpb=f7b671e1dd0d86e45ef2ceb2d83fde738997720d;p=IRC.git diff --git a/Robust/src/Analysis/SSJava/HierarchyGraph.java b/Robust/src/Analysis/SSJava/HierarchyGraph.java index f9bb5e90..4e7c4b57 100644 --- a/Robust/src/Analysis/SSJava/HierarchyGraph.java +++ b/Robust/src/Analysis/SSJava/HierarchyGraph.java @@ -17,6 +17,8 @@ public class HierarchyGraph { Descriptor desc; + boolean isSCgraph; + String name; // graph structure @@ -38,6 +40,8 @@ public class HierarchyGraph { Map> mapNormalNodeToSCNodeReachToSet; + Map, Set> mapCombineNodeSetToFirstNodeOfChainSet; + Set nodeSet; // for the lattice generation @@ -66,6 +70,18 @@ public class HierarchyGraph { mapHNodeNameToCurrentHNode = new HashMap(); mapNormalNodeToSCNodeReachToSet = new HashMap>(); + + mapCombineNodeSetToFirstNodeOfChainSet = new HashMap, Set>(); + + isSCgraph = false; + } + + public void setSCGraph(boolean in) { + isSCgraph = in; + } + + public boolean isSCGraph() { + return isSCgraph; } public Descriptor getDesc() { @@ -141,19 +157,19 @@ public class HierarchyGraph { if (possibleCycleSet.size() > 0) { if (possibleCycleSet.size() == 1) { - System.out.println("possibleCycleSet=" + possibleCycleSet + " from src=" + srcHNode - + " dstHNode=" + dstHNode); + // System.out.println("possibleCycleSet=" + possibleCycleSet + " from src=" + srcHNode + // + " dstHNode=" + dstHNode); if (dstHNode.isSharedNode()) { // it has already been assigned shared node. } else { dstHNode.setSharedNode(true); - System.out.println("$$$setShared=" + dstHNode); + // System.out.println("$$$setShared=" + dstHNode); } return; } - System.out.println("--- CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode); - HNode newMergeNode = mergeNodes(possibleCycleSet, false); + // System.out.println("--- CYCLIC VALUE FLOW: " + srcHNode + " -> " + dstHNode); + HNode newMergeNode = mergeNodes(possibleCycleSet); newMergeNode.setSharedNode(true); } else { @@ -298,21 +314,16 @@ public class HierarchyGraph { } - public void simplifyHierarchyGraph() { + public void simplifyHierarchyGraph(LocationInference infer) { removeRedundantEdges(); - combineRedundantNodes(false); + combineRedundantNodes(infer); } - public void simplifySkeletonCombinationHierarchyGraph() { - removeRedundantEdges(); - combineRedundantNodes(true); - } - - public void combineRedundantNodes(boolean onlyCombinationNodes) { + public void combineRedundantNodes(LocationInference infer) { // Combine field/parameter nodes who have the same set of incoming/outgoing edges. boolean isUpdated = false; do { - isUpdated = combineTwoRedundatnNodes(onlyCombinationNodes); + isUpdated = combineTwoRedundatnNodes(infer); } while (isUpdated); } @@ -330,12 +341,16 @@ public class HierarchyGraph { return mapHNodeToOutgoingSet.get(node); } - private boolean combineTwoRedundatnNodes(boolean onlyCombinationNodes) { + private boolean combineTwoRedundatnNodes(LocationInference infer) { for (Iterator iterator = nodeSet.iterator(); iterator.hasNext();) { HNode node1 = (HNode) iterator.next(); - if ((onlyCombinationNodes && (!node1.isCombinationNode())) - || (!onlyCombinationNodes && (!node1.isSkeleton()))) { + // if ((onlyCombinationNodes && (!node1.isCombinationNode())) + // || (!onlyCombinationNodes && (!node1.isSkeleton()))) { + // continue; + // } + + if (!node1.isSkeleton()) { continue; } @@ -345,8 +360,12 @@ public class HierarchyGraph { for (Iterator iterator2 = nodeSet.iterator(); iterator2.hasNext();) { HNode node2 = (HNode) iterator2.next(); - if ((onlyCombinationNodes && (!node2.isCombinationNode())) - || (!onlyCombinationNodes && (!node2.isSkeleton()))) { + // if ((onlyCombinationNodes && (!node2.isCombinationNode())) + // || (!onlyCombinationNodes && (!node2.isSkeleton()))) { + // continue; + // } + + if (!node2.isSkeleton()) { continue; } @@ -363,10 +382,17 @@ public class HierarchyGraph { && outgoingNodeSet1.equals(outgoingNodeSet2)) { // need to merge node1 and node2 + // /////////////// + // merge two nodes only if every hierarchy graph in the inheritance hierarchy + // that includes both nodes allows the merging of them... Set mergeSet = new HashSet(); mergeSet.add(node1); mergeSet.add(node2); - mergeNodes(mergeSet, onlyCombinationNodes); + infer.isValidMergeInheritanceCheck(desc, mergeSet); + + // /////////////// + + mergeNodes(mergeSet); return true; } @@ -405,7 +431,7 @@ public class HierarchyGraph { // System.out.println("addEdgeWithNoCycleCheck src=" + srcHNode + " -> " + dstHNode); } - private HNode mergeNodes(Set set, boolean onlyCombinationNodes) { + private HNode mergeNodes(Set set) { Set incomingNodeSet = new HashSet(); Set outgoingNodeSet = new HashSet(); @@ -418,12 +444,9 @@ public class HierarchyGraph { String nodeName; boolean isMergeNode = false; - if (onlyCombinationNodes) { - nodeName = "Comb" + (LocationInference.locSeed++); - } else { - nodeName = "Node" + (LocationInference.locSeed++); - isMergeNode = true; - } + nodeName = "MNode" + (LocationInference.locSeed++); + isMergeNode = true; + HNode newMergeNode = new HNode(nodeName); newMergeNode.setMergeNode(isMergeNode); @@ -447,7 +470,7 @@ public class HierarchyGraph { newMergeNode.setSkeleton(hasSkeleton); newMergeNode.setSharedNode(hasShared); - System.out.println("-----MERGING NODE=" + set + " new node=" + newMergeNode); + // System.out.println("-----MERGING NODE=" + set + " new node=" + newMergeNode); for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode node = (HNode) iterator.next(); @@ -494,10 +517,10 @@ public class HierarchyGraph { for (Iterator iterator = set.iterator(); iterator.hasNext();) { HNode hNode = (HNode) iterator.next(); - System.out.println("old=" + hNode + "----->newNode=" + getCurrentHNode(hNode)); + // System.out.println("old=" + hNode + "----->newNode=" + getCurrentHNode(hNode)); } - System.out.println(); + // System.out.println(); return newMergeNode; } @@ -507,8 +530,8 @@ public class HierarchyGraph { if (curNode.isMergeNode()) { Set mergingSet = getMergingSet(curNode); mergingSet.add(curNode); - System.out.println("-------addMapHNodeToCurrentHNode curNode=" + curNode + " meringSet=" - + mergingSet + " newNode=" + newNode); + // System.out.println("-------addMapHNodeToCurrentHNode curNode=" + curNode + " meringSet=" + // + mergingSet + " newNode=" + newNode); for (Iterator iterator = mergingSet.iterator(); iterator.hasNext();) { HNode mergingNode = (HNode) iterator.next(); mapHNodeToCurrentHNode.put(mergingNode, newNode); @@ -752,8 +775,10 @@ public class HierarchyGraph { } public HNode getCombinationNode(Set combineSet) { + assert isSCGraph(); if (!mapCombineNodeSetToCombinationNode.containsKey(combineSet)) { String name = "COMB" + (LocationInference.locSeed++); + System.out.println("-NEW COMB NODE=" + name); HNode node = new HNode(name); node.setCombinationNode(true); nodeSet.add(node); @@ -780,12 +805,41 @@ public class HierarchyGraph { Set> keySet = simpleHierarchyGraph.getCombineNodeSet(); for (Iterator iterator = keySet.iterator(); iterator.hasNext();) { Set combineSet = (Set) iterator.next(); - // System.out.println("--combineSet=" + combineSet); + System.out.println("--combineSet=" + combineSet); HNode combinationNode = getCombinationNode(combineSet); System.out.println("--combinationNode=" + combinationNode + " combineSet=" + combineSet); System.out.println("--hierarchynodes=" + simpleHierarchyGraph.getCombinationNodeSetByCombineNodeSet(combineSet)); + + Set simpleHNodeSet = + simpleHierarchyGraph.getCombinationNodeSetByCombineNodeSet(combineSet); + + // check whether a hnode in the simple hierarchy graph is the first node of the chain + // if all incoming combination nodes to the hnode have a different combination set from the + // hnode, it is the first node of the chain + for (Iterator iterator2 = simpleHNodeSet.iterator(); iterator2.hasNext();) { + HNode simpleHNode = (HNode) iterator2.next(); + boolean isFirstNodeOfChain = true; + Set incomingNodeSet = simpleHierarchyGraph.getIncomingNodeSet(simpleHNode); + for (Iterator iterator3 = incomingNodeSet.iterator(); iterator3.hasNext();) { + HNode inNode = (HNode) iterator3.next(); + if (inNode.isCombinationNode()) { + Set inNodeCombineSet = + simpleHierarchyGraph.getCombineSetByCombinationNode(inNode); + if (inNodeCombineSet.equals(combineSet)) { + isFirstNodeOfChain = false; + break; + } + } + } + simpleHNode.setDirectCombinationNode(isFirstNodeOfChain); + if (isFirstNodeOfChain) { + simpleHierarchyGraph.addFirstNodeOfChain(combineSet, simpleHNode); + System.out.println("IT IS THE FIRST NODE OF THE CHAIN:" + simpleHNode); + } + } + // add an edge from a skeleton node to a combination node for (Iterator iterator2 = combineSet.iterator(); iterator2.hasNext();) { HNode inSkeletonNode = (HNode) iterator2.next(); @@ -819,38 +873,13 @@ public class HierarchyGraph { } } - System.out.println("--"); - - } - - } - - private void addCombinationNode(HNode curNode, Set reachToSet, Set reachableSet) { - if (!mapSkeletonNodeSetToCombinationNode.containsKey(reachToSet)) { - // need to create a new combination node - String nodeName = "Comb" + (LocationInference.locSeed++); - HNode newCombinationNode = new HNode(nodeName); - newCombinationNode.setCombinationNode(true); - - nodeSet.add(newCombinationNode); - mapSkeletonNodeSetToCombinationNode.put(reachToSet, newCombinationNode); - - for (Iterator iterator = reachToSet.iterator(); iterator.hasNext();) { - HNode reachToNode = (HNode) iterator.next(); - addEdge(reachToNode, newCombinationNode); - } - - } + // System.out.println("--"); - HNode combinationNode = mapSkeletonNodeSetToCombinationNode.get(reachToSet); - for (Iterator iterator = reachableSet.iterator(); iterator.hasNext();) { - HNode reachableNode = (HNode) iterator.next(); - addEdge(combinationNode, reachableNode); } } - private Set getSkeleteNodeSetReachTo(HNode node) { + public Set getSkeleteNodeSetReachTo(HNode node) { Set reachToSet = new HashSet(); Set visited = new HashSet(); @@ -865,23 +894,6 @@ public class HierarchyGraph { return reachToSet; } - private void removeRedundantReachToNodes(Set reachToSet) { - - Set toberemoved = new HashSet(); - for (Iterator iterator = reachToSet.iterator(); iterator.hasNext();) { - HNode cur = (HNode) iterator.next(); - - for (Iterator iterator2 = reachToSet.iterator(); iterator2.hasNext();) { - HNode dst = (HNode) iterator2.next(); - if (!cur.equals(dst) && reachTo(cur, dst)) { - // it is redundant - toberemoved.add(cur); - } - } - } - reachToSet.removeAll(toberemoved); - } - private void recurSkeletonReachTo(HNode node, Set reachToSet, Set visited) { Set inSet = getIncomingNodeSet(node); @@ -952,6 +964,10 @@ public class HierarchyGraph { return clone; } + public void setMapCombineNodeSetToCombinationNode(Map, HNode> in) { + mapCombineNodeSetToCombinationNode = in; + } + public Map> getMapHNodetoMergeSet() { return mapMergeNodetoMergingSet; } @@ -978,14 +994,35 @@ public class HierarchyGraph { // Set tempSet = removeTransitivelyReachToSet(reachToSet); // reachToSet = removeTransitivelyReachToSet(reachToSet); Set tempSet = reachToSet; - System.out.println("$node=" + node + " reachToNodeSet=" + reachToSet + " tempSet=" - + tempSet); + // System.out.println("$node=" + node + " reachToNodeSet=" + reachToSet + " tempSet=" + // + tempSet); if (reachToSet.size() > 1) { // if (countSkeletonNodes(reachToSet) > 1) { - System.out.println("-node=" + node + " reachToSet=" + reachToSet); + System.out.println("\n-node=" + node + " reachToSet=" + reachToSet); System.out.println("-set combinationnode=" + node); node.setCombinationNode(true); mapCombinationNodeToCombineNodeSet.put(node, reachToSet); + + // check if this node is the first node of the chain + // boolean isFirstNodeOfChain = false; + // Set inNodeSet = getIncomingNodeSet(node); + // for (Iterator iterator2 = inNodeSet.iterator(); iterator2.hasNext();) { + // HNode inNode = (HNode) iterator2.next(); + // if (inNode.isSkeleton()) { + // isFirstNodeOfChain = true; + // } else if (inNode.isCombinationNode()) { + // Set inNodeReachToSet = getSkeleteNodeSetReachTo(inNode); + // if (!reachToSet.equals(inNodeReachToSet)) { + // isFirstNodeOfChain = true; + // } + // } + // } + // + // if (isFirstNodeOfChain) { + // node.setDirectCombinationNode(true); + // addFirstNodeOfChain(reachToSet, node); + // } + } } } @@ -1002,6 +1039,20 @@ public class HierarchyGraph { } + public void addFirstNodeOfChain(Set combineSet, HNode firstNode) { + + if (!mapCombineNodeSetToFirstNodeOfChainSet.containsKey(combineSet)) { + mapCombineNodeSetToFirstNodeOfChainSet.put(combineSet, new HashSet()); + } + + mapCombineNodeSetToFirstNodeOfChainSet.get(combineSet).add(firstNode); + + } + + public Set getFirstNodeOfCombinationNodeChainSet(Set combineNodeSet) { + return mapCombineNodeSetToFirstNodeOfChainSet.get(combineNodeSet); + } + private Set removeTransitivelyReachToSet(Set reachToSet) { Set toberemoved = new HashSet(); @@ -1222,6 +1273,8 @@ public class HierarchyGraph { graphName += "_PAPER"; } + // System.out.println("***graphName=" + graphName + " node siz=" + nodeSet.size()); + try { BufferedWriter bw = new BufferedWriter(new FileWriter(graphName + ".dot")); @@ -1309,6 +1362,7 @@ public class HierarchyGraph { if (node.isMergeNode()) { nodeName = node.getNamePropertyString(); Set mergeSet = mapMergeNodetoMergingSet.get(node); + // System.out.println("node=" + node + " mergeSet=" + mergeSet); nodeName += ":" + convertMergeSetToString(mergeSet); } else { nodeName = node.getNamePropertyString(); @@ -1343,4 +1397,33 @@ public class HierarchyGraph { return max; } + public int countNonSharedNode(HNode startNode, Set endNodeSet) { + System.out.println("countNonSharedNode startNode=" + startNode + " endNode=" + endNodeSet); + return recur_countNonSharedNode(startNode, endNodeSet, 0); + } + + private int recur_countNonSharedNode(HNode startNode, Set endNodeSet, int count) { + + Set inNodeSet = getIncomingNodeSet(startNode); + + if (inNodeSet.size() == 0) { + // it is directly connected to the TOP node + } + + for (Iterator iterator = inNodeSet.iterator(); iterator.hasNext();) { + HNode inNode = (HNode) iterator.next(); + if (endNodeSet.contains(inNode)) { + return count; + } else { + if (!inNode.isSharedNode()) { + count++; + } + return recur_countNonSharedNode(inNode, endNodeSet, count); + } + } + + // System.out.println("startNode=" + startNode + " inNodeSet=" + inNodeSet); + // HNode inNode = inNodeSet.iterator().next(); + return -1; + } }