fix hashcode problems and misc. minor cleanups
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2734 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
ec363cc10a
commit
f89380f996
|
@ -225,7 +225,7 @@ public abstract class AbstractIntStackMachine implements FixedPointConstants {
|
|||
Assertions._assert(from != null);
|
||||
Assertions._assert(to != null);
|
||||
}
|
||||
MachineState result = new MachineState(71167 * (from.hashCode() + to.hashCode()), from);
|
||||
MachineState result = new MachineState(71167 * from.hashCode() + to.hashCode(), from);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -73,4 +73,29 @@ public abstract class DirectoryTreeModule implements Module {
|
|||
public String toString() {
|
||||
return getClass() + ":" + getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((root == null) ? 0 : root.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final DirectoryTreeModule other = (DirectoryTreeModule) obj;
|
||||
if (root == null) {
|
||||
if (other.root != null)
|
||||
return false;
|
||||
} else if (!root.equals(other.root))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
|
@ -39,10 +40,9 @@ import com.ibm.wala.classLoader.SourceDirectoryTreeModule;
|
|||
import com.ibm.wala.client.AbstractAnalysisEngine;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.MapUtil;
|
||||
import com.ibm.wala.util.config.*;
|
||||
import com.ibm.wala.util.config.AnalysisScopeReader;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
|
@ -95,9 +95,11 @@ public class EclipseProjectPath {
|
|||
*/
|
||||
private final IJavaProject project;
|
||||
|
||||
private final Map<Loader, Set<Module>> binaryModules = HashMapFactory.make();
|
||||
// SJF: Intentionally do not use HashMapFactory, since the Loader keys in the following must use
|
||||
// identityHashCode. TODO: fix this source of non-determinism?
|
||||
private final Map<Loader, Set<Module>> binaryModules = new HashMap<Loader, Set<Module>>();
|
||||
|
||||
private final Map<Loader, Set<Module>> sourceModules = HashMapFactory.make();
|
||||
private final Map<Loader, Set<Module>> sourceModules = new HashMap<Loader, Set<Module>>();
|
||||
|
||||
private final Collection<IClasspathEntry> alreadyResolved = HashSetFactory.make();
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
package com.ibm.wala.ipa.callgraph.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
|
@ -19,7 +21,6 @@ import com.ibm.wala.types.TypeReference;
|
|||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
*
|
||||
* An entrypoint whose parameter types are the declared types.
|
||||
*
|
||||
* @author sfink
|
||||
|
@ -93,4 +94,26 @@ public class DefaultEntrypoint extends Entrypoint {
|
|||
public IClassHierarchy getCha() {
|
||||
return cha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + Arrays.hashCode(paramTypes);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final DefaultEntrypoint other = (DefaultEntrypoint) obj;
|
||||
if (!Arrays.equals(paramTypes, other.paramTypes))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1055,7 +1055,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
if (instruction.getCallSite().isStatic()) {
|
||||
CGNode n = getTargetForCall(node, instruction.getCallSite(), (InstanceKey) null);
|
||||
if (n == null) {
|
||||
Warnings.add(ResolutionFailure.create(node, instruction));
|
||||
Warnings.add(ResolutionFailure.create(node, instruction.getCallSite()));
|
||||
} else {
|
||||
getBuilder().processResolvedCall(node, instruction, n, computeInvariantParameters(instruction), uniqueCatch);
|
||||
if (DEBUG) {
|
||||
|
|
|
@ -165,10 +165,11 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
*/
|
||||
private void populate() {
|
||||
if (!isPopulated) {
|
||||
// ensure that we keep the single, canonical IR live throughout initialization, while the instructionIndices map is live.
|
||||
// ensure that we keep the single, canonical IR live throughout initialization, while the instructionIndices map
|
||||
// is live.
|
||||
IR ir = node.getIR();
|
||||
isPopulated = true;
|
||||
|
||||
|
||||
Map<SSAInstruction, Integer> instructionIndices = computeInstructionIndices(ir);
|
||||
createNodes(ref, cOptions, ir);
|
||||
createScalarEdges(cOptions, ir, instructionIndices);
|
||||
|
@ -205,7 +206,8 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
/**
|
||||
* Create all control dependence edges in this PDG.
|
||||
*/
|
||||
private void createControlDependenceEdges(ControlDependenceOptions cOptions, IR ir,Map<SSAInstruction, Integer> instructionIndices) {
|
||||
private void createControlDependenceEdges(ControlDependenceOptions cOptions, IR ir,
|
||||
Map<SSAInstruction, Integer> instructionIndices) {
|
||||
if (cOptions.equals(ControlDependenceOptions.NONE)) {
|
||||
return;
|
||||
}
|
||||
|
@ -322,7 +324,7 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
return;
|
||||
}
|
||||
|
||||
// this is tricky .. I'm explicitly creating a new DefUse to make sure it refers to the instructions we need from
|
||||
// this is tricky .. I'm explicitly creating a new DefUse to make sure it refers to the instructions we need from
|
||||
// the "one true" ir of the moment.
|
||||
DefUse DU = new DefUse(ir);
|
||||
SSAInstruction[] instructions = ir.getInstructions();
|
||||
|
@ -409,7 +411,7 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
if (Assertions.verifyAssertions && dOptions.isIgnoreExceptions()) {
|
||||
Assertions._assert(!s.getKind().equals(Kind.EXC_RET_CALLER));
|
||||
}
|
||||
|
||||
|
||||
ValueNumberCarrier a = (ValueNumberCarrier) s;
|
||||
for (Iterator<SSAInstruction> it2 = DU.getUses(a.getValueNumber()); it2.hasNext();) {
|
||||
SSAInstruction use = it2.next();
|
||||
|
@ -796,8 +798,8 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
private void createNodes(Map<CGNode, OrdinalSet<PointerKey>> ref, ControlDependenceOptions cOptions, IR ir) {
|
||||
|
||||
if (ir != null) {
|
||||
Collection<SSAInstruction> visited = createNormalStatements(ir, ref);
|
||||
createSpecialStatements(ir, visited);
|
||||
createNormalStatements(ir, ref);
|
||||
createSpecialStatements(ir);
|
||||
}
|
||||
|
||||
createCalleeParams(ref);
|
||||
|
@ -868,21 +870,16 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
* <li> getCaughtExceptions
|
||||
* </ul>
|
||||
*/
|
||||
private void createSpecialStatements(IR ir, Collection<SSAInstruction> visited) {
|
||||
private void createSpecialStatements(IR ir) {
|
||||
// create a node for instructions which do not correspond to bytecode
|
||||
for (Iterator<SSAInstruction> it = ir.iterateAllInstructions(); it.hasNext();) {
|
||||
SSAInstruction s = it.next();
|
||||
if (s != null && !visited.contains(s)) {
|
||||
visited.add(s);
|
||||
if (s instanceof SSAPhiInstruction) {
|
||||
delegate.addNode(new PhiStatement(node, (SSAPhiInstruction) s));
|
||||
} else if (s instanceof SSAGetCaughtExceptionInstruction) {
|
||||
delegate.addNode(new GetCaughtExceptionStatement(node, (SSAGetCaughtExceptionInstruction) s));
|
||||
} else if (s instanceof SSAPiInstruction) {
|
||||
delegate.addNode(new PiStatement(node, (SSAPiInstruction) s));
|
||||
} else {
|
||||
Assertions.UNREACHABLE(s.toString());
|
||||
}
|
||||
if (s instanceof SSAPhiInstruction) {
|
||||
delegate.addNode(new PhiStatement(node, (SSAPhiInstruction) s));
|
||||
} else if (s instanceof SSAGetCaughtExceptionInstruction) {
|
||||
delegate.addNode(new GetCaughtExceptionStatement(node, (SSAGetCaughtExceptionInstruction) s));
|
||||
} else if (s instanceof SSAPiInstruction) {
|
||||
delegate.addNode(new PiStatement(node, (SSAPiInstruction) s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -890,8 +887,7 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
/**
|
||||
* Create nodes in the graph corresponding to "normal" (bytecode) instructions
|
||||
*/
|
||||
private Collection<SSAInstruction> createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||
Collection<SSAInstruction> visited = HashSetFactory.make();
|
||||
private void createNormalStatements(IR ir, Map<CGNode, OrdinalSet<PointerKey>> ref) {
|
||||
// create a node for every normal instruction in the IR
|
||||
SSAInstruction[] instructions = ir.getInstructions();
|
||||
for (int i = 0; i < instructions.length; i++) {
|
||||
|
@ -903,13 +899,11 @@ public class PDG implements NumberedGraph<Statement> {
|
|||
|
||||
if (s != null) {
|
||||
delegate.addNode(new NormalStatement(node, i));
|
||||
visited.add(s);
|
||||
}
|
||||
if (s instanceof SSAAbstractInvokeInstruction) {
|
||||
addParamPassingStatements(i, ref, ir);
|
||||
}
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,9 +21,7 @@ import com.ibm.wala.types.MemberReference;
|
|||
public abstract class MethodWarning extends Warning {
|
||||
|
||||
private final MemberReference method;
|
||||
/**
|
||||
* @param level
|
||||
*/
|
||||
|
||||
public MethodWarning(byte level, MemberReference method) {
|
||||
super(level);
|
||||
this.method = method;
|
||||
|
@ -37,4 +35,30 @@ public abstract class MethodWarning extends Warning {
|
|||
public MemberReference getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final MethodWarning other = (MethodWarning) obj;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,29 +13,26 @@ package com.ibm.wala.util.warnings;
|
|||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
|
||||
/**
|
||||
*
|
||||
* A failure to resolve some entity while processing a particular
|
||||
* node
|
||||
*
|
||||
* @author sfink
|
||||
*/
|
||||
public class ResolutionFailure extends MethodWarning {
|
||||
public class ResolutionFailure<T> extends MethodWarning {
|
||||
|
||||
final Object ref;
|
||||
final T ref;
|
||||
final String message;
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param ref
|
||||
* @throws NullPointerException if node is null
|
||||
*/
|
||||
public ResolutionFailure(CGNode node, Object ref, String message) throws NullPointerException {
|
||||
public ResolutionFailure(CGNode node, T ref, String message) throws NullPointerException {
|
||||
super(Warning.SEVERE, node.getMethod().getReference());
|
||||
this.message = message;
|
||||
this.ref = ref;
|
||||
}
|
||||
|
||||
private ResolutionFailure(CGNode node, Object ref) {
|
||||
private ResolutionFailure(CGNode node, T ref) {
|
||||
this(node, ref, null);
|
||||
}
|
||||
|
||||
|
@ -51,45 +48,52 @@ public class ResolutionFailure extends MethodWarning {
|
|||
}
|
||||
}
|
||||
|
||||
public static ResolutionFailure create(CGNode node, Object ref) throws IllegalArgumentException {
|
||||
public static <T> ResolutionFailure<T> create(CGNode node, T ref, String msg) throws IllegalArgumentException {
|
||||
if (node == null) {
|
||||
throw new IllegalArgumentException("node cannot be null");
|
||||
}
|
||||
return make(node, ref);
|
||||
return new ResolutionFailure<T>(node, ref, msg);
|
||||
}
|
||||
|
||||
public static ResolutionFailure create(CGNode node, Object ref, String msg) throws IllegalArgumentException {
|
||||
if (node == null) {
|
||||
throw new IllegalArgumentException("node cannot be null");
|
||||
}
|
||||
return new ResolutionFailure(node, ref, msg);
|
||||
}
|
||||
|
||||
public static ResolutionFailure make(CGNode node, Object ref) {
|
||||
public static <T> ResolutionFailure create(CGNode node, T ref) {
|
||||
if (node == null) {
|
||||
throw new IllegalArgumentException("node is null");
|
||||
}
|
||||
return new ResolutionFailure(node, ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass().equals(obj.getClass())) {
|
||||
ResolutionFailure other = (ResolutionFailure)obj;
|
||||
return (getMethod().equals(other.getMethod()) && getLevel()==other.getLevel() && ref.equals(other.ref));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return new ResolutionFailure<T>(node, ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getMethod().hashCode() * 8999 + ref.hashCode() * 8461 + getLevel();
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((message == null) ? 0 : message.hashCode());
|
||||
result = prime * result + ((ref == null) ? 0 : ref.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final ResolutionFailure other = (ResolutionFailure) obj;
|
||||
if (message == null) {
|
||||
if (other.message != null)
|
||||
return false;
|
||||
} else if (!message.equals(other.message))
|
||||
return false;
|
||||
if (ref == null) {
|
||||
if (other.ref != null)
|
||||
return false;
|
||||
} else if (!ref.equals(other.ref))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue