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);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
return delegate.getStringConstantForInstanceKey(I);
|
||||
}
|
||||
|
||||
public Iterator<PointerKey> 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
|
||||
*
|
||||
* @param node
|
||||
* @throws IllegalArgumentException if node == null
|
||||
* @throws IllegalArgumentException
|
||||
* if node == null
|
||||
*/
|
||||
public void addSubgraphForNode(CGNode node) throws IllegalArgumentException {
|
||||
if (node == null) {
|
||||
|
@ -352,7 +353,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
|||
* @param sfk
|
||||
* the static field
|
||||
* @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 {
|
||||
if (sfk == null) {
|
||||
|
@ -369,7 +371,8 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
|||
* @param sfk
|
||||
* the static field
|
||||
* @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 {
|
||||
if (sfk == null) {
|
||||
|
@ -539,9 +542,6 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
|||
|
||||
/**
|
||||
* add constraints for reference constants assigned to vars
|
||||
*
|
||||
* @param node
|
||||
* @param ir
|
||||
*/
|
||||
private void addNodeConstantConstraints(CGNode node, IR ir) {
|
||||
SymbolTable symbolTable = ir.getSymbolTable();
|
||||
|
@ -551,12 +551,14 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
|||
if (!(v instanceof Number)) {
|
||||
Object S = symbolTable.getConstantValue(i);
|
||||
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
||||
InstanceKey ik = heapModel.getInstanceKeyForConstant(type, S);
|
||||
if (ik != null) {
|
||||
PointerKey pk = heapModel.getPointerKeyForLocal(node, i);
|
||||
addNode(pk);
|
||||
addNode(ik);
|
||||
addEdge(pk, ik, NewLabel.v());
|
||||
if (type != null) {
|
||||
InstanceKey ik = heapModel.getInstanceKeyForConstant(type, S);
|
||||
if (ik != null) {
|
||||
PointerKey pk = heapModel.getPointerKeyForLocal(node, i);
|
||||
addNode(pk);
|
||||
addNode(ik);
|
||||
addEdge(pk, ik, NewLabel.v());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -566,9 +568,6 @@ public abstract class DemandFlowGraph extends FlowLabelGraph {
|
|||
/**
|
||||
* Add constraints to represent the flow of exceptions to the exceptional
|
||||
* return value for this node
|
||||
*
|
||||
* @param node
|
||||
* @param ir
|
||||
*/
|
||||
protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) {
|
||||
// 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.
|
||||
*/
|
||||
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);
|
||||
|
||||
// visit each instruction in the basic block.
|
||||
|
|
|
@ -233,10 +233,7 @@ public class EMFScopeWrapper extends AnalysisScope {
|
|||
addClassFileToScope(loader, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param m
|
||||
* @param loader
|
||||
*/
|
||||
|
||||
private void processJarFile(EJarFile m, ClassLoaderReference loader) throws IllegalArgumentException {
|
||||
String fileName = m.getUrl();
|
||||
Assertions.productionAssertion(fileName != null, "null jar file name specified");
|
||||
|
|
|
@ -101,10 +101,10 @@ public class AnalysisOptions {
|
|||
/**
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
|
|
|
@ -688,7 +688,7 @@ public class Util {
|
|||
addDefaultBypassLogic(options, scope, Util.class.getClassLoader(), cha);
|
||||
|
||||
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);
|
||||
ContextSelector appSelector = null;
|
||||
SSAContextInterpreter appInterpreter = null;
|
||||
options.setUseConstantSpecificKeys(true);
|
||||
|
||||
return new ZeroOneContainerCFABuilder(cha, options, cache, appSelector, appInterpreter, options.getReflectionSpec()) {
|
||||
@Override
|
||||
|
|
|
@ -45,7 +45,7 @@ public class AllocationSiteInstanceKeys implements InstanceKeyFactory {
|
|||
|
||||
/**
|
||||
* @param options
|
||||
* Governing call graph construction options
|
||||
* Governing call graph construction options
|
||||
*/
|
||||
public AllocationSiteInstanceKeys(AnalysisOptions options, IClassHierarchy cha) {
|
||||
this.options = options;
|
||||
|
@ -85,16 +85,17 @@ public class AllocationSiteInstanceKeys implements InstanceKeyFactory {
|
|||
return key;
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
||||
if (options.getUseConstantSpecificKeys())
|
||||
return new ConstantKey(S, cha.lookupClass(type));
|
||||
else
|
||||
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||
if (options.getUseConstantSpecificKeys()) {
|
||||
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||
} else {
|
||||
return new ConcreteTypeKey(cha.lookupClass(type));
|
||||
}
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
if (I instanceof StringConstantKey) {
|
||||
return ((StringConstantKey) I).getString();
|
||||
public Object getConstantForInstanceKey(InstanceKey I) {
|
||||
if (I instanceof ConstantKey) {
|
||||
return ((ConstantKey) I).getValue();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -108,25 +108,18 @@ public class ClassBasedInstanceKeys implements InstanceKeyFactory {
|
|||
return key;
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
||||
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||
if (type == null || cha.lookupClass(type) == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (options.getUseConstantSpecificKeys()) {
|
||||
return new ConstantKey(S, cha.lookupClass(type));
|
||||
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||
} else {
|
||||
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
|
||||
* throw.
|
||||
|
|
|
@ -15,12 +15,12 @@ import com.ibm.wala.classLoader.IClass;
|
|||
/**
|
||||
* An instance key which represents a unique set for each String constant
|
||||
*/
|
||||
public final class ConstantKey implements InstanceKey {
|
||||
private final Object value;
|
||||
public final class ConstantKey<T> implements InstanceKey {
|
||||
private final T value;
|
||||
|
||||
private final IClass valueClass;
|
||||
|
||||
public ConstantKey(Object value, IClass valueClass) {
|
||||
public ConstantKey(T value, IClass valueClass) {
|
||||
this.value = value;
|
||||
this.valueClass = valueClass;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public final class ConstantKey implements InstanceKey {
|
|||
return valueClass;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public interface InstanceKeyFactory {
|
|||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public abstract InstanceKey getInstanceKeyForConstant(TypeReference type, Object 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);
|
||||
public abstract <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S);
|
||||
|
||||
/**
|
||||
* @param node
|
||||
|
|
|
@ -461,15 +461,10 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis {
|
|||
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);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter peiLoc, TypeReference type) {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
|
|
|
@ -1024,14 +1024,10 @@ public abstract class PropagationCallGraphBuilder implements CallGraphBuilder {
|
|||
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);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
return instanceKeyFactory.getStringConstantForInstanceKey(I);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForClassObject(TypeReference type) {
|
||||
return instanceKeyFactory.getInstanceKeyForClassObject(type);
|
||||
}
|
||||
|
|
|
@ -171,7 +171,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
*/
|
||||
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);
|
||||
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
|
||||
* call
|
||||
* @throws IllegalArgumentException if ir == null
|
||||
* @throws IllegalArgumentException if call == null
|
||||
* @throws IllegalArgumentException
|
||||
* 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) {
|
||||
throw new IllegalArgumentException("call == null");
|
||||
}
|
||||
|
@ -597,7 +601,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
protected AnalysisOptions getOptions() {
|
||||
return builder.options;
|
||||
}
|
||||
|
||||
|
||||
protected AnalysisCache getAnalysisCache() {
|
||||
return builder.getAnalysisCache();
|
||||
}
|
||||
|
@ -638,15 +642,11 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
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);
|
||||
return getBuilder().getInstanceKeyForConstant(type, S);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
return getBuilder().getStringConstantForInstanceKey(I);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForPEI(ProgramCounter instr, TypeReference type) {
|
||||
return getBuilder().getInstanceKeyForPEI(node, instr, type);
|
||||
}
|
||||
|
@ -1137,7 +1137,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
@Override
|
||||
public void visitNew(SSANewInstruction instruction) {
|
||||
InstanceKey iKey = getInstanceKeyForAllocation(instruction.getNewSite());
|
||||
|
||||
|
||||
if (iKey == null) {
|
||||
// something went wrong. I hope someone raised a warning.
|
||||
return;
|
||||
|
@ -1264,23 +1264,23 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
@Override
|
||||
public void visitPhi(SSAPhiInstruction instruction) {
|
||||
if (ir.getMethod() instanceof AbstractRootMethod) {
|
||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||
if (hasNoInterestingUses(instruction.getDef())) {
|
||||
system.recordImplicitPointsToSet(dst);
|
||||
} else {
|
||||
for(int i = 0; i < instruction.getNumberOfUses(); i++) {
|
||||
PointerKey use = getPointerKeyForLocal(instruction.getUse(i));
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getUse(i))) {
|
||||
system.recordImplicitPointsToSet(use);
|
||||
PointerKey dst = getPointerKeyForLocal(instruction.getDef());
|
||||
if (hasNoInterestingUses(instruction.getDef())) {
|
||||
system.recordImplicitPointsToSet(dst);
|
||||
} else {
|
||||
for (int i = 0; i < instruction.getNumberOfUses(); i++) {
|
||||
PointerKey use = getPointerKeyForLocal(instruction.getUse(i));
|
||||
if (contentsAreInvariant(symbolTable, du, instruction.getUse(i))) {
|
||||
system.recordImplicitPointsToSet(use);
|
||||
InstanceKey[] ik = getInvariantContents(instruction.getUse(i));
|
||||
for (int j = 0; j < ik.length; j++) {
|
||||
system.newConstraint(dst, ik[j]);
|
||||
system.newConstraint(dst, ik[j]);
|
||||
}
|
||||
} else {
|
||||
system.newConstraint(dst, assignOperator, use);
|
||||
system.newConstraint(dst, assignOperator, use);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1692,7 +1692,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
Trace.println("Warning: null target for call " + call + " " + iKey);
|
||||
}
|
||||
} else {
|
||||
IntSet targets = getCallGraph().getPossibleTargetNumbers(node,call.getCallSite());
|
||||
IntSet targets = getCallGraph().getPossibleTargetNumbers(node, call.getCallSite());
|
||||
if (targets != null && targets.contains(target.getGraphNodeId())) {
|
||||
// do nothing; we've previously discovered and handled this
|
||||
// receiver for this call site.
|
||||
|
@ -2046,13 +2046,34 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
|
|||
boolean ensureIndexes) {
|
||||
InstanceKey[] result;
|
||||
if (isConstantRef(symbolTable, valueNumber)) {
|
||||
Object S = symbolTable.getConstantValue(valueNumber);
|
||||
TypeReference type = node.getMethod().getDeclaringClass().getClassLoader().getLanguage().getConstantType(S);
|
||||
InstanceKey ik = hm.getInstanceKeyForConstant(type, S);
|
||||
if (ik != null) {
|
||||
result = new InstanceKey[] { ik };
|
||||
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);
|
||||
if (type == null) {
|
||||
return new InstanceKey[0];
|
||||
}
|
||||
InstanceKey ik = hm.getInstanceKeyForConstant(type, S);
|
||||
if (ik != null) {
|
||||
result = new InstanceKey[] { ik };
|
||||
} else {
|
||||
result = new InstanceKey[0];
|
||||
}
|
||||
} else {
|
||||
result = new InstanceKey[0];
|
||||
// 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 {
|
||||
SSANewInstruction def = (SSANewInstruction) du.getDef(valueNumber);
|
||||
|
|
|
@ -86,21 +86,13 @@ public class SmushedAllocationSiteInstanceKeys implements InstanceKeyFactory {
|
|||
return key;
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
||||
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||
if (options.getUseConstantSpecificKeys())
|
||||
return new ConstantKey(S, cha.lookupClass(type));
|
||||
return new ConstantKey<T>(S, cha.lookupClass(type));
|
||||
else
|
||||
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) {
|
||||
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.propagation.AllocationSiteInstanceKeys;
|
||||
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.InstanceKeyFactory;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.SmushedAllocationSiteInstanceKeys;
|
||||
|
@ -47,7 +48,7 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
|
||||
public final static TypeReference JavaLangStringBuffer = TypeReference.findOrCreate(ClassLoaderReference.Primordial,
|
||||
JavaLangStringBufferName);
|
||||
|
||||
|
||||
private final static TypeName JavaLangStringBuilderName = TypeName.string2TypeName("Ljava/lang/StringBuilder");
|
||||
|
||||
public final static TypeReference JavaLangStringBuilder = TypeReference.findOrCreate(ClassLoaderReference.Primordial,
|
||||
|
@ -93,6 +94,11 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
*/
|
||||
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
|
||||
* smushing?
|
||||
|
@ -135,13 +141,16 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
*/
|
||||
final Map<CGNode, Set> smushMap = HashMapFactory.make();
|
||||
|
||||
public ZeroXInstanceKeys(AnalysisOptions options, IClassHierarchy cha, RTAContextInterpreter contextInterpreter,
|
||||
int policy) {
|
||||
public ZeroXInstanceKeys(AnalysisOptions options, IClassHierarchy cha, RTAContextInterpreter contextInterpreter, 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);
|
||||
siteBased = new AllocationSiteInstanceKeys(options, cha);
|
||||
smushed = new SmushedAllocationSiteInstanceKeys(options, cha);
|
||||
this.cha = cha;
|
||||
this.policy = policy;
|
||||
this.contextInterpreter = contextInterpreter;
|
||||
}
|
||||
|
||||
|
@ -168,6 +177,10 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
return (policy & SMUSH_PRIMITIVE_HOLDERS) > 0;
|
||||
}
|
||||
|
||||
public boolean disambiguateConstants() {
|
||||
return (policy & CONSTANT_SPECIFIC) > 0;
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
||||
if (allocation == null) {
|
||||
throw new IllegalArgumentException("allocation is null");
|
||||
|
@ -193,8 +206,6 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
/**
|
||||
* side effect: populates the smush map.
|
||||
*
|
||||
* @param c
|
||||
* @param node
|
||||
* @return true iff the node contains too many allocation sites of type c
|
||||
*/
|
||||
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
|
||||
* type.
|
||||
*/
|
||||
|
@ -245,15 +255,15 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -291,7 +301,8 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
if (C == 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) {
|
||||
|
@ -329,9 +340,6 @@ public class ZeroXInstanceKeys implements InstanceKeyFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the cha.
|
||||
*/
|
||||
protected IClassHierarchy getClassHierarchy() {
|
||||
return cha;
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class DelegatingExtendedHeapModel implements ExtendedHeapModel {
|
|||
return h.getInstanceKeyForClassObject(type);
|
||||
}
|
||||
|
||||
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
||||
public <T> InstanceKey getInstanceKeyForConstant(TypeReference type, T S) {
|
||||
return h.getInstanceKeyForConstant(type, S);
|
||||
}
|
||||
|
||||
|
@ -96,10 +96,6 @@ public class DelegatingExtendedHeapModel implements ExtendedHeapModel {
|
|||
return h.getPointerKeyForStaticField(f);
|
||||
}
|
||||
|
||||
public String getStringConstantForInstanceKey(InstanceKey I) {
|
||||
return h.getStringConstantForInstanceKey(I);
|
||||
}
|
||||
|
||||
public Iterator<PointerKey> iteratePointerKeys() {
|
||||
return h.iteratePointerKeys();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue