miscellaneous housekeeping
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1364 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
dd8d708fc3
commit
8864b70d50
|
@ -79,7 +79,7 @@ public class BasicHeapGraph extends HeapGraph {
|
|||
this.pointerAnalysis = P;
|
||||
this.callGraph = callGraph;
|
||||
|
||||
final OrdinalSetMapping<PointerKey> pointerKeys = getPointerKeys(P);
|
||||
final OrdinalSetMapping<PointerKey> pointerKeys = getPointerKeys();
|
||||
final NumberedNodeManager<Object> nodeMgr = new NumberedNodeManager<Object>() {
|
||||
public Iterator<Object> iterator() {
|
||||
return new CompoundIterator<Object>(pointerKeys.iterator(), P.getInstanceKeyMapping().iterator());
|
||||
|
@ -208,10 +208,7 @@ public class BasicHeapGraph extends HeapGraph {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private OrdinalSetMapping<PointerKey> getPointerKeys(PointerAnalysis pointerAnalysis) {
|
||||
private OrdinalSetMapping<PointerKey> getPointerKeys() {
|
||||
MutableMapping<PointerKey> result = new MutableMapping<PointerKey>();
|
||||
|
||||
for (Iterator<PointerKey> it = pointerAnalysis.getPointerKeys().iterator(); it.hasNext();) {
|
||||
|
|
|
@ -63,7 +63,6 @@ import com.ibm.wala.util.warnings.Warning;
|
|||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* Logic to interpret "factory" methods in context.
|
||||
*
|
||||
* @author sfink
|
||||
|
@ -97,7 +96,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
/**
|
||||
* Keep track of analysis warnings
|
||||
*/
|
||||
private WarningSet warnings;
|
||||
private WarningSet warningsSet;
|
||||
|
||||
/**
|
||||
* User-defined reflection specification
|
||||
|
@ -113,7 +112,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
*/
|
||||
public FactoryBypassInterpreter(AnalysisOptions options, ReflectionSpecification userSpec, WarningSet warnings) {
|
||||
this.options = options;
|
||||
this.warnings = warnings;
|
||||
this.warningsSet = warnings;
|
||||
this.userSpec = userSpec;
|
||||
}
|
||||
|
||||
|
@ -339,10 +338,10 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
if (DEBUG) {
|
||||
Trace.println("Found no implementors of type " + T);
|
||||
}
|
||||
warnings.add(NoSubtypesWarning.create(T));
|
||||
warningsSet.add(NoSubtypesWarning.create(T));
|
||||
}
|
||||
if (implementors.size() > CONE_BOUND) {
|
||||
warnings.add(ManySubtypesWarning.create(T, implementors.size()));
|
||||
warningsSet.add(ManySubtypesWarning.create(T, implementors.size()));
|
||||
}
|
||||
|
||||
addStatementsForSetOfTypes(implementors.iterator());
|
||||
|
@ -355,10 +354,10 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
if (DEBUG) {
|
||||
Trace.println("Found no subclasses of type " + T);
|
||||
}
|
||||
warnings.add(NoSubtypesWarning.create(T));
|
||||
warningsSet.add(NoSubtypesWarning.create(T));
|
||||
}
|
||||
if (subclasses.size() > CONE_BOUND) {
|
||||
warnings.add(ManySubtypesWarning.create(T, subclasses.size()));
|
||||
warningsSet.add(ManySubtypesWarning.create(T, subclasses.size()));
|
||||
}
|
||||
addStatementsForSetOfTypes(subclasses.iterator());
|
||||
}
|
||||
|
@ -375,7 +374,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
private TypeAbstraction interceptType(TypeAbstraction T) {
|
||||
TypeReference type = T.getType().getReference();
|
||||
if (type.equals(TypeReference.JavaIoSerializable)) {
|
||||
warnings.add(IgnoreSerializableWarning.create());
|
||||
warningsSet.add(IgnoreSerializableWarning.create());
|
||||
return null;
|
||||
} else {
|
||||
return T;
|
||||
|
@ -623,7 +622,7 @@ public class FactoryBypassInterpreter implements RTAContextInterpreter, SSAConte
|
|||
* @see com.ibm.wala.ipa.callgraph.propagation.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet)
|
||||
*/
|
||||
public void setWarnings(WarningSet newWarnings) {
|
||||
this.warnings = newWarnings;
|
||||
this.warningsSet = newWarnings;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -882,9 +882,9 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
|
|||
/**
|
||||
* Initialize the visitor used to perform the flow functions
|
||||
*/
|
||||
protected void init(BasicStackMachineVisitor visitor, com.ibm.wala.shrikeBT.Instruction.Visitor edgeVisitor) {
|
||||
this.visitor = visitor;
|
||||
this.edgeVisitor = edgeVisitor;
|
||||
protected void init(BasicStackMachineVisitor v, com.ibm.wala.shrikeBT.Instruction.Visitor ev) {
|
||||
this.visitor = v;
|
||||
this.edgeVisitor = ev;
|
||||
}
|
||||
|
||||
public boolean needsNodeFlow() {
|
||||
|
|
|
@ -115,7 +115,7 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
|||
if (klass != null) {
|
||||
v.setType(new ConeType(klass));
|
||||
} else {
|
||||
v.setType(ConeType.TOP);
|
||||
v.setType(TypeAbstraction.TOP);
|
||||
// v.setType(BOTTOM);
|
||||
}
|
||||
} else if (doPrimitives) {
|
||||
|
@ -432,13 +432,10 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
|||
}
|
||||
} else {
|
||||
IClass klass = cha.lookupClass(elementType);
|
||||
// if (Assertions.verifyAssertions) {
|
||||
// Assertions._assert(klass != null);
|
||||
// }
|
||||
if (klass != null) {
|
||||
t.setType(new ConeType(klass));
|
||||
} else {
|
||||
t.setType(ConeType.TOP);
|
||||
t.setType(TypeAbstraction.TOP);
|
||||
}
|
||||
|
||||
return CHANGED;
|
||||
|
@ -583,12 +580,11 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
|||
if (doPrimitives) {
|
||||
result = new DeclaredTypeOperator(PrimitiveType.BOOLEAN);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitGetCaughtException(SSAGetCaughtExceptionInstruction instruction) {
|
||||
TypeAbstraction type = meetDeclaredExceptionTypes(instruction, cha);
|
||||
TypeAbstraction type = meetDeclaredExceptionTypes(instruction);
|
||||
result = new DeclaredTypeOperator(type);
|
||||
}
|
||||
|
||||
|
@ -602,7 +598,7 @@ public class TypeInference extends SSAInference implements FixedPointConstants {
|
|||
result = piOp;
|
||||
}
|
||||
|
||||
private TypeAbstraction meetDeclaredExceptionTypes(SSAGetCaughtExceptionInstruction s, IClassHierarchy cha) {
|
||||
private TypeAbstraction meetDeclaredExceptionTypes(SSAGetCaughtExceptionInstruction s) {
|
||||
ExceptionHandlerBasicBlock bb = (ExceptionHandlerBasicBlock) ir.getControlFlowGraph().getNode(s.getBasicBlockNumber());
|
||||
Iterator it = bb.getCaughtExceptionTypes();
|
||||
TypeReference t = (TypeReference) it.next();
|
||||
|
|
|
@ -75,7 +75,7 @@ public class CFGCache {
|
|||
return null;
|
||||
}
|
||||
|
||||
processResetLogic(m);
|
||||
processResetLogic();
|
||||
|
||||
Pair<IMethod,Context> p = new Pair<IMethod,Context>(m, C);
|
||||
Object ref = dictionary.get(p);
|
||||
|
@ -90,7 +90,7 @@ public class CFGCache {
|
|||
}
|
||||
}
|
||||
|
||||
private void processResetLogic(IMethod m) {
|
||||
private void processResetLogic() {
|
||||
resetCount++;
|
||||
if (resetCount == RESET_INTERVAL) {
|
||||
reset();
|
||||
|
|
|
@ -48,7 +48,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
if (Assertions.verifyAssertions) {
|
||||
TypeReference elementType = type.getInnermostElementType();
|
||||
if (!elementType.isPrimitiveType()) {
|
||||
IClass klass = loader.lookupClass(elementType.getName(), cha);
|
||||
IClass klass = loader.lookupClass(elementType.getName());
|
||||
if (klass == null) {
|
||||
Assertions.UNREACHABLE("caller should not attempt to create an array with type " + type);
|
||||
}
|
||||
|
@ -114,14 +114,14 @@ public class ArrayClass implements IClass, Constants {
|
|||
// 1) [Ljava/lang/Object
|
||||
// 2) [? for primitive arrays (null from getElementClass)
|
||||
if (elt == null || elt.getReference() == TypeReference.JavaLangObject) {
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
}
|
||||
|
||||
// else it is array of super of element type (yuck)
|
||||
else {
|
||||
TypeReference eltSuperRef = elt.getSuperclass().getReference();
|
||||
TypeReference superRef = TypeReference.findOrCreateArrayOf(eltSuperRef);
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName(), getClassHierarchy());
|
||||
return elt.getSuperclass().getClassLoader().lookupClass(superRef.getName());
|
||||
}
|
||||
} catch (ClassHierarchyException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -134,7 +134,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
* @see com.ibm.wala.classLoader.IClass#getMethod(com.ibm.wala.classLoader.Selector)
|
||||
*/
|
||||
public IMethod getMethod(Selector sig) {
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy()).getMethod(sig);
|
||||
return loader.lookupClass(TypeReference.JavaLangObject.getName()).getMethod(sig);
|
||||
}
|
||||
|
||||
public IField getField(Atom name) {
|
||||
|
@ -194,7 +194,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
if (elementType.isPrimitiveType()) {
|
||||
return null;
|
||||
}
|
||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
||||
return loader.lookupClass(elementType.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -223,8 +223,8 @@ public class ArrayClass implements IClass, Constants {
|
|||
*/
|
||||
public Collection<IClass> getAllImplementedInterfaces() {
|
||||
HashSet<IClass> result = HashSetFactory.make(2);
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[0], getClassHierarchy()));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[1], getClassHierarchy()));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[0]));
|
||||
result.add(loader.lookupClass(TypeReference.array_interfaces[1]));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ public class ArrayClass implements IClass, Constants {
|
|||
if (elementType.isPrimitiveType()) {
|
||||
return null;
|
||||
}
|
||||
return loader.lookupClass(elementType.getName(), getClassHierarchy());
|
||||
return loader.lookupClass(elementType.getName());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -62,7 +62,7 @@ public class ArrayClassLoader {
|
|||
arrayClass = arrayClasses.get(type);
|
||||
if (arrayClass == null) {
|
||||
// check that the element class is loadable. If not, return null.
|
||||
IClass elementCls = delegator.lookupClass(elementType.getName(), cha);
|
||||
IClass elementCls = delegator.lookupClass(elementType.getName());
|
||||
if (elementCls == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ public class ClassLoaderFactoryImpl implements ClassLoaderFactory {
|
|||
cl = new ClassLoaderImpl(classLoaderReference, scope.getArrayClassLoader(), parent, exclusions, cha, warnings);
|
||||
} else
|
||||
try {
|
||||
// this is fragile. why are we doing things this way again?
|
||||
Class<?> impl = Class.forName(implClass);
|
||||
Constructor<?> ctor = impl.getDeclaredConstructor(new Class[] { ClassLoaderReference.class, IClassLoader.class,
|
||||
SetOfClasses.class, IClassHierarchy.class, WarningSet.class });
|
||||
|
@ -109,8 +110,6 @@ public class ClassLoaderFactoryImpl implements ClassLoaderFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* @author sfink
|
||||
*
|
||||
* A waring when we fail to load an appropriate class loader implementation
|
||||
*/
|
||||
private static class InvalidClassLoaderImplementation extends Warning {
|
||||
|
|
|
@ -400,7 +400,7 @@ public class ClassLoaderImpl implements IClassLoader {
|
|||
return loadedClasses.get(className);
|
||||
}
|
||||
|
||||
public IClass lookupClass(TypeName className, IClassHierarchy cha) {
|
||||
public IClass lookupClass(TypeName className) {
|
||||
if (className == null) {
|
||||
throw new IllegalArgumentException("className is null");
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.Collection;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.util.Atom;
|
||||
|
@ -37,7 +36,7 @@ public interface IClassLoader {
|
|||
* @return the IClass defined by this class loader that
|
||||
* corresponds to the given class name, or null if not found.
|
||||
*/
|
||||
public abstract IClass lookupClass(TypeName className, IClassHierarchy cha);
|
||||
public abstract IClass lookupClass(TypeName className);
|
||||
|
||||
/**
|
||||
* Return the ClassLoaderReference for this class loader.
|
||||
|
@ -46,7 +45,7 @@ public interface IClassLoader {
|
|||
public abstract ClassLoaderReference getReference();
|
||||
|
||||
/**
|
||||
* @return an Iterator of all classees loaded by this loader
|
||||
* @return an Iterator of all classes loaded by this loader
|
||||
*/
|
||||
public abstract Iterator<IClass> iterateAllClasses();
|
||||
|
||||
|
|
|
@ -284,12 +284,12 @@ public final class ShrikeClass implements IClass {
|
|||
|
||||
if (superName == null) {
|
||||
if (!getReference().equals(TypeReference.JavaLangObject)) {
|
||||
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
superClass = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
superClass = loader.lookupClass(TypeName.findOrCreate(superName), getClassHierarchy());
|
||||
superClass = loader.lookupClass(TypeName.findOrCreate(superName));
|
||||
if (DEBUG) {
|
||||
Trace.println("got superclass " + superClass + " for " + this);
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ public final class ShrikeClass implements IClass {
|
|||
for (int i = 0; i < interfaces.length; i++) {
|
||||
ImmutableByteArray name = interfaces[i];
|
||||
IClass klass = null;
|
||||
klass = loader.lookupClass(TypeName.findOrCreate(name), getClassHierarchy());
|
||||
klass = loader.lookupClass(TypeName.findOrCreate(name));
|
||||
if (klass == null) {
|
||||
warnings.add(ClassNotFoundWarning.create(name));
|
||||
} else {
|
||||
|
|
|
@ -104,7 +104,7 @@ public class ShrikeIRFactory implements IRFactory {
|
|||
|
||||
{
|
||||
SSABuilder builder = new SSABuilder((ShrikeCTMethod) method, newCfg, shrikeCFG, newInstrs, symbolTable, buildLocalMap,
|
||||
options.getUsePiNodes(), warnings);
|
||||
options.getUsePiNodes());
|
||||
builder.build();
|
||||
if (buildLocalMap)
|
||||
localMap = builder.getLocalMap();
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.ibm.wala.types.TypeReference;
|
|||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.bytecode.BytecodeStream;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.UnimplementedError;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
|
@ -237,16 +238,22 @@ public class SyntheticMethod implements IMethod {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options options governing SSA construction
|
||||
*/
|
||||
public SSAInstruction[] getStatements(SSAOptions options) {
|
||||
return NO_STATEMENTS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.IMethod#getIR(com.ibm.wala.util.WarningSet)
|
||||
|
||||
/**
|
||||
* Most subclasses should override this.
|
||||
*
|
||||
* @param options options governing IR conversion
|
||||
* @param warnings object to record analysis warnings
|
||||
*/
|
||||
public IR makeIR(SSAOptions options, WarningSet warnings) {
|
||||
Assertions.UNREACHABLE("haven't implemented IR yet for class " + getClass());
|
||||
return null;
|
||||
public IR makeIR(SSAOptions options, WarningSet warnings) throws UnimplementedError {
|
||||
throw new UnimplementedError("haven't implemented IR yet for class " + getClass());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -419,17 +419,16 @@ public class ExplodedSupergraphPath<T> {
|
|||
*/
|
||||
public static <T> ExplodedSupergraphPath<T> summarize(ISupergraph<T,?> supergraph, ExplodedSupergraphPath<T> path) {
|
||||
pruneForCallReturn(supergraph, path);
|
||||
// System.err.println("pruned path A: " + p);
|
||||
pruneBoringCalls(supergraph, path);
|
||||
pruneBoringCalls(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a brief(er) summary of a path, which excludes call/return pairs in
|
||||
* Create a briefer summary of a path, which excludes call/return pairs in
|
||||
* which no state transitions occur
|
||||
* @throws IllegalArgumentException if path is null
|
||||
*/
|
||||
public static <T> void pruneBoringCalls(ISupergraph supergraph, ExplodedSupergraphPath<T> path) {
|
||||
public static <T> void pruneBoringCalls(ExplodedSupergraphPath<T> path) {
|
||||
if (path == null) {
|
||||
throw new IllegalArgumentException("path is null");
|
||||
}
|
||||
|
|
|
@ -97,17 +97,6 @@ public class PartiallyCollapsedSupergraph extends AbstractGraph<Object> implemen
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param cg
|
||||
* Governing call graph
|
||||
* @param noCollapse
|
||||
* set of nodes in the call graph which cannot be collapsed
|
||||
* @param warnings
|
||||
* object to track analysis warnings
|
||||
*/
|
||||
public PartiallyCollapsedSupergraph(CallGraph cg, CFGCache cfgCache, Collection<CGNode> noCollapse, WarningSet warnings) {
|
||||
this(cg, noCollapse, IndiscriminateFilter.singleton(), warnings);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cg
|
||||
|
|
|
@ -84,7 +84,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
|
||||
private final String scopeFile;
|
||||
|
||||
private final ClassLoader loader;
|
||||
private final ClassLoader classloader;
|
||||
|
||||
private static final Object SUCCESS = new Object();
|
||||
|
||||
|
@ -100,7 +100,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
* files provided)
|
||||
*/
|
||||
protected EMFScopeWrapper(final ClassLoader loader) {
|
||||
this.loader = loader;
|
||||
this.classloader = loader;
|
||||
this.scopeFile = null;
|
||||
this.exclusionsFile = null;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
public EMFScopeWrapper(String scopeFile, String exclusionsFile, ClassLoader loader, boolean scopeAsFile) {
|
||||
super();
|
||||
this.scopeFile = scopeFile;
|
||||
this.loader = loader;
|
||||
this.classloader = loader;
|
||||
|
||||
if (DEBUG_LEVEL > 0) {
|
||||
Trace.println(getClass() + " ctor " + scopeFile);
|
||||
|
@ -164,9 +164,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param m
|
||||
*/
|
||||
|
||||
private void processModule(EModule m, final ClassLoaderReference loader) {
|
||||
JavaScopeSwitch sw = new JavaScopeSwitch() {
|
||||
|
||||
|
@ -356,7 +354,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
* @return an EMF scope object
|
||||
*/
|
||||
private EJavaAnalysisScope readScope() {
|
||||
InputStream s = loader.getResourceAsStream(scopeFile);
|
||||
InputStream s = classloader.getResourceAsStream(scopeFile);
|
||||
if (s == null) {
|
||||
Assertions.UNREACHABLE("failed to open scope file: " + scopeFile);
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public class FILiveObjectAnalysis implements ILiveObjectAnalysis {
|
|||
}
|
||||
|
||||
public boolean mayBeLive(CGNode allocMethod, int allocPC, CGNode m, int instructionIndex) throws WalaException {
|
||||
NewSiteReference site = TrivialMethodEscape.findAlloc(callGraph, allocMethod, allocPC);
|
||||
NewSiteReference site = TrivialMethodEscape.findAlloc(allocMethod, allocPC);
|
||||
InstanceKey ik = heapGraph.getHeapModel().getInstanceKeyForAllocation(allocMethod, site);
|
||||
return mayBeLive(ik, m, instructionIndex);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ public class TrivialMethodEscape implements IMethodEscapeAnalysis, INodeEscapeAn
|
|||
// instances := set of instance key allocated at <allocMethod, allocPC>
|
||||
for (Iterator it = allocN.iterator(); it.hasNext();) {
|
||||
CGNode n = (CGNode) it.next();
|
||||
NewSiteReference site = findAlloc(cg, n, allocPC);
|
||||
NewSiteReference site = findAlloc(n, allocPC);
|
||||
InstanceKey ik = hg.getHeapModel().getInstanceKeyForAllocation(n, site);
|
||||
if (ik == null) {
|
||||
throw new WalaException("could not get instance key at site " + site + " in " + n);
|
||||
|
@ -138,7 +138,7 @@ public class TrivialMethodEscape implements IMethodEscapeAnalysis, INodeEscapeAn
|
|||
* @return the NewSiteReference for the allocation
|
||||
* @throws WalaException
|
||||
*/
|
||||
static NewSiteReference findAlloc(CallGraph cg, CGNode n, int allocPC) throws WalaException {
|
||||
static NewSiteReference findAlloc(CGNode n, int allocPC) throws WalaException {
|
||||
for (Iterator it = n.iterateNewSites(); it.hasNext();) {
|
||||
NewSiteReference site = (NewSiteReference) it.next();
|
||||
if (site.getProgramCounter() == allocPC) {
|
||||
|
|
|
@ -214,12 +214,6 @@ public class AnalysisScope {
|
|||
return loadersByName.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method classLoaderName2Ref.
|
||||
*
|
||||
* @param clName
|
||||
* @return ClassLoaderReference
|
||||
*/
|
||||
protected ClassLoaderReference classLoaderName2Ref(String clName) {
|
||||
return getLoader(Atom.findOrCreateUnicodeAtom(clName));
|
||||
}
|
||||
|
@ -235,16 +229,10 @@ public class AnalysisScope {
|
|||
loaderImplByRef.put(ref, implClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an Iterator <ClassLoaderReference>over the loaders.
|
||||
*/
|
||||
public Collection<ClassLoaderReference> getLoaders() {
|
||||
return Collections.unmodifiableCollection(loadersByName.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of loaders.
|
||||
*/
|
||||
public int getNumberOfLoaders() {
|
||||
return loadersByName.values().size();
|
||||
}
|
||||
|
|
|
@ -131,20 +131,20 @@ public abstract class Entrypoint implements BytecodeConstants {
|
|||
TypeAbstraction a;
|
||||
if (p[0].isPrimitiveType()) {
|
||||
a = PrimitiveType.getPrimitive(p[0]);
|
||||
for(i = 1; i < p.length; i++) {
|
||||
for (i = 1; i < p.length; i++) {
|
||||
a = a.meet(PrimitiveType.getPrimitive(p[i]));
|
||||
}
|
||||
} else {
|
||||
IClassHierarchy cha = m.getClassHierarchy();
|
||||
IClass p0 = cha.lookupClass(p[0]);
|
||||
a = new ConeType(p0);
|
||||
for(i = 1; i < p.length; i++) {
|
||||
for (i = 1; i < p.length; i++) {
|
||||
IClass pi = cha.lookupClass(p[i]);
|
||||
a = a.meet(new ConeType(pi));
|
||||
}
|
||||
}
|
||||
|
||||
return m.addPhi(a.getTypeReference(), values);
|
||||
return m.addPhi(values);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ public abstract class AbstractRootMethod extends SyntheticMethod {
|
|||
}
|
||||
}
|
||||
|
||||
public int addPhi(TypeReference type, int[] values) {
|
||||
public int addPhi(int[] values) {
|
||||
int result = nextLocal++;
|
||||
SSAPhiInstruction phi = new SSAPhiInstruction(result, values);
|
||||
statements.add(phi);
|
||||
|
|
|
@ -344,7 +344,11 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph<CGNode> imple
|
|||
return (result == null) ? empty : result;
|
||||
}
|
||||
|
||||
public SSAContextInterpreter getInterpreter(CGNode node) {
|
||||
/**
|
||||
* @param node a call graph node we want information about
|
||||
* @return an object that knows how to interpret information about the node
|
||||
*/
|
||||
protected SSAContextInterpreter getInterpreter(CGNode node) {
|
||||
return interpreter;
|
||||
}
|
||||
|
||||
|
|
|
@ -828,9 +828,9 @@ public class Util {
|
|||
|
||||
return new ZeroOneContainerCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()) {
|
||||
@Override
|
||||
protected ZeroXInstanceKeys makeInstanceKeys(IClassHierarchy cha, WarningSet warnings, AnalysisOptions options,
|
||||
protected ZeroXInstanceKeys makeInstanceKeys(IClassHierarchy c, WarningSet w, AnalysisOptions o,
|
||||
SSAContextInterpreter contextInterpreter) {
|
||||
ZeroXInstanceKeys zik = new ZeroXInstanceKeys(options, cha, contextInterpreter, warnings, ZeroXInstanceKeys.ALLOCATIONS);
|
||||
ZeroXInstanceKeys zik = new ZeroXInstanceKeys(o, c, contextInterpreter, w, ZeroXInstanceKeys.ALLOCATIONS);
|
||||
return zik;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,21 +13,13 @@ package com.ibm.wala.ipa.callgraph.propagation;
|
|||
import com.ibm.wala.fixedpoint.impl.AbstractOperator;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryStatement;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.fixpoint.IntSetVariable;
|
||||
import com.ibm.wala.util.debug.VerboseAction;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
import com.ibm.wala.util.intset.MutableSharedBitVectorIntSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* A apecialized equation class introduced for efficiency
|
||||
* A specialized equation class introduced for efficiency
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public final class AssignEquation extends UnaryStatement implements VerboseAction {
|
||||
|
||||
private final boolean DEBUG = false;
|
||||
public final class AssignEquation extends UnaryStatement {
|
||||
|
||||
AssignEquation(IVariable lhs, IVariable rhs) {
|
||||
super(lhs, rhs);
|
||||
|
@ -47,24 +39,4 @@ public final class AssignEquation extends UnaryStatement implements VerboseActio
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void performVerboseAction() {
|
||||
if (DEBUG) {
|
||||
IntSetVariable lhs = (IntSetVariable) getLHS();
|
||||
IntSetVariable rhs = (IntSetVariable) getRightHandSide();
|
||||
System.err.println("LHS " + ((lhs.getValue() == null) ? "null" : lhs.getValue().getClass().toString()));
|
||||
System.err.println("RHS " + ((rhs.getValue() == null) ? "null" : rhs.getValue().getClass().toString()));
|
||||
if (lhs.getValue() instanceof MutableSharedBitVectorIntSet) {
|
||||
if (rhs.getValue() instanceof MutableSharedBitVectorIntSet) {
|
||||
MutableSharedBitVectorIntSet a = (MutableSharedBitVectorIntSet) lhs.getValue();
|
||||
MutableSharedBitVectorIntSet b = (MutableSharedBitVectorIntSet) rhs.getValue();
|
||||
System.err.println("Shared? " + MutableSharedBitVectorIntSet.sameSharedPart(a, b));
|
||||
IntSet diff = IntSetUtil.diff(a,b);
|
||||
System.err.println("Diff a/b" + diff.size() + " " + diff);
|
||||
diff = IntSetUtil.diff(b,a);
|
||||
System.err.println("Diff b/a" + diff.size() + " " + diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -345,7 +345,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
OrdinalSet ep = getPointsToSet(e);
|
||||
for (Iterator it2 = ep.iterator(); it2.hasNext();) {
|
||||
InstanceKey ik = (InstanceKey) it2.next();
|
||||
if (SSAPropagationCallGraphBuilder.catches(caughtTypes, ik.getConcreteType(), getCallGraph().getClassHierarchy())) {
|
||||
if (PropagationCallGraphBuilder.catches(caughtTypes, ik.getConcreteType(), getCallGraph().getClassHierarchy())) {
|
||||
S.add(instanceKeys.getMappedIndex(ik));
|
||||
}
|
||||
}
|
||||
|
@ -362,7 +362,7 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
InstanceKey ik = SSAPropagationCallGraphBuilder.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory);
|
||||
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
||||
IClass klass = ck.getType();
|
||||
if (SSAPropagationCallGraphBuilder.catches(caughtTypes, klass, getCallGraph().getClassHierarchy())) {
|
||||
if (PropagationCallGraphBuilder.catches(caughtTypes, klass, getCallGraph().getClassHierarchy())) {
|
||||
S.add(instanceKeys.getMappedIndex(SSAPropagationCallGraphBuilder
|
||||
.getInstanceKeyForPEI(node, peiLoc, type, iKeyFactory)));
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
|||
Assertions._assert(!processedNodes.contains(node));
|
||||
}
|
||||
processedNodes.add(node);
|
||||
IR ir = getIR(cg, node);
|
||||
IR ir = getIR(node);
|
||||
if (ir != null) {
|
||||
visit(node, ir);
|
||||
} else {
|
||||
|
@ -217,7 +217,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
|||
}
|
||||
}
|
||||
|
||||
private static IR getIR(CallGraph cg, CGNode node) {
|
||||
private static IR getIR(CGNode node) {
|
||||
wipeCount++;
|
||||
if (wipeCount > WIPE_THRESHOLD) {
|
||||
wipeCount = 0;
|
||||
|
@ -465,7 +465,7 @@ public class PointerFlowGraph extends AbstractGraph<PointerKey> {
|
|||
CGNode target = (CGNode) it.next();
|
||||
|
||||
// some methods, like unmodelled natives, do not have IR.
|
||||
if (getIR(cg, target) == null)
|
||||
if (getIR(target) == null)
|
||||
continue;
|
||||
|
||||
// handle parameter passing
|
||||
|
|
|
@ -483,7 +483,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
for (int i = 1; i < dim; i++) {
|
||||
TypeReference jlo = makeArray(TypeReference.JavaLangObject, i);
|
||||
IClass jloClass = null;
|
||||
jloClass = aClass.getClassLoader().lookupClass(jlo.getName(), aClass.getClassHierarchy());
|
||||
jloClass = aClass.getClassLoader().lookupClass(jlo.getName());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(jloClass);
|
||||
set.add(index);
|
||||
}
|
||||
|
@ -502,7 +502,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
IClass I = (IClass) it.next();
|
||||
TypeReference iArrayRef = makeArray(I.getReference(), dim);
|
||||
IClass iArrayClass = null;
|
||||
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName(), I.getClassHierarchy());
|
||||
iArrayClass = I.getClassLoader().lookupClass(iArrayRef.getName());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(iArrayClass);
|
||||
set.add(index);
|
||||
if (DEBUG) {
|
||||
|
@ -527,7 +527,7 @@ public class PropagationSystem extends DefaultFixedPointSolver {
|
|||
while (T != null) {
|
||||
TypeReference tArrayRef = makeArray(T.getReference(), dim);
|
||||
IClass tArrayClass = null;
|
||||
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName(), T.getClassHierarchy());
|
||||
tArrayClass = T.getClassLoader().lookupClass(tArrayRef.getName());
|
||||
MutableIntSet set = findOrCreateSparseSetForClass(tArrayClass);
|
||||
set.add(index);
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -21,19 +21,24 @@ import com.ibm.wala.analysis.reflection.CloneInterpreter;
|
|||
import com.ibm.wala.analysis.reflection.Malleable;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.classLoader.*;
|
||||
import com.ibm.wala.classLoader.ArrayClass;
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.classLoader.NewSiteReference;
|
||||
import com.ibm.wala.classLoader.ProgramCounter;
|
||||
import com.ibm.wala.fixedpoint.impl.UnaryOperator;
|
||||
import com.ibm.wala.fixpoint.IVariable;
|
||||
import com.ibm.wala.fixpoint.IntSetVariable;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ExplicitCallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.FakeWorldClinitMethod;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.shrikeBT.ConditionalBranchInstruction;
|
||||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.shrikeBT.IInvokeInstruction;
|
||||
|
@ -449,7 +454,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
}
|
||||
ConcreteTypeKey ck = (ConcreteTypeKey) ik;
|
||||
IClass klass = ck.getType();
|
||||
if (SSAPropagationCallGraphBuilder.catches(catchClasses, klass, cha)) {
|
||||
if (PropagationCallGraphBuilder.catches(catchClasses, klass, cha)) {
|
||||
system.newConstraint(exceptionVar, getInstanceKeyForPEI(node, peiLoc, type, instanceKeyFactory));
|
||||
}
|
||||
}
|
||||
|
@ -477,14 +482,6 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true iff there's a unique catch block which catches all exceptions
|
||||
* thrown by a certain call site.
|
||||
*/
|
||||
static boolean hasUniqueCatchBlock(SSAAbstractInvokeInstruction call, CGNode node, CallGraph cg) {
|
||||
return hasUniqueCatchBlock(call, node.getIR(new WarningSet()));
|
||||
}
|
||||
|
||||
/**
|
||||
* precondition: hasUniqueCatchBlock(call,node,cg)
|
||||
*
|
||||
|
|
|
@ -62,11 +62,6 @@ public class DefaultSSAInterpreter extends DefaultRTAInterpreter implements SSAC
|
|||
return getCFAInterpreter(node).getNumberOfStatements(node, warnings);
|
||||
}
|
||||
|
||||
|
||||
public boolean understands(IMethod method, Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
|
||||
return getCFAInterpreter(node).iterateNewSites(node);
|
||||
|
|
|
@ -14,7 +14,6 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.cfg.CFGCache;
|
||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||
import com.ibm.wala.cfg.IBasicBlock;
|
||||
import com.ibm.wala.cfg.TwoExitCFG;
|
||||
|
@ -103,7 +102,7 @@ public class InterproceduralCFG implements NumberedGraph<BasicBlockInContext> {
|
|||
* @param warnings
|
||||
* an object to track analysis warnings
|
||||
*/
|
||||
public InterproceduralCFG(CallGraph CG, CFGCache cfgCache, WarningSet warnings) {
|
||||
public InterproceduralCFG(CallGraph CG, WarningSet warnings) {
|
||||
this(CG, IndiscriminateFilter.singleton(), false, warnings);
|
||||
}
|
||||
|
||||
|
|
|
@ -350,7 +350,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
throw new UnimplementedError("factory.getLoader failed " + e);
|
||||
}
|
||||
IClass declaredClass;
|
||||
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName(), this);
|
||||
declaredClass = loader.lookupClass(ref.getDeclaringClass().getName());
|
||||
if (declaredClass == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
@ -789,7 +789,7 @@ public class ClassHierarchy implements IClassHierarchy {
|
|||
ClassLoaderReference loaderRef = A.getClassLoader();
|
||||
for (int i = 0; i < loaders.length; i++) {
|
||||
if (loaders[i].getReference().equals(loaderRef)) {
|
||||
IClass klass = loaders[i].lookupClass(A.getName(), this);
|
||||
IClass klass = loaders[i].lookupClass(A.getName());
|
||||
if (klass != null) {
|
||||
if (DEBUG) {
|
||||
Trace.println("lookupClass: got " + klass);
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.ibm.wala.ipa.slicer.Statement.Kind;
|
|||
import com.ibm.wala.shrikeBT.IInstruction;
|
||||
import com.ibm.wala.ssa.DefUse;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
|
||||
import com.ibm.wala.ssa.SSAArrayReferenceInstruction;
|
||||
import com.ibm.wala.ssa.SSACheckCastInstruction;
|
||||
|
@ -41,7 +42,6 @@ import com.ibm.wala.ssa.SSAFieldAccessInstruction;
|
|||
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstanceofInstruction;
|
||||
import com.ibm.wala.ssa.SSAInstruction;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSANewInstruction;
|
||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||
import com.ibm.wala.ssa.SSAPiInstruction;
|
||||
|
@ -92,7 +92,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
|
||||
private final PointerAnalysis pa;
|
||||
|
||||
private final ExtendedHeapModel h;
|
||||
private final ExtendedHeapModel heapModel;
|
||||
|
||||
private final Map<CGNode, OrdinalSet<PointerKey>> mod;
|
||||
|
||||
|
@ -117,18 +117,18 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
throw new IllegalArgumentException("node is null");
|
||||
}
|
||||
this.node = node;
|
||||
this.h = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
this.heapModel = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel());
|
||||
this.pa = pa;
|
||||
this.dOptions = dOptions;
|
||||
this.mod = mod;
|
||||
this.exclusions = exclusions;
|
||||
instructionIndices = computeInstructionIndices(node.getIR(new WarningSet()));
|
||||
createNodes(mod, ref, dOptions, cOptions);
|
||||
createScalarEdges(dOptions, cOptions);
|
||||
createNodes(ref, cOptions);
|
||||
createScalarEdges(cOptions);
|
||||
}
|
||||
|
||||
private void createScalarEdges(DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
|
||||
createScalarDataDependenceEdges(dOptions);
|
||||
private void createScalarEdges(ControlDependenceOptions cOptions) {
|
||||
createScalarDataDependenceEdges();
|
||||
createControlDependenceEdges(cOptions);
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
* @param pa
|
||||
* @param mod
|
||||
*/
|
||||
private void createScalarDataDependenceEdges(DataDependenceOptions dOptions) {
|
||||
private void createScalarDataDependenceEdges() {
|
||||
if (dOptions.equals(DataDependenceOptions.NONE)) {
|
||||
return;
|
||||
}
|
||||
|
@ -450,12 +450,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
/**
|
||||
* Create heap data dependence edges in this PDG relevant to a particular
|
||||
* statement.
|
||||
*
|
||||
* @param pa
|
||||
* @param mod
|
||||
*/
|
||||
private void createHeapDataDependenceEdges(final PointerKey pk, PointerAnalysis pa, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||
DataDependenceOptions dOptions) {
|
||||
private void createHeapDataDependenceEdges(final PointerKey pk) {
|
||||
|
||||
if (locationsHandled.contains(pk)) {
|
||||
return;
|
||||
|
@ -480,7 +476,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
System.err.println("Location " + pk);
|
||||
}
|
||||
|
||||
// in reaching defs calcuation, exclude heap statements that are irrelevant.
|
||||
// in reaching defs calculation, exclude heap statements that are
|
||||
// irrelevant.
|
||||
Filter f = new Filter() {
|
||||
public boolean accepts(Object o) {
|
||||
if (o instanceof HeapStatement) {
|
||||
|
@ -677,17 +674,16 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
*
|
||||
* @param dOptions
|
||||
*/
|
||||
private void createNodes(Map<CGNode, OrdinalSet<PointerKey>> mod, Map<CGNode, OrdinalSet<PointerKey>> ref,
|
||||
DataDependenceOptions dOptions, ControlDependenceOptions cOptions) {
|
||||
private void createNodes(Map<CGNode, OrdinalSet<PointerKey>> ref, ControlDependenceOptions cOptions) {
|
||||
IR ir = node.getIR(new WarningSet());
|
||||
|
||||
if (ir != null) {
|
||||
Collection<SSAInstruction> visited = createNormalStatements(ir, mod, ref, dOptions);
|
||||
Collection<SSAInstruction> visited = createNormalStatements(ir, ref);
|
||||
createSpecialStatements(ir, visited);
|
||||
}
|
||||
|
||||
createCalleeParams(ref, dOptions);
|
||||
createReturnStatements(mod, dOptions);
|
||||
createCalleeParams(ref);
|
||||
createReturnStatements();
|
||||
|
||||
if (!cOptions.equals(ControlDependenceOptions.NONE)) {
|
||||
addNode(new MethodEntryStatement(node));
|
||||
|
@ -703,7 +699,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
* this node. These are logically parameters in the SDG.
|
||||
* @param dOptions
|
||||
*/
|
||||
private void createReturnStatements(Map<CGNode, OrdinalSet<PointerKey>> mod, DataDependenceOptions dOptions) {
|
||||
private void createReturnStatements() {
|
||||
ArrayList<Statement> list = new ArrayList<Statement>();
|
||||
if (!node.getMethod().getReturnType().equals(TypeReference.Void)) {
|
||||
ParamStatement.NormalReturnCallee n = new ParamStatement.NormalReturnCallee(node);
|
||||
|
@ -732,9 +728,8 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
* @param ref
|
||||
* the set of heap locations which may be read (transitively) by
|
||||
* this node. These are logically parameters in the SDG.
|
||||
* @param dOptions
|
||||
*/
|
||||
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
||||
private void createCalleeParams(Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||
|
||||
ArrayList<Statement> list = new ArrayList<Statement>();
|
||||
for (int i = 1; i <= node.getMethod().getNumberOfParameters(); i++) {
|
||||
|
@ -785,8 +780,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
* @param options
|
||||
*
|
||||
*/
|
||||
private Collection<SSAInstruction> createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
||||
private Collection<SSAInstruction> createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||
Collection<SSAInstruction> visited = HashSetFactory.make();
|
||||
// create a node for every normal instruction in the IR
|
||||
SSAInstruction[] instructions = ir.getInstructions();
|
||||
|
@ -802,7 +796,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
visited.add(s);
|
||||
}
|
||||
if (s instanceof SSAAbstractInvokeInstruction) {
|
||||
addParamPassingStatements((SSAAbstractInvokeInstruction) s, mod, ref, dOptions);
|
||||
addParamPassingStatements((SSAAbstractInvokeInstruction) s, ref);
|
||||
}
|
||||
}
|
||||
return visited;
|
||||
|
@ -814,8 +808,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
*
|
||||
* @param dOptions
|
||||
*/
|
||||
private void addParamPassingStatements(SSAAbstractInvokeInstruction call, Map<CGNode, OrdinalSet<PointerKey>> mod,
|
||||
Map<CGNode, OrdinalSet<PointerKey>> ref, DataDependenceOptions dOptions) {
|
||||
private void addParamPassingStatements(SSAAbstractInvokeInstruction call, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||
|
||||
Collection<Statement> params = MapUtil.findOrCreateSet(callerParamStatements, call.getCallSite());
|
||||
Collection<Statement> rets = MapUtil.findOrCreateSet(callerReturnStatements, call.getCallSite());
|
||||
|
@ -920,9 +913,9 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
case NORMAL:
|
||||
NormalStatement st = (NormalStatement) N;
|
||||
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
||||
Collection<PointerKey> ref = ModRef.getRef(node, h, pa, st.getInstruction(), exclusions);
|
||||
Collection<PointerKey> ref = ModRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions);
|
||||
for (PointerKey pk : ref) {
|
||||
createHeapDataDependenceEdges(pk, pa, mod, dOptions);
|
||||
createHeapDataDependenceEdges(pk);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -931,7 +924,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
case HEAP_RET_CALLEE:
|
||||
case HEAP_RET_CALLER:
|
||||
HeapStatement h = (HeapStatement) N;
|
||||
createHeapDataDependenceEdges(h.getLocation(), pa, mod, dOptions);
|
||||
createHeapDataDependenceEdges(h.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,9 +933,9 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
case NORMAL:
|
||||
NormalStatement st = (NormalStatement) N;
|
||||
if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) {
|
||||
Collection<PointerKey> ref = ModRef.getMod(node, h, pa, st.getInstruction(), exclusions);
|
||||
Collection<PointerKey> ref = ModRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions);
|
||||
for (PointerKey pk : ref) {
|
||||
createHeapDataDependenceEdges(pk, pa, mod, dOptions);
|
||||
createHeapDataDependenceEdges(pk);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -951,7 +944,7 @@ public class PDG extends SlowSparseNumberedGraph<Statement> {
|
|||
case HEAP_RET_CALLEE:
|
||||
case HEAP_RET_CALLER:
|
||||
HeapStatement h = (HeapStatement) N;
|
||||
createHeapDataDependenceEdges(h.getLocation(), pa, mod, dOptions);
|
||||
createHeapDataDependenceEdges(h.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import com.ibm.wala.util.intset.SparseIntSet;
|
|||
* A wrapper around an SDG to make it look like a supergraph for tabulation.
|
||||
*
|
||||
* @author sjfink
|
||||
*
|
||||
*/
|
||||
class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
||||
|
||||
|
@ -39,7 +38,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
/**
|
||||
* We are interested in flow to or from the following statement.
|
||||
*/
|
||||
private final Statement src;
|
||||
private final Statement srcStatement;
|
||||
|
||||
/**
|
||||
* Do a backward slice?
|
||||
|
@ -48,7 +47,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
|
||||
public SDGSupergraph(ISDG sdg, Statement src, boolean backward) {
|
||||
this.sdg = sdg;
|
||||
this.src = src;
|
||||
this.srcStatement = src;
|
||||
this.backward = backward;
|
||||
}
|
||||
|
||||
|
@ -57,6 +56,9 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.dataflow.IFDS.ISupergraph#classifyEdge(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public byte classifyEdge(Statement src, Statement dest) {
|
||||
Assertions.UNREACHABLE();
|
||||
return 0;
|
||||
|
@ -162,7 +164,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
* @see com.ibm.wala.dataflow.IFDS.ISupergraph#getMain()
|
||||
*/
|
||||
public PDG getMain() {
|
||||
return getProcOf(src);
|
||||
return getProcOf(srcStatement);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -170,7 +172,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
*/
|
||||
public Statement getMainEntry() {
|
||||
Assertions.productionAssertion(!backward, "todo: support backward");
|
||||
return src;
|
||||
return srcStatement;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -180,7 +182,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
// We pretend that sink is the "main exit" .. we don't care about
|
||||
// flow past the sink.
|
||||
Assertions.productionAssertion(backward, "todo: support forward");
|
||||
return src;
|
||||
return srcStatement;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -397,7 +399,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
|
||||
public Iterator<? extends Statement> getSuccNodes(Statement N) {
|
||||
if (backward) {
|
||||
if (N.equals(src)) {
|
||||
if (N.equals(srcStatement)) {
|
||||
return EmptyIterator.instance();
|
||||
} else {
|
||||
return sdg.getSuccNodes(N);
|
||||
|
@ -409,13 +411,13 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
|
||||
public boolean hasEdge(Statement src, Statement dst) {
|
||||
if (backward) {
|
||||
if (src.equals(this.src)) {
|
||||
if (src.equals(this.srcStatement)) {
|
||||
return IteratorUtil.contains(getSuccNodes(src), dst);
|
||||
} else {
|
||||
return sdg.hasEdge(src, dst);
|
||||
}
|
||||
} else {
|
||||
if (dst.equals(this.src)) {
|
||||
if (dst.equals(this.srcStatement)) {
|
||||
return IteratorUtil.contains(getPredNodes(dst), src);
|
||||
} else {
|
||||
return sdg.hasEdge(src, dst);
|
||||
|
@ -469,7 +471,7 @@ class SDGSupergraph implements ISupergraph<Statement, PDG> {
|
|||
*/
|
||||
public IntSet getSuccNodeNumbers(Statement node) {
|
||||
if (backward) {
|
||||
if (node.equals(src)) {
|
||||
if (node.equals(srcStatement)) {
|
||||
return new SparseIntSet();
|
||||
} else {
|
||||
return sdg.getSuccNodeNumbers(node);
|
||||
|
|
|
@ -224,7 +224,7 @@ public class Slicer {
|
|||
if (VERBOSE) {
|
||||
System.err.println("Tabulated.");
|
||||
}
|
||||
Collection<Statement> slice = result2Slice(sdg, tr);
|
||||
Collection<Statement> slice = result2Slice(tr);
|
||||
result.addAll(slice);
|
||||
|
||||
if (VERBOSE) {
|
||||
|
@ -351,10 +351,10 @@ public class Slicer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Convert the resuls of the tabulation to a slice, represented as a
|
||||
* Convert the results of the tabulation to a slice, represented as a
|
||||
* Collection<Statement>
|
||||
*/
|
||||
private static Collection<Statement> result2Slice(ISDG sdg, final TabulationResult<Statement> result) {
|
||||
private static Collection<Statement> result2Slice(final TabulationResult<Statement> result) {
|
||||
return result.getSupergraphNodesReached();
|
||||
// final Collection<Statement> nodes = new
|
||||
// Iterator2Collection<Statement>(sdg.iterateLazyNodes());
|
||||
|
|
|
@ -100,7 +100,7 @@ public class BypassClassTargetSelector implements ClassTargetSelector {
|
|||
}
|
||||
if (realType.isAbstract() || realType.isInterface()) {
|
||||
TypeName syntheticName = BypassSyntheticClass.getName(realRef);
|
||||
IClass result = bypassLoader.lookupClass(syntheticName, realType.getClassHierarchy());
|
||||
IClass result = bypassLoader.lookupClass(syntheticName);
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class BypassSyntheticClass extends SyntheticClass {
|
|||
*/
|
||||
public IClass getSuperclass() throws ClassHierarchyException {
|
||||
if (realType.isInterface()) {
|
||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName(), getClassHierarchy());
|
||||
IClass result = loader.lookupClass(TypeReference.JavaLangObject.getName());
|
||||
if (result != null) {
|
||||
return result;
|
||||
} else {
|
||||
|
|
|
@ -62,11 +62,17 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
|||
|
||||
private final IClassHierarchy cha;
|
||||
|
||||
/**
|
||||
* A mapping from TypeName -> IClass
|
||||
*/
|
||||
private final HashMap<TypeName, IClass> syntheticClasses = HashMapFactory.make();
|
||||
|
||||
/**
|
||||
* Don't change my signature! ClassLoaderFactoryImpl calls me by reflection! yuck.
|
||||
*
|
||||
* @param me the name of this class loader
|
||||
* @param parent its parent
|
||||
* @param exclusions classes to ignore
|
||||
* @param cha governing class hierarchy
|
||||
* @param warnings object to record analysis warnings
|
||||
*/
|
||||
public BypassSyntheticClassLoader(ClassLoaderReference me, IClassLoader parent, SetOfClasses exclusions, IClassHierarchy cha,
|
||||
WarningSet warnings) {
|
||||
this.me = me;
|
||||
|
@ -74,8 +80,8 @@ public class BypassSyntheticClassLoader implements IClassLoader {
|
|||
this.parent = parent;
|
||||
}
|
||||
|
||||
public IClass lookupClass(TypeName className, IClassHierarchy cha) {
|
||||
IClass pc = parent.lookupClass(className, cha);
|
||||
public IClass lookupClass(TypeName className) {
|
||||
IClass pc = parent.lookupClass(className);
|
||||
if (pc == null) {
|
||||
IClass c = syntheticClasses.get(className);
|
||||
return c;
|
||||
|
|
|
@ -49,7 +49,6 @@ import com.ibm.wala.types.TypeReference;
|
|||
import com.ibm.wala.util.ShrikeUtil;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.intset.IntPair;
|
||||
import com.ibm.wala.util.warnings.WarningSet;
|
||||
|
||||
/**
|
||||
* This class constructs an SSA IR from a backing ShrikeBT instruction stream.
|
||||
|
@ -75,7 +74,7 @@ public class SSABuilder extends AbstractIntStackMachine {
|
|||
private final SSA2LocalMap localMap;
|
||||
|
||||
public SSABuilder(ShrikeCTMethod method, SSACFG cfg, ShrikeCFG scfg, SSAInstruction[] instructions,
|
||||
SymbolTable symbolTable, boolean buildLocalMap, boolean addPiNodes, WarningSet warnings) {
|
||||
SymbolTable symbolTable, boolean buildLocalMap, boolean addPiNodes) {
|
||||
super(scfg);
|
||||
localMap = buildLocalMap ? new SSA2LocalMap(scfg, instructions.length, cfg.getNumberOfNodes(), maxLocals) : null;
|
||||
init(new SymbolTableMeeter(symbolTable, cfg, instructions, scfg), new SymbolicPropagator(scfg, instructions, symbolTable,
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SSACFG implements ControlFlowGraph{
|
|||
} else {
|
||||
TypeReference exceptionType = ShrikeUtil.makeTypeReference(loader.getReference(), handler.getCatchClass());
|
||||
IClass klass = null;
|
||||
klass = loader.lookupClass(exceptionType.getName(), method.getClassHierarchy());
|
||||
klass = loader.lookupClass(exceptionType.getName());
|
||||
if (klass == null) {
|
||||
warnings.add(ExceptionLoadFailure.create(exceptionType, method));
|
||||
t = exceptionType;
|
||||
|
|
|
@ -197,6 +197,10 @@ public abstract class SSAInstruction implements IInstruction {
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ith def
|
||||
* @param i number of the def, starting at 0.
|
||||
*/
|
||||
public int getDef(int i) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -387,14 +387,14 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
|||
if (!instbb.isPiBlock()) {
|
||||
for (Iterator sit = cfg.getSuccNodes(bb); sit.hasNext();) {
|
||||
BasicBlock succNode = (BasicBlock) sit.next();
|
||||
boolean fallThrough = isFallThroughEdge(cfg, bb, succNode);
|
||||
boolean fallThrough = isFallThroughEdge(bb, succNode);
|
||||
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
||||
}
|
||||
} else {
|
||||
SSAPiInstruction pi = (SSAPiInstruction) instbb.getInstruction();
|
||||
int succNum = pi.getSuccessor();
|
||||
BasicBlock succNode = (BasicBlock) cfg.getNode(succNum);
|
||||
boolean fallThrough = isFallThroughEdge(cfg, bb, succNode);
|
||||
boolean fallThrough = isFallThroughEdge(bb, succNode);
|
||||
edgeWorkSet.add(new BBEdge(bb, succNode, fallThrough));
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
|||
Iterator workIt = edgeWorkSet.iterator();
|
||||
BBEdge edge = (BBEdge) workIt.next();
|
||||
boolean fallThru = false;
|
||||
if (isFallThroughEdge(cfg, edge.src, edge.dest)) {
|
||||
if (isFallThroughEdge(edge.src, edge.dest)) {
|
||||
fallThru = true;
|
||||
}
|
||||
workIt.remove();
|
||||
|
@ -963,15 +963,12 @@ public class ExpandedControlFlowGraph implements ControlFlowGraph {
|
|||
/**
|
||||
* is the given edge a fall-through edge?
|
||||
*
|
||||
* @param cfg
|
||||
* @param src
|
||||
* @param dest
|
||||
* @return note: this is based on a DOMO-invariant that guarantees the blocks
|
||||
* are numbered in a certain way. This is the "DOMO-way" of
|
||||
* @return note: this is based on a WALA-invariant that guarantees the blocks
|
||||
* are numbered in a certain way. This is the "WALA-way" of
|
||||
* identifying fall-through edges, and is mainly done due for
|
||||
* efficiency reasons (as many other software crimes).
|
||||
*/
|
||||
private boolean isFallThroughEdge(SSACFG cfg, IBasicBlock src, IBasicBlock dest) {
|
||||
private boolean isFallThroughEdge(IBasicBlock src, IBasicBlock dest) {
|
||||
if (cfg.getSuccNodeCount(src) == 2) {
|
||||
return ((src.getNumber() + 1) == dest.getNumber());
|
||||
} else {
|
||||
|
|
|
@ -173,18 +173,18 @@ public class BytecodeStream implements BytecodeConstants {
|
|||
/**
|
||||
* Skips the current instruction (without using the opcode field)
|
||||
* A slightly optimized version of skipInstruction()
|
||||
* @param opcode current opcode
|
||||
* @param wide whether current instruction follows wide
|
||||
* @param opc current opcode
|
||||
* @param w whether current instruction follows wide
|
||||
* @see #skipInstruction()
|
||||
*/
|
||||
public final void skipInstruction(int opcode, boolean wide) {
|
||||
int len = JBC_length[opcode] - 1;
|
||||
if (wide)
|
||||
public final void skipInstruction(int opc, boolean w) {
|
||||
int len = JBC_length[opc] - 1;
|
||||
if (w)
|
||||
len += len;
|
||||
if (len >= 0)
|
||||
bcIndex += len;
|
||||
else
|
||||
skipSpecialInstruction(opcode);
|
||||
skipSpecialInstruction(opc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -535,8 +535,6 @@ public class BytecodeStream implements BytecodeConstants {
|
|||
* Used for ldc
|
||||
* @return constant index
|
||||
* @see #getWideConstantIndex()
|
||||
* @see #getConstantType(int)
|
||||
* @see #getIntConstant(int)
|
||||
*/
|
||||
public final int getConstantIndex() {
|
||||
return readUnsignedByte();
|
||||
|
@ -547,43 +545,41 @@ public class BytecodeStream implements BytecodeConstants {
|
|||
* Used for ldc_w, ldc2_w
|
||||
* @return wide constant index
|
||||
* @see #getConstantIndex()
|
||||
* @see #getConstantType(int)
|
||||
* @see #getIntConstant(int)
|
||||
*/
|
||||
public final int getWideConstantIndex() {
|
||||
return readUnsignedShort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of a constant at a given constant pool index (as a byte)
|
||||
* Used for ldc, ldc_w, ldc2_w
|
||||
* @return constant type
|
||||
* @see #getConstantIndex()
|
||||
* @see #getWideConstantIndex()
|
||||
* @see #getIntConstant(int)
|
||||
* @throws UnimplementedError unconditionally
|
||||
*/
|
||||
public final byte getConstantType(int index) throws UnimplementedError {
|
||||
throw new UnimplementedError();
|
||||
// byte desc = declaringClass.getLiteralDescription(index);
|
||||
// return desc;
|
||||
}
|
||||
// /**
|
||||
// * Returns the type of a constant at a given constant pool index (as a byte)
|
||||
// * Used for ldc, ldc_w, ldc2_w
|
||||
// * @return constant type
|
||||
// * @see #getConstantIndex()
|
||||
// * @see #getWideConstantIndex()
|
||||
// * @see #getIntConstant(int)
|
||||
// * @throws UnimplementedError unconditionally
|
||||
// */
|
||||
// public final byte getConstantType(int index) throws UnimplementedError {
|
||||
// throw new UnimplementedError();
|
||||
// // byte desc = declaringClass.getLiteralDescription(index);
|
||||
// // return desc;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns the constant at a given constant pool index (as an int)
|
||||
* Used for ldc, ldc_w
|
||||
* @return int constant
|
||||
* @see #getConstantIndex()
|
||||
* @see #getWideConstantIndex()
|
||||
* @see #getConstantType(int)
|
||||
* @throws UnimplementedError unconditionally
|
||||
*/
|
||||
public final int getIntConstant(int index) throws UnimplementedError {
|
||||
throw new UnimplementedError();
|
||||
// int offset = declaringClass.getLiteralOffset(index) >> 2;
|
||||
// int val = Statics.getSlotContentsAsInt(offset);
|
||||
// return val;
|
||||
}
|
||||
// /**
|
||||
// * Returns the constant at a given constant pool index (as an int)
|
||||
// * Used for ldc, ldc_w
|
||||
// * @return int constant
|
||||
// * @see #getConstantIndex()
|
||||
// * @see #getWideConstantIndex()
|
||||
// * @see #getConstantType(int)
|
||||
// * @throws UnimplementedError unconditionally
|
||||
// */
|
||||
// public final int getIntConstant(int index) throws UnimplementedError {
|
||||
// throw new UnimplementedError();
|
||||
// // int offset = declaringClass.getLiteralOffset(index) >> 2;
|
||||
// // int val = Statics.getSlotContentsAsInt(offset);
|
||||
// // return val;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns the constant at a given constant pool index (as a long)
|
||||
|
|
|
@ -150,7 +150,11 @@ public abstract class DFSDiscoverTimeIterator<T> extends Stack<T> implements Ite
|
|||
throw new UnimplementedError();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param from source of the edge to visit
|
||||
* @param to target of the edge to visit
|
||||
*/
|
||||
protected void visitEdge(T from, T to) {
|
||||
|
||||
// do nothing. subclasses will override.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,265 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 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.util.graph.traverse;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.graph.Graph;
|
||||
import com.ibm.wala.util.graph.INodeWithNumber;
|
||||
import com.ibm.wala.util.graph.NumberedGraph;
|
||||
|
||||
/**
|
||||
* Depth first search of a graph using a stack instead of recursive method
|
||||
* calls. It allows each vertice of the graph to be visited when its is first
|
||||
* discovered and when it is "finished" (i.e. completely processed).
|
||||
*
|
||||
* @author <a href="mailto:achille@us.ibm.com">Achille Fokoue </a>
|
||||
* @version
|
||||
*/
|
||||
public class DFSVisit {
|
||||
|
||||
/**
|
||||
* the empty iterator constant
|
||||
*/
|
||||
public final static Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
|
||||
|
||||
/**
|
||||
* A simple map interface. It is used during DFS to associate a node in a
|
||||
* graph to its its traversal state.
|
||||
*/
|
||||
public interface SimpleMap<K,V> {
|
||||
/**
|
||||
* returns the state associated with a given node
|
||||
*
|
||||
* @param node
|
||||
*/
|
||||
public V get(Object node);
|
||||
|
||||
/**
|
||||
* sets the state associated with a given node, and returns the previous
|
||||
* associated states
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
public V put(K key, V value);
|
||||
|
||||
/**
|
||||
* clear this {@link SimpleMap}
|
||||
*
|
||||
*/
|
||||
public void clear();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link SimpleMap}that maps
|
||||
* {@link com.ibm.wala.util.graph.INodeWithNumber}to their traversal state.
|
||||
* <p>
|
||||
* NOTE: the capacity of this map does not grow!
|
||||
*
|
||||
* @version
|
||||
*/
|
||||
public static class NumberedSimpleMap<K,V> implements SimpleMap<K,V> {
|
||||
final Object[] table;
|
||||
|
||||
public NumberedSimpleMap(int capacity) {
|
||||
table = new Object[capacity];
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public V get(Object n) {
|
||||
int id = ((INodeWithNumber) n).getGraphNodeId();
|
||||
V ret = (V) table[id];
|
||||
return ret;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public V put(K key, V value) {
|
||||
int id = ((INodeWithNumber) key).getGraphNodeId();
|
||||
V prev = (V) table[id];
|
||||
table[id] = value;
|
||||
return prev;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
Arrays.fill(table, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Default implementation of {@link SimpleMap}based on a {@link HashMap}
|
||||
*
|
||||
* @version
|
||||
*/
|
||||
public static class DefaultSimpleMap<K,V> extends HashMap<K,V> implements SimpleMap<K,V> {
|
||||
|
||||
private static final long serialVersionUID = 8314610925208365087L;
|
||||
|
||||
/**
|
||||
* Constructs an empty DefaultSimpleMap with the specified initial capacity.
|
||||
*/
|
||||
public DefaultSimpleMap(int initialCapacity) {
|
||||
super(initialCapacity);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public DefaultSimpleMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an empty DefaultSimpleMap with the specified initial capacity
|
||||
* and load factor.
|
||||
*/
|
||||
public DefaultSimpleMap(int initialCapacity, float loadFactor) {
|
||||
super(initialCapacity, loadFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor that visits Nodes in the DFS2 of a graph
|
||||
*
|
||||
* @author <a href="mailto:achille@us.ibm.com">Achille Fokoue </a>
|
||||
* @version
|
||||
*/
|
||||
public static abstract class Visitor {
|
||||
public abstract void visit(Object node, Object parent);
|
||||
|
||||
public abstract void leave(Object node);
|
||||
|
||||
public void visitEdge(Object source, Object target) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Depth first search of a node of graph using a stack instead of recursive
|
||||
* method calls. This is necessary in order to avoid
|
||||
* java.lang.StackOverflowError for big graphs.
|
||||
*/
|
||||
private static <T >void DFS(Graph<T> g, T node, SimpleMap<T, Iterator<? extends T>> states, Visitor visitor) {
|
||||
int leave = 0;
|
||||
int found = 0;
|
||||
Stack<T> pending = new Stack<T>();
|
||||
found++;
|
||||
visitor.visit(node, null);
|
||||
states.put(node, getConnectedTo(g, node));
|
||||
pending.push(node);
|
||||
cont: while (!pending.isEmpty()) {
|
||||
T current = pending.peek();
|
||||
Iterator<? extends T> currentChildren = states.get(current);
|
||||
for (Iterator<? extends T> e = currentChildren; e.hasNext();) {
|
||||
T currentChild = e.next();
|
||||
// visit edge
|
||||
visitor.visitEdge(current, currentChild);
|
||||
Iterator currentGrandChildren = states.get(currentChild);
|
||||
if (currentGrandChildren == null) {
|
||||
// new child discovered
|
||||
found++;
|
||||
visitor.visit(currentChild, current);
|
||||
states.put(currentChild, getConnectedTo(g, currentChild));
|
||||
pending.push(currentChild);
|
||||
// recursion continue
|
||||
continue cont;
|
||||
}
|
||||
}
|
||||
// all children of current have been processed
|
||||
// current is finished
|
||||
Object ret = pending.pop();
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(ret == current);
|
||||
}
|
||||
leave++;
|
||||
visitor.leave(current);
|
||||
// allow the garbage collector to do its job
|
||||
Iterator<? extends T> empty = EmptyIterator.instance();
|
||||
states.put(current, empty);
|
||||
|
||||
}
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(found == leave, found + " nodes discovered, but " + leave + " finished!");
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T> Iterator<? extends T> getConnectedTo(Graph<T> g, T node) {
|
||||
return g.getSuccNodes(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Depth first search of a graph using a stack instead of recursive method
|
||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
||||
* big graphs
|
||||
*
|
||||
* @param g
|
||||
* the graph to traverse
|
||||
* @param nodes
|
||||
* an iterator over the nodes where the traversal should start
|
||||
* @param visitor
|
||||
* the visitor to notify when nodes are discovered and finished
|
||||
* @param states
|
||||
* the map to use to store and retrieve the state of nodes
|
||||
*/
|
||||
public static <T> void DFS(Graph<T> g, Iterator<? extends T> nodes, Visitor visitor, SimpleMap<T,Iterator<? extends T>> states) {
|
||||
for (Iterator<? extends T> it = nodes; it.hasNext();) {
|
||||
T node = it.next();
|
||||
if (node != null && states.get(node) == null) {
|
||||
DFS(g, node, states, visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Depth first search of a graph using a stack instead of recursive method
|
||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
||||
* big graphs
|
||||
*
|
||||
* @param g
|
||||
* the graph to traverse
|
||||
* @param nodes
|
||||
* an iterator over the nodes where the traversal should start
|
||||
* @param visitor
|
||||
* the visitor to notify when nodes are discovered and finished
|
||||
*/
|
||||
public static <T> void DFS(Graph<T> g, Iterator<? extends T> nodes, Visitor visitor) {
|
||||
if (g instanceof NumberedGraph) {
|
||||
DFS(g, nodes, visitor, new NumberedSimpleMap<T, Iterator<? extends T>>(g.getNumberOfNodes()));
|
||||
} else {
|
||||
DFS(g, nodes, visitor, new DefaultSimpleMap<T,Iterator<? extends T>>());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Depth first search of a graph using a stack instead of recursive method
|
||||
* calls. This is necessary in order to avoid java.lang.StackOverflowError for
|
||||
* big graphs
|
||||
*
|
||||
* @param g
|
||||
* the graph to traverse
|
||||
* @param visitor
|
||||
* the visitor to notify when nodes are discovered and finished
|
||||
* @throws IllegalArgumentException if g is null
|
||||
*/
|
||||
public static <T> void DFS(Graph<T> g, Visitor visitor) {
|
||||
if (g == null) {
|
||||
throw new IllegalArgumentException("g is null");
|
||||
}
|
||||
DFS(g, g.iterator(), visitor);
|
||||
}
|
||||
|
||||
}
|
|
@ -107,9 +107,7 @@ public class BimodalMutableIntSet implements MutableIntSet {
|
|||
// don't bother
|
||||
return;
|
||||
}
|
||||
int bvSize = BitVector.subscript(impl.max()) + 1;
|
||||
// Trace.println("S B " + sparseSize + " " + bvSize + " " + impl.max() + " "
|
||||
// + impl);
|
||||
int bvSize = BitVectorBase.subscript(impl.max()) + 1;
|
||||
if (sparseSize > bvSize) {
|
||||
if (!(impl instanceof BitVectorIntSet)) {
|
||||
impl = new BitVectorIntSet(impl);
|
||||
|
|
|
@ -356,10 +356,4 @@ public final class MutableSparseLongSet extends SparseLongSet implements Mutable
|
|||
size = ci;
|
||||
return (al != size);
|
||||
}
|
||||
|
||||
|
||||
public void removeAll(MutableSparseLongSet set) throws UnimplementedError {
|
||||
Assertions.UNREACHABLE("implement me");
|
||||
}
|
||||
|
||||
}
|
|
@ -48,9 +48,9 @@ import com.ibm.wala.util.warnings.WalaException;
|
|||
* Given an Eclipse plugin, this class detects all the other plugins that should
|
||||
* be part of the analysis scope when analyzing the given plugin.
|
||||
*
|
||||
* This is buggy in that it ignores the Import-Package declarations in the manifest.
|
||||
* This is a problem. Probably the way to go is to recode this whole thing using
|
||||
* a headless Eclipse instance, and rely on Eclipse APIs to resolve
|
||||
* This is buggy in that it ignores the Import-Package declarations in the
|
||||
* manifest. This is a problem. Probably the way to go is to recode this whole
|
||||
* thing using a headless Eclipse instance, and rely on Eclipse APIs to resolve
|
||||
* dependencies the right way.
|
||||
*
|
||||
* @author Marco Pistoia
|
||||
|
@ -95,7 +95,6 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
*/
|
||||
private final String pluginsDirName;
|
||||
|
||||
|
||||
/**
|
||||
* @param pluginName
|
||||
* name of the plugin to be analyzed
|
||||
|
@ -265,9 +264,11 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
* @return a File representing the directory or JAR file containing the
|
||||
* plugin. This method returns <code>null</code> if no directory or
|
||||
* JAR file was found for this plugin.
|
||||
* @throws IllegalArgumentException if pluginDirectory is null
|
||||
* @throws IllegalArgumentException
|
||||
* if pluginDirectory is null
|
||||
*/
|
||||
public static File findPluginDirOrJAR(String libName, String pluginsDirName, File pluginDirectory) throws IllegalArgumentException {
|
||||
public static File findPluginDirOrJAR(String libName, String pluginsDirName, File pluginDirectory)
|
||||
throws IllegalArgumentException {
|
||||
if (pluginDirectory == null) {
|
||||
throw new IllegalArgumentException("pluginDirectory is null");
|
||||
}
|
||||
|
@ -348,7 +349,8 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
* in its MANIFEST.MF file.
|
||||
*
|
||||
* @param manifestFileName
|
||||
* a String representing the fully qualified name of a manifest file.
|
||||
* a String representing the fully qualified name of a manifest
|
||||
* file.
|
||||
* @return a TreeSet of Strings each of which represents the fully qualified
|
||||
* name of a required plugin's directory. The returned TreeSet is
|
||||
* <code>null</code> if it was not possible to have access to the
|
||||
|
@ -373,7 +375,7 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
String requiredBundleName = (requiredArray[i].trim()).split(";")[0];
|
||||
if ((version > 3 || version == 3 && subversion >= 2) && Character.isDigit(requiredBundleName.charAt(0)))
|
||||
continue;
|
||||
File requiredBundle = findPluginDirOrJAR(requiredBundleName, pluginDirsName,pluginDirectory);
|
||||
File requiredBundle = findPluginDirOrJAR(requiredBundleName, pluginDirsName, pluginDirectory);
|
||||
if (requiredBundle == null) {
|
||||
System.err.println("EclipseAnalysisScopeBuilder: " + requiredBundleName + " was not found.");
|
||||
continue;
|
||||
|
@ -442,7 +444,7 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
Iterator pluginIdsIter = pluginIds.iterator();
|
||||
while (pluginIdsIter.hasNext()) {
|
||||
String fragmentHost = (String) pluginIdsIter.next();
|
||||
result.addAll(getContributingFragment(fragmentHost, manifestName, pluginsDirName, pluginDirectory));
|
||||
result.addAll(getContributingFragment(fragmentHost, manifestName, pluginDirectory));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -459,7 +461,8 @@ public class EclipseAnalysisScope extends AnalysisScope {
|
|||
* The name of the current manifest file being scanned.
|
||||
*
|
||||
*/
|
||||
private Collection<JarFile> getContributingFragment(String fragmentHost, String manifestFileName, String pluginsDirName, File pluginDirectory) {
|
||||
private Collection<JarFile> getContributingFragment(String fragmentHost, String manifestFileName,
|
||||
File pluginDirectory) {
|
||||
Collection<JarFile> result = HashSetFactory.make();
|
||||
InputStream is = getInputStream(manifestFileName);
|
||||
if (is == null) {
|
||||
|
|
|
@ -230,6 +230,10 @@ public class DotUtil {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n node to decorate
|
||||
* @param d decorating master
|
||||
*/
|
||||
private static String decorateNode(Object n, NodeDecorator d) throws WalaException {
|
||||
StringBuffer result = new StringBuffer();
|
||||
|
||||
|
|
|
@ -39,28 +39,22 @@ public class GhostviewUtil {
|
|||
/**
|
||||
* spawn a process to ghostview a WALA IR
|
||||
*
|
||||
* @param cha
|
||||
* @param ir
|
||||
* @return a handle to the ghostview process
|
||||
* @throws WalaException
|
||||
*/
|
||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, boolean sanitize, String psFile, String dotFile, String dotExe,
|
||||
String gvExe) throws WalaException {
|
||||
return ghostviewIR(cha, ir, sanitize, psFile, dotFile, dotExe, gvExe, null);
|
||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, String psFile, String dotFile, String dotExe, String gvExe)
|
||||
throws WalaException {
|
||||
return ghostviewIR(cha, ir, psFile, dotFile, dotExe, gvExe, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* spawn a process to ghostview a WALA IR
|
||||
*
|
||||
* @param cha
|
||||
* @param ir
|
||||
* @return a handle to the ghostview process
|
||||
* @throws WalaException
|
||||
* @throws IllegalArgumentException
|
||||
* if ir is null
|
||||
*/
|
||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, boolean sanitize, String psFile, String dotFile, String dotExe,
|
||||
String gvExe, NodeDecorator annotations) throws WalaException {
|
||||
public static Process ghostviewIR(IClassHierarchy cha, IR ir, String psFile, String dotFile, String dotExe, String gvExe,
|
||||
NodeDecorator annotations) throws WalaException {
|
||||
|
||||
if (ir == null) {
|
||||
throw new IllegalArgumentException("ir is null");
|
||||
|
|
|
@ -188,10 +188,10 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
|||
*/
|
||||
public IStructuredSelection getSelection() throws IllegalStateException {
|
||||
GraphViewer viewer = (GraphViewer)getApplicationWindow();
|
||||
if (viewer == null || viewer.viewer == null) {
|
||||
if (viewer == null || viewer.treeViewer == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
return (IStructuredSelection) viewer.viewer.getSelection();
|
||||
return (IStructuredSelection) viewer.treeViewer.getSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,7 +209,7 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
|||
/**
|
||||
* JFace component implementing the tree viewer
|
||||
*/
|
||||
private TreeViewer viewer;
|
||||
private TreeViewer treeViewer;
|
||||
|
||||
/**
|
||||
* @throws WalaException
|
||||
|
@ -227,20 +227,20 @@ public class SWTTreeViewer extends EJfaceApplicationRunner {
|
|||
*/
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
viewer = new TreeViewer(parent);
|
||||
viewer.setContentProvider(new GraphContentProvider());
|
||||
viewer.setLabelProvider(new GraphLabelProvider());
|
||||
viewer.setInput(getGraphInput());
|
||||
treeViewer = new TreeViewer(parent);
|
||||
treeViewer.setContentProvider(new GraphContentProvider());
|
||||
treeViewer.setLabelProvider(new GraphLabelProvider());
|
||||
treeViewer.setInput(getGraphInput());
|
||||
|
||||
// create a pop-up menu
|
||||
if (getPopUpActions().size() > 0) {
|
||||
MenuManager mm = new MenuManager();
|
||||
viewer.getTree().setMenu(mm.createContextMenu(viewer.getTree()));
|
||||
treeViewer.getTree().setMenu(mm.createContextMenu(treeViewer.getTree()));
|
||||
for (Iterator<ViewIRAction> it = getPopUpActions().iterator(); it.hasNext(); ) {
|
||||
mm.add(it.next());
|
||||
}
|
||||
}
|
||||
return viewer.getTree();
|
||||
return treeViewer.getTree();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ public class ViewAnnotatedIRAction extends ViewIRAction {
|
|||
|
||||
private final BasicBlockDecorator dec;
|
||||
|
||||
public ViewAnnotatedIRAction(SWTTreeViewer viewer, CallGraph cg, String psFile, String dotFile, String dotExe, String gvExe, BasicBlockDecorator dec) {
|
||||
public ViewAnnotatedIRAction(SWTTreeViewer viewer, CallGraph cg, String psFile, String dotFile, String dotExe, String gvExe,
|
||||
BasicBlockDecorator dec) {
|
||||
super(viewer, cg, psFile, dotFile, dotExe, gvExe);
|
||||
this.dec = dec;
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ public class ViewAnnotatedIRAction extends ViewIRAction {
|
|||
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
||||
try {
|
||||
dec.setCurrentNode(getNodeForSelection());
|
||||
GhostviewUtil.ghostviewIR(getCg().getClassHierarchy(), ir, false, getPsFile(), getDotFile(), getDotExe(), getGvExe(), dec);
|
||||
GhostviewUtil.ghostviewIR(getCg().getClassHierarchy(), ir, getPsFile(), getDotFile(), getDotExe(), getGvExe(), dec);
|
||||
} catch (WalaException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public class ViewIRAction extends Action {
|
|||
// spawn the viewer
|
||||
System.err.println("Spawn IR Viewer for " + ir.getMethod());
|
||||
try {
|
||||
GhostviewUtil.ghostviewIR(cg.getClassHierarchy(), ir, false, psFile, dotFile, dotExe, gvExe);
|
||||
GhostviewUtil.ghostviewIR(cg.getClassHierarchy(), ir, psFile, dotFile, dotExe, gvExe);
|
||||
} catch (WalaException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue