+ public FlatNode getSSJavaLoopEntrance() {
+ return ssjavaLoopEntrance;
+ }
+
+ public void setSSJavaLoopEntrance(FlatNode ssjavaLoopEntrance) {
+ this.ssjavaLoopEntrance = ssjavaLoopEntrance;
+ }
+
+ public void addSameHeightWriteFlatNode(FlatNode fn) {
+ this.sameHeightWriteFlatNodeSet.add(fn);
+ }
+
+ public boolean isSameHeightWrite(FlatNode fn) {
+ return this.sameHeightWriteFlatNodeSet.contains(fn);
+ }
+
+ public LinkedList<MethodDescriptor> topologicalSort(Set<MethodDescriptor> toSort) {
+
+ Set<MethodDescriptor> discovered = new HashSet<MethodDescriptor>();
+
+ LinkedList<MethodDescriptor> sorted = new LinkedList<MethodDescriptor>();
+
+ Iterator<MethodDescriptor> itr = toSort.iterator();
+ while (itr.hasNext()) {
+ MethodDescriptor d = itr.next();
+
+ if (!discovered.contains(d)) {
+ dfsVisit(d, toSort, sorted, discovered);
+ }
+ }
+
+ return sorted;
+ }
+
+ // While we're doing DFS on call graph, remember
+ // dependencies for efficient queuing of methods
+ // during interprocedural analysis:
+ //
+ // a dependent of a method decriptor d for this analysis is:
+ // 1) a method or task that invokes d
+ // 2) in the descriptorsToAnalyze set
+ private void dfsVisit(MethodDescriptor md, Set<MethodDescriptor> toSort,
+ LinkedList<MethodDescriptor> sorted, Set<MethodDescriptor> discovered) {
+
+ discovered.add(md);
+
+ Iterator itr2 = callgraph.getCalleeSet(md).iterator();
+ while (itr2.hasNext()) {
+ MethodDescriptor dCallee = (MethodDescriptor) itr2.next();
+ addDependent(dCallee, md);
+ }
+
+ Iterator itr = callgraph.getCallerSet(md).iterator();
+ while (itr.hasNext()) {
+ MethodDescriptor dCaller = (MethodDescriptor) itr.next();
+ // only consider callers in the original set to analyze
+ if (!toSort.contains(dCaller)) {
+ continue;
+ }
+ if (!discovered.contains(dCaller)) {
+ addDependent(md, // callee
+ dCaller // caller
+ );
+
+ dfsVisit(dCaller, toSort, sorted, discovered);
+ }
+ }
+
+ // for leaf-nodes last now!
+ sorted.addLast(md);
+ }
+
+ public void addDependent(MethodDescriptor callee, MethodDescriptor caller) {
+ Set<MethodDescriptor> deps = mapDescriptorToSetDependents.get(callee);
+ if (deps == null) {
+ deps = new HashSet<MethodDescriptor>();
+ }
+ deps.add(caller);
+ mapDescriptorToSetDependents.put(callee, deps);
+ }
+
+ public Set<MethodDescriptor> getDependents(MethodDescriptor callee) {
+ Set<MethodDescriptor> deps = mapDescriptorToSetDependents.get(callee);
+ if (deps == null) {
+ deps = new HashSet<MethodDescriptor>();
+ mapDescriptorToSetDependents.put(callee, deps);
+ }
+ return deps;
+ }
+