add CancelException to interact with Eclipse progress monitors and thread it through some APIs
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2006 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
471e6b1b3e
commit
2a1213789b
|
@ -22,6 +22,7 @@ import com.ibm.wala.classLoader.JarFileModule;
|
|||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.client.AnalysisEngine;
|
||||
import com.ibm.wala.client.CallGraphBuilderFactory;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.emf.wrappers.EMFScopeWrapper;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -149,7 +150,7 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine {
|
|||
return getCallGraphBuilderFactory().make(options, cache, cha, getScope(), false);
|
||||
}
|
||||
|
||||
protected CallGraphBuilder buildCallGraph(IClassHierarchy cha, AnalysisOptions options, boolean savePointerAnalysis) {
|
||||
protected CallGraphBuilder buildCallGraph(IClassHierarchy cha, AnalysisOptions options, boolean savePointerAnalysis) throws IllegalArgumentException, CancelException {
|
||||
Assertions.productionAssertion(getCallGraphBuilderFactory() != null, "must initialize callGraphBuilderFactory!");
|
||||
|
||||
CallGraphBuilder builder = getCallGraphBuilder(cha, options, cache);
|
||||
|
@ -349,8 +350,10 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine {
|
|||
/**
|
||||
* Builds the call graph for the analysis scope in effect, using all of the
|
||||
* given entry points.
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public CallGraphBuilder defaultCallGraphBuilder() {
|
||||
public CallGraphBuilder defaultCallGraphBuilder() throws IllegalArgumentException, CancelException {
|
||||
buildAnalysisScope();
|
||||
IClassHierarchy cha = buildClassHierarchy();
|
||||
setClassHierarchy(cha);
|
||||
|
@ -360,7 +363,7 @@ public abstract class AbstractAnalysisEngine implements AnalysisEngine {
|
|||
return buildCallGraph(cha, options, true);
|
||||
}
|
||||
|
||||
public CallGraph buildDefaultCallGraph() {
|
||||
public CallGraph buildDefaultCallGraph() throws IllegalArgumentException, CancelException {
|
||||
return defaultCallGraphBuilder().makeCallGraph(options);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,11 @@ import java.util.TreeMap;
|
|||
import java.util.TreeSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.eclipse.util.MonitorUtil;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.util.ReferenceCleanser;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
|
@ -120,16 +124,6 @@ public class TabulationSolver<T, P> {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* solver allows interruption
|
||||
*/
|
||||
static protected final boolean INTERRUPTIBLE = true;
|
||||
|
||||
/**
|
||||
* how frequently to check for interruption?
|
||||
*/
|
||||
static final private int INTERRUPT_LATENCY = 20;
|
||||
|
||||
/**
|
||||
* The supergraph which induces this dataflow problem
|
||||
*/
|
||||
|
@ -173,6 +167,11 @@ public class TabulationSolver<T, P> {
|
|||
* The worklist
|
||||
*/
|
||||
final protected Worklist worklist = new Worklist();
|
||||
|
||||
/**
|
||||
* A progress monitor. can be null.
|
||||
*/
|
||||
private final IProgressMonitor progressMonitor;
|
||||
|
||||
/**
|
||||
* @param p
|
||||
|
@ -180,7 +179,7 @@ public class TabulationSolver<T, P> {
|
|||
* @throws IllegalArgumentException
|
||||
* if p is null
|
||||
*/
|
||||
protected TabulationSolver(TabulationProblem<T, P> p) {
|
||||
protected TabulationSolver(TabulationProblem<T, P> p, IProgressMonitor monitor) {
|
||||
if (p == null) {
|
||||
throw new IllegalArgumentException("p is null");
|
||||
}
|
||||
|
@ -191,6 +190,7 @@ public class TabulationSolver<T, P> {
|
|||
this.flowFunctionMap = IdentityFlowFunctions.singleton();
|
||||
}
|
||||
this.problem = p;
|
||||
this.progressMonitor = monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,16 +200,15 @@ public class TabulationSolver<T, P> {
|
|||
* if p is null
|
||||
*/
|
||||
public static <T, P> TabulationSolver<T, P> make(TabulationProblem<T, P> p) {
|
||||
return new TabulationSolver<T, P>(p);
|
||||
return new TabulationSolver<T, P>(p, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve the dataflow problem.
|
||||
*
|
||||
* @return a representation of the result
|
||||
* @throws SolverInterruptedException
|
||||
*/
|
||||
public TabulationResult<T, P> solve() throws SolverInterruptedException {
|
||||
public TabulationResult<T, P> solve() throws CancelException {
|
||||
EngineTimings.startVirtual("TabulationSolver.solve()");
|
||||
|
||||
EngineTimings.startVirtual("TabulationSolver.initialize");
|
||||
|
@ -244,27 +243,17 @@ public class TabulationSolver<T, P> {
|
|||
/**
|
||||
* See POPL 95 paper for this algorithm, Figure 3
|
||||
*
|
||||
* @throws SolverInterruptedException
|
||||
* @throws CancelException
|
||||
*/
|
||||
private void forwardTabulateSLRPs() throws SolverInterruptedException {
|
||||
int interrupt = 0;
|
||||
private void forwardTabulateSLRPs() throws CancelException {
|
||||
while (worklist.size() > 0) {
|
||||
MonitorUtil.throwExceptionIfCanceled(progressMonitor);
|
||||
if (verbose) {
|
||||
performVerboseAction();
|
||||
}
|
||||
if (PERIODIC_WIPE_SOFT_CACHES) {
|
||||
tendToSoftCaches();
|
||||
}
|
||||
if (INTERRUPTIBLE) {
|
||||
// checking Thread.interrupted is expensive. Don't do it every time.
|
||||
interrupt++;
|
||||
if (interrupt % INTERRUPT_LATENCY == 0) {
|
||||
interrupt = 0;
|
||||
if (Thread.interrupted()) {
|
||||
throw new SolverInterruptedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PathEdge edge = popFromWorkList();
|
||||
if (DEBUG_LEVEL > 0) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,13 +8,22 @@
|
|||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.dataflow.IFDS;
|
||||
package com.ibm.wala.eclipse.util;
|
||||
|
||||
public class SolverInterruptedException extends Exception {
|
||||
/**
|
||||
* An exception for when work is canceled in eclipse.
|
||||
*
|
||||
* @author sjfink
|
||||
*
|
||||
*/
|
||||
public class CancelException extends Exception {
|
||||
|
||||
/**
|
||||
* UID
|
||||
*/
|
||||
private static final long serialVersionUID = -32488844370356591L;
|
||||
private CancelException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public static CancelException make(String msg) {
|
||||
return new CancelException(msg);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.eclipse.util;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
|
||||
/**
|
||||
* Simple utilities for Eclipse progress monitors
|
||||
*
|
||||
* @author sjfink
|
||||
*
|
||||
*/
|
||||
public class MonitorUtil {
|
||||
|
||||
public static void beginTask(IProgressMonitor monitor, String task, int totalWork) throws CancelException {
|
||||
if (monitor != null) {
|
||||
monitor.beginTask(task, totalWork);
|
||||
if (monitor.isCanceled()) {
|
||||
throw CancelException.make("cancelled in " + task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void done(IProgressMonitor monitor) throws CancelException {
|
||||
if (monitor != null) {
|
||||
monitor.done();
|
||||
if (monitor.isCanceled()) {
|
||||
throw CancelException.make("cancelled in " + monitor.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void worked(IProgressMonitor monitor, int units) throws CancelException {
|
||||
if (monitor != null) {
|
||||
monitor.worked(units);
|
||||
if (monitor.isCanceled()) {
|
||||
throw CancelException.make("cancelled in " + monitor.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void throwExceptionIfCanceled(IProgressMonitor progressMonitor) throws CancelException {
|
||||
if (progressMonitor != null) {
|
||||
if (progressMonitor.isCanceled()) {
|
||||
throw CancelException.make("operation cancelled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerFlowGraphFactory;
|
||||
|
||||
|
@ -27,8 +28,10 @@ public interface CallGraphBuilder {
|
|||
* @param options an object representing controlling options that the call
|
||||
* graph building algorithm needs to know.
|
||||
* @return the built call graph
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public CallGraph makeCallGraph(AnalysisOptions options);
|
||||
public CallGraph makeCallGraph(AnalysisOptions options) throws IllegalArgumentException, CancelException;
|
||||
|
||||
/**
|
||||
* @return the Pointer Analysis information computed as a side-effect of
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph.propagation;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
|
||||
|
||||
/**
|
||||
* abstract base class for solver for pointer analysis
|
||||
|
@ -35,7 +37,7 @@ public abstract class AbstractPointsToSolver implements IPointsToSolver {
|
|||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve()
|
||||
*/
|
||||
public abstract void solve();
|
||||
public abstract void solve() throws IllegalArgumentException, CancelException;
|
||||
|
||||
protected PropagationCallGraphBuilder getBuilder() {
|
||||
return builder;
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph.propagation;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
*/
|
||||
public interface IPointsToSolver {
|
||||
|
||||
public void solve();
|
||||
public void solve() throws IllegalArgumentException, CancelException;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Collection;
|
|||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractFixedPointSolver;
|
||||
import com.ibm.wala.fixedpoint.impl.AbstractStatement;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryStatement;
|
||||
|
@ -61,7 +62,7 @@ public class PreTransitiveSolver extends AbstractPointsToSolver {
|
|||
* @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve()
|
||||
*/
|
||||
@Override
|
||||
public void solve() {
|
||||
public void solve() throws IllegalArgumentException, CancelException {
|
||||
|
||||
EngineTimings.startVirtual("PreTransitiveSolver.solve()");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.ibm.wala.classLoader.IMethod;
|
|||
import com.ibm.wala.classLoader.Language;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.SyntheticClass;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
|
@ -258,7 +259,7 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
/*
|
||||
* @see com.ibm.wala.ipa.callgraph.CallGraphBuilder#makeCallGraph(com.ibm.wala.ipa.callgraph.AnalysisOptions)
|
||||
*/
|
||||
public CallGraph makeCallGraph(AnalysisOptions options) {
|
||||
public CallGraph makeCallGraph(AnalysisOptions options) throws IllegalArgumentException, CancelException {
|
||||
if (options == null) {
|
||||
throw new IllegalArgumentException("options is null");
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Set;
|
|||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.SyntheticMethod;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
|
@ -60,8 +61,10 @@ public class ReflectionHandler {
|
|||
* results to checkcasts
|
||||
*
|
||||
* @return true if anything has changed
|
||||
* @throws CancelException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
protected boolean updateForReflection() {
|
||||
protected boolean updateForReflection() throws IllegalArgumentException, CancelException {
|
||||
|
||||
EngineTimings.startVirtual("ReflectionHandler.updateForReflection()");
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph.propagation;
|
||||
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.perf.EngineTimings;
|
||||
|
||||
|
@ -33,7 +34,7 @@ public class StandardSolver extends AbstractPointsToSolver {
|
|||
* @see com.ibm.wala.ipa.callgraph.propagation.IPointsToSolver#solve()
|
||||
*/
|
||||
@Override
|
||||
public void solve() {
|
||||
public void solve() throws IllegalArgumentException, CancelException {
|
||||
|
||||
EngineTimings.startVirtual("StandardSolver.solve()");
|
||||
int i = 0;
|
||||
|
|
|
@ -18,11 +18,11 @@ import com.ibm.wala.dataflow.IFDS.BackwardsSupergraph;
|
|||
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
|
||||
import com.ibm.wala.dataflow.IFDS.IMergeFunction;
|
||||
import com.ibm.wala.dataflow.IFDS.ISupergraph;
|
||||
import com.ibm.wala.dataflow.IFDS.SolverInterruptedException;
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationProblem;
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationResult;
|
||||
import com.ibm.wala.dataflow.IFDS.TabulationSolver;
|
||||
import com.ibm.wala.eclipse.util.CancelException;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.modref.ModRef;
|
||||
|
@ -147,9 +147,10 @@ public class Slicer {
|
|||
* @param s
|
||||
* a statement of interest
|
||||
* @return the backward slice of s.
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(Statement s, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException {
|
||||
return computeSlice(null, Collections.singleton(s), cg, pa, dOptions, cOptions, true);
|
||||
}
|
||||
|
||||
|
@ -157,47 +158,52 @@ public class Slicer {
|
|||
* @param s
|
||||
* a statement of interest
|
||||
* @return the forward slice of s.
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeForwardSlice(Statement s, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException {
|
||||
return computeSlice(null, Collections.singleton(s), cg, pa, dOptions, cOptions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the passed-in SDG
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(SDG sdg, Statement s, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException {
|
||||
return computeSlice(sdg, Collections.singleton(s), cg, pa, dOptions, cOptions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the passed-in SDG
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeForwardSlice(SDG sdg, Statement s, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException {
|
||||
return computeSlice(sdg, Collections.singleton(s), cg, pa, dOptions, cOptions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the passed-in SDG
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) throws IllegalArgumentException, CancelException {
|
||||
return computeSlice(sdg, ss, cg, pa, dOptions, cOptions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ss
|
||||
* a collection of statements of interest
|
||||
* @throws CancelException
|
||||
*/
|
||||
protected static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) throws CancelException {
|
||||
return computeSlice(sdg, ss, cg, pa, ModRef.make(), dOptions, cOptions, backward);
|
||||
}
|
||||
|
||||
protected static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, CallGraph cg, PointerAnalysis pa, ModRef modRef,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) {
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) throws CancelException {
|
||||
|
||||
if (VERBOSE) {
|
||||
System.err.println("Build SDG...");
|
||||
|
@ -227,13 +233,8 @@ public class Slicer {
|
|||
}
|
||||
|
||||
TabulationSolver<Statement, PDG> solver = TabulationSolver.make(p);
|
||||
TabulationResult<Statement, PDG> tr = null;
|
||||
try {
|
||||
tr = solver.solve();
|
||||
} catch (SolverInterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
TabulationResult<Statement, PDG> tr = solver.solve();
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println("RESULT");
|
||||
System.err.println(tr);
|
||||
|
@ -361,9 +362,10 @@ public class Slicer {
|
|||
* @param s
|
||||
* a statement of interest
|
||||
* @return the backward slice of s.
|
||||
* @throws CancelException
|
||||
*/
|
||||
public static Collection<Statement> computeBackwardSlice(Statement s, CallGraph cg, PointerAnalysis pointerAnalysis)
|
||||
throws IllegalArgumentException {
|
||||
throws IllegalArgumentException, CancelException {
|
||||
return computeBackwardSlice(s, cg, pointerAnalysis, DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue