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:
sjfink 2007-11-13 16:19:15 +00:00
parent 471e6b1b3e
commit 2a1213789b
12 changed files with 134 additions and 60 deletions

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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");
}
}
}
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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()");

View File

@ -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");
}

View File

@ -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()");

View File

@ -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;

View File

@ -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);
}