Skip to content

Commit

Permalink
Merge branch 'mergetest' into develop
Browse files Browse the repository at this point in the history
This merges commits by Steven Lambeth which improve the performance of SmartLocalDefs and other intra-procedural analyses through a BitSet-based implementation.
  • Loading branch information
Eric Bodden committed Jan 15, 2014
2 parents 3592314 + 5ba2678 commit 01e6122
Show file tree
Hide file tree
Showing 8 changed files with 518 additions and 564 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Improvements and API changes in HEAD

12. EquivalentValue is never nested now. This eliminates the need of
getDeepestValue().

13. Multiple performance improvements for intra-procedural analyses and class loading

Improvements and API changes in version 2.5.0

Expand Down
3 changes: 3 additions & 0 deletions credits
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ John Jorgensen ([email protected])

Felix Kwok ([email protected])
- VTA re-implementation

Steven Lambeth
- BitSet based implementation of FlowAnalysis and other performance improvements

Patrick Lam ([email protected])
- general Soot hacker
Expand Down
105 changes: 60 additions & 45 deletions src/soot/toolkits/graph/PseudoTopologicalOrderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,52 @@

package soot.toolkits.graph;

import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.IdentityHashMap;

/**
* Orders in pseudo-topological order, the nodes of a DirectedGraph instance.
*/

/* Updated By Marc Berndl May 13 */

/**
* @author Steven Lambeth
*/
public class PseudoTopologicalOrderer<N> implements Orderer<N> {
private static final Object VISITED = new Object();

public static final boolean REVERSE = true;

public PseudoTopologicalOrderer() {}
private Map<N, Object> visited;

private Map<Object, Object> stmtToColor;

private static final Object GRAY = new Object();
private int[] indexStack;

private LinkedList<N> order;
private N[] stmtStack;
private N[] order;
private int orderLength;

private boolean mIsReversed = false;

private DirectedGraph<N> graph;

private int[] indexStack;

private N[] stmtStack;
public PseudoTopologicalOrderer() {
}

private int last;
/**
* Reverses the order of the elements in the specified array.
*
* @param array
*/
private static <T> void reverseArray(T[] array) {
final int max = array.length >> 1;
for (int i = 0, j = array.length - 1; i < max; i++, j--) {
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

/**
* {@inheritDoc}
Expand All @@ -73,40 +87,46 @@ public List<N> newList(DirectedGraph<N> g, boolean reverse) {
* a DirectedGraph instance we want to order the nodes for.
* @return an ordered list of the graph's nodes.
*/

@SuppressWarnings("unchecked")
protected List<N> computeOrder(DirectedGraph<N> g) {
stmtToColor = new IdentityHashMap<Object, Object>((3 * g.size()) / 2);//new HashMap((3 * g.size()) / 2, 0.7f);
indexStack = new int[g.size()];
stmtStack = (N[]) new Object[g.size()];
order = new LinkedList<N>();
protected final List<N> computeOrder(DirectedGraph<N> g) {
final int n = g.size();
visited = new IdentityHashMap<N, Object>(n*2+1);//new HashMap((3 * g.size()) / 2, 0.7f);
indexStack = new int[n];
stmtStack = (N[]) new Object[n];
order = (N[]) new Object[n];
graph = g;
orderLength = 0;

// Visit each node
{
Iterator<N> stmtIt = g.iterator();
while (stmtIt.hasNext()) {
N s = stmtIt.next();
if (stmtToColor.get(s) == null)
visitNode(s);
}
for (N s : g) {
if (visited.put(s, VISITED) != VISITED)
visitNode(s);
}

assert (orderLength == n);

if (!mIsReversed)
reverseArray(order);

List<N> o = Arrays.asList(order);

indexStack = null;
stmtStack = null;
stmtToColor = null;
return order;
visited = null;
order = null;

return o;
}

// Unfortunately, the nice recursive solution fails
// because of stack overflows

// Fill in the 'order' list with a pseudo topological order (possibly
// reversed)
// Fill in the 'order' list with a pseudo topological order
// list of statements starting at s. Simulates recursion with a stack.

protected void visitNode(N startStmt) {
last = 0;

stmtToColor.put(startStmt, GRAY);
protected final void visitNode(N startStmt) {
int last = 0;

stmtStack[last] = startStmt;
indexStack[last++] = -1;
Expand All @@ -117,27 +137,22 @@ protected void visitNode(N startStmt) {
List<N> succs = graph.getSuccsOf(toVisitNode);
if (toVisitIndex >= succs.size()) {
// Visit this node now that we ran out of children
if (mIsReversed)
order.addLast(toVisitNode);
else
order.addFirst(toVisitNode);
order[orderLength++] = toVisitNode;

last--;
} else {
N childNode = succs.get(
toVisitIndex);
N childNode = succs.get(toVisitIndex);

if (stmtToColor.get(childNode) == null) {
stmtToColor.put(childNode, GRAY);
if ( visited.put(childNode, VISITED) != VISITED ) {
stmtStack[last] = childNode;
indexStack[last++] = -1;
}
}
}
}

//deprecated methods and constructors follow
// deprecated methods and constructors follow

/**
* @deprecated use {@link #PseudoTopologicalOrderer()} instead
*/
Expand All @@ -151,7 +166,7 @@ public PseudoTopologicalOrderer(boolean isReversed) {
* @return a pseudo-topologically ordered list of the graph's nodes.
* @deprecated use {@link #newList(DirectedGraph, boolean))} instead
*/
public List<N> newList(DirectedGraph g) {
public List<N> newList(DirectedGraph<N> g) {
return computeOrder(g);
}

Expand All @@ -178,5 +193,5 @@ public boolean isReverseOrder() {
return mIsReversed;
}


}

4 changes: 2 additions & 2 deletions src/soot/toolkits/scalar/AbstractFlowAnalysis.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

package soot.toolkits.scalar;

import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;

import soot.jimple.Stmt;
Expand Down Expand Up @@ -54,7 +54,7 @@ public abstract class AbstractFlowAnalysis<N,A>
/** Constructs a flow analysis on the given <code>DirectedGraph</code>. */
public AbstractFlowAnalysis(DirectedGraph<N> graph)
{
unitToBeforeFlow = new HashMap<N,A>(graph.size() * 2 + 1, 0.7f);
unitToBeforeFlow = new IdentityHashMap<N,A>(graph.size() * 2 + 1);
this.graph = graph;
if (Options.v().interactive_mode()){
InteractionHandler.v().handleCfgEvent(graph);
Expand Down
Loading

0 comments on commit 01e6122

Please sign in to comment.