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:
sjfink 2008-03-31 15:47:58 +00:00
parent ec363cc10a
commit f89380f996
8 changed files with 138 additions and 66 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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