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:
sjfink 2007-11-29 18:22:39 +00:00
parent 95042b1f2f
commit f6ebdd8eee
16 changed files with 121 additions and 189 deletions

View File

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

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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