157 lines
5.1 KiB
Java
157 lines
5.1 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2013 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.demandpa.alg;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import com.ibm.wala.classLoader.IClass;
|
|
import com.ibm.wala.classLoader.IField;
|
|
import com.ibm.wala.classLoader.IMethod;
|
|
import com.ibm.wala.classLoader.NewSiteReference;
|
|
import com.ibm.wala.classLoader.ProgramCounter;
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
import com.ibm.wala.ipa.callgraph.ContextKey;
|
|
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
|
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey.TypeFilter;
|
|
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
|
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
import com.ibm.wala.types.TypeReference;
|
|
import com.ibm.wala.util.debug.Assertions;
|
|
|
|
/**
|
|
* a {@link HeapModel} that delegates to another except for pointer keys representing <code>this</code> parameters of methods, for
|
|
* which it returns a {@link FilteredPointerKey} for the type of the parameter
|
|
*
|
|
* @see {@link DemandRefinementPointsTo}
|
|
* @author manu
|
|
*
|
|
*/
|
|
class ThisFilteringHeapModel implements HeapModel {
|
|
|
|
private final HeapModel delegate;
|
|
|
|
private final IClassHierarchy cha;
|
|
|
|
@Override
|
|
public IClassHierarchy getClassHierarchy() {
|
|
return delegate.getClassHierarchy();
|
|
}
|
|
|
|
@Override
|
|
public FilteredPointerKey getFilteredPointerKeyForLocal(CGNode node, int valueNumber, TypeFilter filter) {
|
|
return delegate.getFilteredPointerKeyForLocal(node, valueNumber, filter);
|
|
}
|
|
|
|
@Override
|
|
public InstanceKey getInstanceKeyForAllocation(CGNode node, NewSiteReference allocation) {
|
|
return delegate.getInstanceKeyForAllocation(node, allocation);
|
|
}
|
|
|
|
@Override
|
|
public InstanceKey getInstanceKeyForMetadataObject(Object obj, TypeReference objType) {
|
|
return delegate.getInstanceKeyForMetadataObject(obj, objType);
|
|
}
|
|
|
|
@Override
|
|
public InstanceKey getInstanceKeyForConstant(TypeReference type, Object S) {
|
|
return delegate.getInstanceKeyForConstant(type, S);
|
|
}
|
|
|
|
@Override
|
|
public InstanceKey getInstanceKeyForMultiNewArray(CGNode node, NewSiteReference allocation, int dim) {
|
|
return delegate.getInstanceKeyForMultiNewArray(node, allocation, dim);
|
|
}
|
|
|
|
@Override
|
|
public InstanceKey getInstanceKeyForPEI(CGNode node, ProgramCounter instr, TypeReference type) {
|
|
return delegate.getInstanceKeyForPEI(node, instr, type);
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForArrayContents(InstanceKey I) {
|
|
return delegate.getPointerKeyForArrayContents(I);
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForExceptionalReturnValue(CGNode node) {
|
|
return delegate.getPointerKeyForExceptionalReturnValue(node);
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForInstanceField(InstanceKey I, IField field) {
|
|
return delegate.getPointerKeyForInstanceField(I, field);
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForLocal(CGNode node, int valueNumber) {
|
|
if (!node.getMethod().isStatic() && valueNumber == 1) {
|
|
return delegate.getFilteredPointerKeyForLocal(node, valueNumber, getFilter(node));
|
|
} else {
|
|
return delegate.getPointerKeyForLocal(node, valueNumber);
|
|
}
|
|
}
|
|
|
|
private FilteredPointerKey.TypeFilter getFilter(CGNode target) {
|
|
FilteredPointerKey.TypeFilter filter = (FilteredPointerKey.TypeFilter) target.getContext().get(ContextKey.PARAMETERS[0]);
|
|
|
|
if (filter != null) {
|
|
return filter;
|
|
} else {
|
|
// the context does not select a particular concrete type for the
|
|
// receiver.
|
|
IClass C = getReceiverClass(target.getMethod());
|
|
return new FilteredPointerKey.SingleClassFilter(C);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param method
|
|
* @return the receiver class for this method.
|
|
*/
|
|
private IClass getReceiverClass(IMethod method) {
|
|
TypeReference formalType = method.getParameterType(0);
|
|
IClass C = cha.lookupClass(formalType);
|
|
if (method.isStatic()) {
|
|
Assertions.UNREACHABLE("asked for receiver of static method " + method);
|
|
}
|
|
if (C == null) {
|
|
Assertions.UNREACHABLE("no class found for " + formalType + " recv of " + method);
|
|
}
|
|
return C;
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForReturnValue(CGNode node) {
|
|
return delegate.getPointerKeyForReturnValue(node);
|
|
}
|
|
|
|
@Override
|
|
public PointerKey getPointerKeyForStaticField(IField f) {
|
|
return delegate.getPointerKeyForStaticField(f);
|
|
}
|
|
|
|
@Override
|
|
public Iterator<PointerKey> iteratePointerKeys() {
|
|
return delegate.iteratePointerKeys();
|
|
}
|
|
|
|
public ThisFilteringHeapModel(HeapModel delegate, IClassHierarchy cha) {
|
|
if (delegate == null) {
|
|
throw new IllegalArgumentException("delegate null");
|
|
}
|
|
this.delegate = delegate;
|
|
this.cha = cha;
|
|
}
|
|
|
|
}
|