first phase of restructuring to fix string constant pointer analysis problems
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2076 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
95042b1f2f
commit
f6ebdd8eee
|
@ -249,10 +249,6 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
return delegate.getPointerKeyForStaticField(f);
|
return delegate.getPointerKeyForStaticField(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
return delegate.getStringConstantForInstanceKey(I);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<PointerKey> iteratePointerKeys() {
|
public Iterator<PointerKey> iteratePointerKeys() {
|
||||||
return delegate.iteratePointerKeys();
|
return delegate.iteratePointerKeys();
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
* add representation of flow for a node, if not already present
|
* add representation of flow for a node, if not already present
|
||||||
*
|
*
|
||||||
* @param node
|
* @param node
|
||||||
* @throws IllegalArgumentException if node == null
|
* @throws IllegalArgumentException
|
||||||
|
* if node == null
|
||||||
*/
|
*/
|
||||||
public void addSubgraphForNode(CGNode node) throws IllegalArgumentException {
|
public void addSubgraphForNode(CGNode node) throws IllegalArgumentException {
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
|
@ -352,7 +353,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
* @param sfk
|
* @param sfk
|
||||||
* the static field
|
* the static field
|
||||||
* @return all the variables whose values are written to sfk
|
* @return all the variables whose values are written to sfk
|
||||||
* @throws IllegalArgumentException if sfk == null
|
* @throws IllegalArgumentException
|
||||||
|
* if sfk == null
|
||||||
*/
|
*/
|
||||||
public Iterator<? extends Object> getWritesToStaticField(StaticFieldKey sfk) throws IllegalArgumentException {
|
public Iterator<? extends Object> getWritesToStaticField(StaticFieldKey sfk) throws IllegalArgumentException {
|
||||||
if (sfk == null) {
|
if (sfk == null) {
|
||||||
|
@ -369,7 +371,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
* @param sfk
|
* @param sfk
|
||||||
* the static field
|
* the static field
|
||||||
* @return all the variables that get the value of sfk
|
* @return all the variables that get the value of sfk
|
||||||
* @throws IllegalArgumentException if sfk == null
|
* @throws IllegalArgumentException
|
||||||
|
* if sfk == null
|
||||||
*/
|
*/
|
||||||
public Iterator<? extends Object> getReadsOfStaticField(StaticFieldKey sfk) throws IllegalArgumentException {
|
public Iterator<? extends Object> getReadsOfStaticField(StaticFieldKey sfk) throws IllegalArgumentException {
|
||||||
if (sfk == null) {
|
if (sfk == null) {
|
||||||
|
@ -539,9 +542,6 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add constraints for reference constants assigned to vars
|
* add constraints for reference constants assigned to vars
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
* @param ir
|
|
||||||
*/
|
*/
|
||||||
private void addNodeConstantConstraints(CGNode node, IR ir) {
|
private void addNodeConstantConstraints(CGNode node, IR ir) {
|
||||||
SymbolTable symbolTable = ir.getSymbolTable();
|
SymbolTable symbolTable = ir.getSymbolTable();
|
||||||
|
@ -551,6 +551,7 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
if (!(v instanceof Number)) {
|
if (!(v instanceof Number)) {
|
||||||
Object S = symbolTable.getConstantValue(i);
|
Object S = symbolTable.getConstantValue(i);
|
||||||
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
||||||
|
if (type != null) {
|
||||||
InstanceKey ik = heapModel.getInstanceKeyForConstant(type, S);
|
InstanceKey ik = heapModel.getInstanceKeyForConstant(type, S);
|
||||||
if (ik != null) {
|
if (ik != null) {
|
||||||
PointerKey pk = heapModel.getPointerKeyForLocal(node, i);
|
PointerKey pk = heapModel.getPointerKeyForLocal(node, i);
|
||||||
|
@ -562,13 +563,11 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add constraints to represent the flow of exceptions to the exceptional
|
* Add constraints to represent the flow of exceptions to the exceptional
|
||||||
* return value for this node
|
* return value for this node
|
||||||
*
|
|
||||||
* @param node
|
|
||||||
* @param ir
|
|
||||||
*/
|
*/
|
||||||
protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) {
|
protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) {
|
||||||
// add constraints relating to thrown exceptions that reach the exit
|
// add constraints relating to thrown exceptions that reach the exit
|
||||||
|
@ -655,7 +654,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
||||||
/**
|
/**
|
||||||
* Add constraints for a particular basic block.
|
* Add constraints for a particular basic block.
|
||||||
*/
|
*/
|
||||||
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b, FlowStatementVisitor v) {
|
protected void addBlockInstructionConstraints(CGNode node, ControlFlowGraph<ISSABasicBlock> cfg, ISSABasicBlock b,
|
||||||
|
FlowStatementVisitor v) {
|
||||||
v.setBasicBlock(b);
|
v.setBasicBlock(b);
|
||||||
|
|
||||||
// visit each instruction in the basic block.
|
// visit each instruction in the basic block.
|
||||||
|
|
|
@ -233,10 +233,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
||||||
addClassFileToScope(loader, file);
|
addClassFileToScope(loader, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param m
|
|
||||||
* @param loader
|
|
||||||
*/
|
|
||||||
private void processJarFile(EJarFile m, ClassLoaderReference loader) throws IllegalArgumentException {
|
private void processJarFile(EJarFile m, ClassLoaderReference loader) throws IllegalArgumentException {
|
||||||
String fileName = m.getUrl();
|
String fileName = m.getUrl();
|
||||||
Assertions.productionAssertion(fileName != null, "null jar file name specified");
|
Assertions.productionAssertion(fileName != null, "null jar file name specified");
|
||||||
|
|
|
@ -101,10 +101,10 @@ public class AnalysisOptions {
|
||||||
/**
|
/**
|
||||||
* Use distinct instance keys for distinct string constants?
|
* Use distinct instance keys for distinct string constants?
|
||||||
*
|
*
|
||||||
* TODO: possibly, this option should moved somewhere into the creation of
|
* TODO: Probably, this option should moved somewhere into the creation of
|
||||||
* instance keys. However, those factories are created within the various
|
* instance keys. However, those factories are created within the various
|
||||||
* builders right now, and this is the most convenient place for an engine
|
* builders right now, and this is the most convenient place for an engine
|
||||||
* user to set an option which the creation of instance keys laters picks up.
|
* user to set an option which the creation of instance keys later picks up.
|
||||||
*/
|
*/
|
||||||
private boolean useConstantSpecificKeys = false;
|
private boolean useConstantSpecificKeys = false;
|
||||||
|
|
||||||
|
|
|
@ -688,7 +688,7 @@ public class Util {
|
||||||
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
||||||
|
|
||||||
return ZeroXCFABuilder.make(cha, options, cache, customSelector, customInterpreter, options.getReflectionSpec(),
|
return ZeroXCFABuilder.make(cha, options, cache, customSelector, customInterpreter, options.getReflectionSpec(),
|
||||||
ZeroXInstanceKeys.ALLOCATIONS);
|
ZeroXInstanceKeys.ALLOCATIONS | ZeroXInstanceKeys.CONSTANT_SPECIFIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -809,6 +809,7 @@ public class Util {
|
||||||
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
||||||
ContextSelector appSelector = null;
|
ContextSelector appSelector = null;
|
||||||
SSAContextInterpreter appInterpreter = null;
|
SSAContextInterpreter appInterpreter = null;
|
||||||
|
options.setUseConstantSpecificKeys(true);
|
||||||
|
|
||||||
return new ZeroOneContainerCFABuilder(cha, options, cache, appSelector, appInterpreter, options.getReflectionSpec()) {
|
return new ZeroOneContainerCFABuilder(cha, options, cache, appSelector, appInterpreter, options.getReflectionSpec()) {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -85,16 +85,17 @@ public class AllocationSiteInstanceKeys implements InstanceKeyFactory {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
if (options.getUseConstantSpecificKeys())
|
if (options.getUseConstantSpecificKeys()) {
|
||||||
return new ConstantKey(S, cha.lookupClass(type));
|
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||||
else
|
} else {
|
||||||
return new ConcreteTypeKey(cha.lookupClass(type));
|
return new ConcreteTypeKey(cha.lookupClass(type));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
public Object getConstantForInstanceKey(InstanceKey I) {
|
||||||
if (I instanceof StringConstantKey) {
|
if (I instanceof ConstantKey) {
|
||||||
return ((StringConstantKey) I).getString();
|
return ((ConstantKey) I).getValue();
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,25 +108,18 @@ public class ClassBasedInstanceKeys implements InstanceKeyFactory {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
if (type == null || cha.lookupClass(type) == null) {
|
if (type == null || cha.lookupClass(type) == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
if (options.getUseConstantSpecificKeys()) {
|
if (options.getUseConstantSpecificKeys()) {
|
||||||
return new ConstantKey(S, cha.lookupClass(type));
|
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||||
} else {
|
} else {
|
||||||
return new ConcreteTypeKey(cha.lookupClass(type));
|
return new ConcreteTypeKey(cha.lookupClass(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
if (I instanceof StringConstantKey)
|
|
||||||
return ((StringConstantKey) I).getString();
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a set of ConcreteTypeKeys that represent the exceptions the PEI may
|
* @return a set of ConcreteTypeKeys that represent the exceptions the PEI may
|
||||||
* throw.
|
* throw.
|
||||||
|
|
|
@ -15,12 +15,12 @@ import com.ibm.wala.classLoader.IClass;
|
||||||
/**
|
/**
|
||||||
* An instance key which represents a unique set for each String constant
|
* An instance key which represents a unique set for each String constant
|
||||||
*/
|
*/
|
||||||
public final class ConstantKey implements InstanceKey {
|
public final class ConstantKey<T> implements InstanceKey {
|
||||||
private final Object value;
|
private final T value;
|
||||||
|
|
||||||
private final IClass valueClass;
|
private final IClass valueClass;
|
||||||
|
|
||||||
public ConstantKey(Object value, IClass valueClass) {
|
public ConstantKey(T value, IClass valueClass) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.valueClass = valueClass;
|
this.valueClass = valueClass;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public final class ConstantKey implements InstanceKey {
|
||||||
return valueClass;
|
return valueClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue() {
|
public T getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public interface InstanceKeyFactory {
|
||||||
public abstract InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation);
|
public abstract InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the instance key that represents the array allocated as the dimth
|
* @return the instance key that represents the array allocated as the dim_th
|
||||||
* dimension at a particular allocation
|
* dimension at a particular allocation
|
||||||
*/
|
*/
|
||||||
public abstract InstanceKey getInstanceKeyForMultiNewArray(CGNode node, NewSiteReference allocation, int dim);
|
public abstract InstanceKey getInstanceKeyForMultiNewArray(CGNode node, NewSiteReference allocation, int dim);
|
||||||
|
@ -35,13 +35,7 @@ public interface InstanceKeyFactory {
|
||||||
/**
|
/**
|
||||||
* @return the instance key that represents a constant with value S, when considered as a particular type
|
* @return the instance key that represents a constant with value S, when considered as a particular type
|
||||||
*/
|
*/
|
||||||
public abstract InstanceKey getInstanceKeyForConstant(TypeReference type, Object S);
|
public abstract <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S);
|
||||||
|
|
||||||
/**
|
|
||||||
* @return if I was allocated by this for a specific string constant, return
|
|
||||||
* that constant (return null otherwise).
|
|
||||||
*/
|
|
||||||
public abstract String getStringConstantForInstanceKey(InstanceKey I);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
|
|
|
@ -461,15 +461,10 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
||||||
return iKeyFactory.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
return iKeyFactory.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
return iKeyFactory.getInstanceKeyForConstant(type, S);
|
return iKeyFactory.getInstanceKeyForConstant(type, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
Assertions.UNREACHABLE();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter peiLoc, TypeReference type) {
|
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter peiLoc, TypeReference type) {
|
||||||
Assertions.UNREACHABLE();
|
Assertions.UNREACHABLE();
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1024,14 +1024,10 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
||||||
return instanceKeyFactory.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
return instanceKeyFactory.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
return instanceKeyFactory.getInstanceKeyForConstant(type, S);
|
return instanceKeyFactory.getInstanceKeyForConstant(type, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
return instanceKeyFactory.getStringConstantForInstanceKey(I);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForClassObject(TypeReference type) {
|
public InstanceKey getInstanceKeyForClassObject(TypeReference type) {
|
||||||
return instanceKeyFactory.getInstanceKeyForClassObject(type);
|
return instanceKeyFactory.getInstanceKeyForClassObject(type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
*/
|
*/
|
||||||
private final boolean usePreTransitiveSolver;
|
private final boolean usePreTransitiveSolver;
|
||||||
|
|
||||||
protected SSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache, PointerKeyFactory pointerKeyFactory) {
|
protected SSAPropagationCallGraphBuilder(IClassHierarchy cha, AnalysisOptions options, AnalysisCache cache,
|
||||||
|
PointerKeyFactory pointerKeyFactory) {
|
||||||
super(cha, options, cache, pointerKeyFactory);
|
super(cha, options, cache, pointerKeyFactory);
|
||||||
this.usePreTransitiveSolver = options.usePreTransitiveSolver();
|
this.usePreTransitiveSolver = options.usePreTransitiveSolver();
|
||||||
}
|
}
|
||||||
|
@ -463,10 +464,13 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
*
|
*
|
||||||
* @return the unique pointer key which catches the exceptions thrown by a
|
* @return the unique pointer key which catches the exceptions thrown by a
|
||||||
* call
|
* call
|
||||||
* @throws IllegalArgumentException if ir == null
|
* @throws IllegalArgumentException
|
||||||
* @throws IllegalArgumentException if call == null
|
* if ir == null
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if call == null
|
||||||
*/
|
*/
|
||||||
public PointerKey getUniqueCatchKey(SSAAbstractInvokeInstruction call, IR ir, CGNode node) throws IllegalArgumentException, IllegalArgumentException {
|
public PointerKey getUniqueCatchKey(SSAAbstractInvokeInstruction call, IR ir, CGNode node) throws IllegalArgumentException,
|
||||||
|
IllegalArgumentException {
|
||||||
if (call == null) {
|
if (call == null) {
|
||||||
throw new IllegalArgumentException("call == null");
|
throw new IllegalArgumentException("call == null");
|
||||||
}
|
}
|
||||||
|
@ -638,15 +642,11 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
return getBuilder().getInstanceKeyForMultiNewArray(node, allocation, dim);
|
return getBuilder().getInstanceKeyForMultiNewArray(node, allocation, dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(T S) {
|
||||||
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
||||||
return getBuilder().getInstanceKeyForConstant(type, S);
|
return getBuilder().getInstanceKeyForConstant(type, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
return getBuilder().getStringConstantForInstanceKey(I);
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForPEI(ProgramCounter instr, TypeReference type) {
|
public InstanceKey getInstanceKeyForPEI(ProgramCounter instr, TypeReference type) {
|
||||||
return getBuilder().getInstanceKeyForPEI(node, instr, type);
|
return getBuilder().getInstanceKeyForPEI(node, instr, type);
|
||||||
}
|
}
|
||||||
|
@ -2046,14 +2046,35 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
||||||
boolean ensureIndexes) {
|
boolean ensureIndexes) {
|
||||||
InstanceKey[] result;
|
InstanceKey[] result;
|
||||||
if (isConstantRef(symbolTable, valueNumber)) {
|
if (isConstantRef(symbolTable, valueNumber)) {
|
||||||
Object S = symbolTable.getConstantValue(valueNumber);
|
Object x = symbolTable.getConstantValue(valueNumber);
|
||||||
|
if (x instanceof String) {
|
||||||
|
// this is always the case in Java. use strong typing in the call to getInstanceKeyForConstant.
|
||||||
|
String S = (String)x;
|
||||||
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
||||||
|
if (type == null) {
|
||||||
|
return new InstanceKey[0];
|
||||||
|
}
|
||||||
InstanceKey ik = hm.getInstanceKeyForConstant(type, S);
|
InstanceKey ik = hm.getInstanceKeyForConstant(type, S);
|
||||||
if (ik != null) {
|
if (ik != null) {
|
||||||
result = new InstanceKey[] { ik };
|
result = new InstanceKey[] { ik };
|
||||||
} else {
|
} else {
|
||||||
result = new InstanceKey[0];
|
result = new InstanceKey[0];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// some non-built in type (e.g. Integer). give up on strong typing.
|
||||||
|
// language-specific subclasses (e.g. Javascript) should override this method to get strong typing
|
||||||
|
// with generics if desired.
|
||||||
|
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(x);
|
||||||
|
if (type == null) {
|
||||||
|
return new InstanceKey[0];
|
||||||
|
}
|
||||||
|
InstanceKey ik = hm.getInstanceKeyForConstant(type, x);
|
||||||
|
if (ik != null) {
|
||||||
|
result = new InstanceKey[] { ik };
|
||||||
|
} else {
|
||||||
|
result = new InstanceKey[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SSANewInstruction def = (SSANewInstruction) du.getDef(valueNumber);
|
SSANewInstruction def = (SSANewInstruction) du.getDef(valueNumber);
|
||||||
InstanceKey iKey = hm.getInstanceKeyForAllocation(node, def.getNewSite());
|
InstanceKey iKey = hm.getInstanceKeyForAllocation(node, def.getNewSite());
|
||||||
|
|
|
@ -86,21 +86,13 @@ public class SmushedAllocationSiteInstanceKeys implements InstanceKeyFactory {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
if (options.getUseConstantSpecificKeys())
|
if (options.getUseConstantSpecificKeys())
|
||||||
return new ConstantKey(S, cha.lookupClass(type));
|
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||||
else
|
else
|
||||||
return new ConcreteTypeKey(cha.lookupClass(type));
|
return new ConcreteTypeKey(cha.lookupClass(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
if (I instanceof StringConstantKey) {
|
|
||||||
return ((StringConstantKey) I).getString();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter pei, TypeReference type) {
|
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter pei, TypeReference type) {
|
||||||
return classBased.getInstanceKeyForPEI(node, pei, type);
|
return classBased.getInstanceKeyForPEI(node, pei, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,58 +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.ipa.callgraph.propagation;
|
|
||||||
|
|
||||||
import com.ibm.wala.classLoader.IClass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An instance key which represents a unique set for each String constant
|
|
||||||
*/
|
|
||||||
public final class StringConstantKey implements InstanceKey {
|
|
||||||
private final String string;
|
|
||||||
|
|
||||||
private final IClass stringClass;
|
|
||||||
|
|
||||||
public StringConstantKey(String string, IClass stringClass) {
|
|
||||||
this.string = string;
|
|
||||||
this.stringClass = stringClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (obj instanceof StringConstantKey) {
|
|
||||||
StringConstantKey other = (StringConstantKey) obj;
|
|
||||||
return string.equals(other.string);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return 1877 * string.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "[" + string + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see com.ibm.wala.ipa.callgraph.propagation.InstanceKey#getConcreteType()
|
|
||||||
*/
|
|
||||||
public IClass getConcreteType() {
|
|
||||||
return stringClass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getString() {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@ import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.AllocationSiteInstanceKeys;
|
import com.ibm.wala.ipa.callgraph.propagation.AllocationSiteInstanceKeys;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.ClassBasedInstanceKeys;
|
import com.ibm.wala.ipa.callgraph.propagation.ClassBasedInstanceKeys;
|
||||||
|
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory;
|
||||||
import com.ibm.wala.ipa.callgraph.propagation.SmushedAllocationSiteInstanceKeys;
|
import com.ibm.wala.ipa.callgraph.propagation.SmushedAllocationSiteInstanceKeys;
|
||||||
|
@ -93,6 +94,11 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
*/
|
*/
|
||||||
public static final int SMUSH_MANY = 16;
|
public static final int SMUSH_MANY = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we use constant-specific keys?
|
||||||
|
*/
|
||||||
|
public static final int CONSTANT_SPECIFIC = 32;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When using smushing, how many sites in a node will be kept distinct before
|
* When using smushing, how many sites in a node will be kept distinct before
|
||||||
* smushing?
|
* smushing?
|
||||||
|
@ -135,13 +141,16 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
*/
|
*/
|
||||||
final Map<CGNode, Set> smushMap = HashMapFactory.make();
|
final Map<CGNode, Set> smushMap = HashMapFactory.make();
|
||||||
|
|
||||||
public ZeroXInstanceKeys(AnalysisOptions options, IClassHierarchy cha, RTAContextInterpreter contextInterpreter,
|
public ZeroXInstanceKeys(AnalysisOptions options, IClassHierarchy cha, RTAContextInterpreter contextInterpreter, int policy) {
|
||||||
int policy) {
|
this.policy = policy;
|
||||||
|
if (disambiguateConstants()) {
|
||||||
|
// this is an ugly hack. TODO: clean it all up.
|
||||||
|
options.setUseConstantSpecificKeys(true);
|
||||||
|
}
|
||||||
classBased = new ClassBasedInstanceKeys(options, cha);
|
classBased = new ClassBasedInstanceKeys(options, cha);
|
||||||
siteBased = new AllocationSiteInstanceKeys(options, cha);
|
siteBased = new AllocationSiteInstanceKeys(options, cha);
|
||||||
smushed = new SmushedAllocationSiteInstanceKeys(options, cha);
|
smushed = new SmushedAllocationSiteInstanceKeys(options, cha);
|
||||||
this.cha = cha;
|
this.cha = cha;
|
||||||
this.policy = policy;
|
|
||||||
this.contextInterpreter = contextInterpreter;
|
this.contextInterpreter = contextInterpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +177,10 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
return (policy & SMUSH_PRIMITIVE_HOLDERS) > 0;
|
return (policy & SMUSH_PRIMITIVE_HOLDERS) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean disambiguateConstants() {
|
||||||
|
return (policy & CONSTANT_SPECIFIC) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
||||||
if (allocation == null) {
|
if (allocation == null) {
|
||||||
throw new IllegalArgumentException("allocation is null");
|
throw new IllegalArgumentException("allocation is null");
|
||||||
|
@ -193,8 +206,6 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
/**
|
/**
|
||||||
* side effect: populates the smush map.
|
* side effect: populates the smush map.
|
||||||
*
|
*
|
||||||
* @param c
|
|
||||||
* @param node
|
|
||||||
* @return true iff the node contains too many allocation sites of type c
|
* @return true iff the node contains too many allocation sites of type c
|
||||||
*/
|
*/
|
||||||
private boolean exceedsSmushLimit(IClass c, CGNode node) {
|
private boolean exceedsSmushLimit(IClass c, CGNode node) {
|
||||||
|
@ -216,7 +227,6 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
|
||||||
* @return Map: IClass -> Integer, the number of allocation sites for each
|
* @return Map: IClass -> Integer, the number of allocation sites for each
|
||||||
* type.
|
* type.
|
||||||
*/
|
*/
|
||||||
|
@ -245,15 +255,15 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
|
if (type == null) {
|
||||||
|
throw new IllegalArgumentException("null type");
|
||||||
|
}
|
||||||
|
if (disambiguateConstants()) {
|
||||||
|
return new ConstantKey<T>(S, getClassHierarchy().lookupClass(type));
|
||||||
|
} else {
|
||||||
return classBased.getInstanceKeyForConstant(type, S);
|
return classBased.getInstanceKeyForConstant(type, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @see com.ibm.wala.ipa.callgraph.propagation.InstanceKeyFactory#getStringConstantForInstanceKey(com.ibm.wala.ipa.callgraph.propagation.InstanceKey)
|
|
||||||
*/
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
return classBased.getStringConstantForInstanceKey(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -291,7 +301,8 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
if (C == null) {
|
if (C == null) {
|
||||||
throw new IllegalArgumentException("C is null");
|
throw new IllegalArgumentException("C is null");
|
||||||
}
|
}
|
||||||
return C.getReference().equals(TypeReference.JavaLangString) || C.getReference().equals(JavaLangStringBuffer) || C.getReference().equals(JavaLangStringBuilder);
|
return C.getReference().equals(TypeReference.JavaLangString) || C.getReference().equals(JavaLangStringBuffer)
|
||||||
|
|| C.getReference().equals(JavaLangStringBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isThrowable(IClass C) {
|
public boolean isThrowable(IClass C) {
|
||||||
|
@ -329,9 +340,6 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns the cha.
|
|
||||||
*/
|
|
||||||
protected IClassHierarchy getClassHierarchy() {
|
protected IClassHierarchy getClassHierarchy() {
|
||||||
return cha;
|
return cha;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class DelegatingExtendedHeapModel implements ExtendedHeapModel {
|
||||||
return h.getInstanceKeyForClassObject(type);
|
return h.getInstanceKeyForClassObject(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||||
return h.getInstanceKeyForConstant(type, S);
|
return h.getInstanceKeyForConstant(type, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,10 +96,6 @@ public class DelegatingExtendedHeapModel implements ExtendedHeapModel {
|
||||||
return h.getPointerKeyForStaticField(f);
|
return h.getPointerKeyForStaticField(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
|
||||||
return h.getStringConstantForInstanceKey(I);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<PointerKey> iteratePointerKeys() {
|
public Iterator<PointerKey> iteratePointerKeys() {
|
||||||
return h.iteratePointerKeys();
|
return h.iteratePointerKeys();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue