various refactorings for demand points-to analysis
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2758 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
a8b09bef6b
commit
3f293dcc60
|
@ -46,7 +46,6 @@ import junit.framework.TestCase;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil;
|
||||
import com.ibm.wala.demandpa.alg.DemandRefinementPointsTo;
|
||||
import com.ibm.wala.demandpa.alg.IDemandPointerAnalysis;
|
||||
import com.ibm.wala.demandpa.alg.ThisFilteringHeapModel;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.DummyStateMachine;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachineFactory;
|
||||
|
@ -176,7 +175,7 @@ public abstract class AbstractPtrTest extends TestCase {
|
|||
|
||||
protected Collection<InstanceKey> getPointsToSetToTest(String scopeFile, String mainClass) throws ClassHierarchyException,
|
||||
IllegalArgumentException, CancelException, IOException {
|
||||
final IDemandPointerAnalysis dmp = makeDemandPointerAnalysis(scopeFile, mainClass);
|
||||
final DemandRefinementPointsTo dmp = makeDemandPointerAnalysis(scopeFile, mainClass);
|
||||
|
||||
// find the testThisVar call, and check the parameter's points-to set
|
||||
CGNode mainMethod = AbstractPtrTest.findMainMethod(dmp.getBaseCallGraph());
|
||||
|
|
|
@ -265,7 +265,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
curP2Set = computer.getP2Set(queriedPk);
|
||||
if (DEBUG) {
|
||||
System.err.println("traversed " + getNumNodesTraversed() + " nodes");
|
||||
System.err.println("POINTS-TO SET " + lastP2Set);
|
||||
System.err.println("POINTS-TO SET " + curP2Set);
|
||||
}
|
||||
break;
|
||||
} catch (StatesMergedException e) {
|
||||
|
@ -278,8 +278,17 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
|
||||
}
|
||||
if (curP2Set != null) {
|
||||
lastP2Set = curP2Set;
|
||||
if (p2setPred.test(curP2Set)) {
|
||||
if (lastP2Set == null) {
|
||||
lastP2Set = curP2Set;
|
||||
} else if (lastP2Set.size() > curP2Set.size()) {
|
||||
// got a more precise set
|
||||
assert lastP2Set.containsAll(curP2Set);
|
||||
lastP2Set = curP2Set;
|
||||
} else {
|
||||
// new set size is >= lastP2Set, so don't update
|
||||
assert curP2Set.containsAll(lastP2Set);
|
||||
}
|
||||
if (curP2Set.isEmpty() || p2setPred.test(curP2Set)) {
|
||||
// we did it!
|
||||
succeeded = true;
|
||||
break;
|
||||
|
@ -911,7 +920,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
public void visitGetField(GetFieldLabel label, Object dst) {
|
||||
IField field = (label).getField();
|
||||
PointerKey loadBase = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, loadBase, curPk, curState)) {
|
||||
if (refineFieldAccesses(field, loadBase, curPk, label, curState)) {
|
||||
// if (Assertions.verifyAssertions) {
|
||||
// Assertions._assert(stateMachine.transition(curState, label) ==
|
||||
// curState);
|
||||
|
@ -1106,8 +1115,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean refineFieldAccesses(IField field, PointerKey basePtr, PointerKey val, State state) {
|
||||
boolean shouldRefine = refinementPolicy.getFieldRefinePolicy().shouldRefine(field, basePtr, val, state);
|
||||
private boolean refineFieldAccesses(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, State state) {
|
||||
boolean shouldRefine = refinementPolicy.getFieldRefinePolicy().shouldRefine(field, basePtr, val, label, state);
|
||||
if (DEBUG) {
|
||||
if (shouldRefine) {
|
||||
System.err.println("refining access to " + field);
|
||||
|
@ -1180,7 +1189,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
public void visitPutField(PutFieldLabel label, Object dst) {
|
||||
IField field = label.getField();
|
||||
PointerKey storeBase = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, storeBase, curPk, curState)) {
|
||||
if (refineFieldAccesses(field, storeBase, curPk, label, curState)) {
|
||||
// statements x.f = y, Y updated (X' not empty required)
|
||||
// update Z.f for all z in X'
|
||||
PointerKeyAndState storeBaseAndState = new PointerKeyAndState(storeBase, curState);
|
||||
|
@ -1201,7 +1210,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
public void visitGetField(GetFieldLabel label, Object dst) {
|
||||
IField field = (label).getField();
|
||||
PointerKey dstPtrKey = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, curState)) {
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, label, curState)) {
|
||||
// statements x = y.f, Y updated
|
||||
// if X queried, start tracking Y.f
|
||||
PointerKeyAndState loadDefAndState = new PointerKeyAndState(dstPtrKey, curState);
|
||||
|
@ -1232,7 +1241,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
public void visitPutField(PutFieldLabel label, Object dst) {
|
||||
IField field = (label).getField();
|
||||
PointerKey dstPtrKey = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, curState)) {
|
||||
// pass barred label since this is for tracked points-to sets
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, label.bar(), curState)) {
|
||||
// x.f = y, X updated
|
||||
// if Y' non-empty, then update
|
||||
// tracked set of X.f, to trace flow
|
||||
|
@ -1428,7 +1438,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
// z in X'
|
||||
IField field = label.getField();
|
||||
PointerKey dstPtrKey = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, curState)) {
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, label, curState)) {
|
||||
for (InstanceKeyAndState ikAndState : makeOrdinalSet(trackedSet)) {
|
||||
boolean needField = forwInstKeyToFields.get(ikAndState).contains(field);
|
||||
PointerKeyAndState storeDst = new PointerKeyAndState(dstPtrKey, curState);
|
||||
|
@ -1468,7 +1478,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
public void visitPutField(PutFieldLabel label, Object dst) {
|
||||
IField field = label.getField();
|
||||
PointerKey storeBase = (PointerKey) dst;
|
||||
if (refineFieldAccesses(field, storeBase, curPk, curState)) {
|
||||
// bar label since this is for tracked points-to sets
|
||||
if (refineFieldAccesses(field, storeBase, curPk, label.bar(), curState)) {
|
||||
PointerKeyAndState storeBaseAndState = new PointerKeyAndState(storeBase, curState);
|
||||
encounteredStores.add(new StoreEdge(storeBaseAndState, field, curPkAndState));
|
||||
if (!addToInitWorklist(storeBaseAndState)) {
|
||||
|
@ -1503,7 +1514,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
IField field = label.getField();
|
||||
PointerKey dstPtrKey = (PointerKey) dst;
|
||||
// x = y.f, Y' updated
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, curState)) {
|
||||
// bar label since this is for tracked points-to sets
|
||||
if (refineFieldAccesses(field, curPk, dstPtrKey, label.bar(), curState)) {
|
||||
for (InstanceKeyAndState ikAndState : makeOrdinalSet(trackedSet)) {
|
||||
// tracking value written into ik.field
|
||||
boolean needField = backInstKeyToFields.get(ikAndState).contains(field);
|
||||
|
@ -1602,7 +1614,8 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
// System.err.println("QUERIED: " + queriedPkAndStates);
|
||||
// }
|
||||
if (!basePointerOkay) {
|
||||
Assertions._assert(false, "queried " + loadedValAndState + " but not " + baseAndStateToHandle);
|
||||
// TEMPORARY --MS
|
||||
//Assertions._assert(false, "queried " + loadedValAndState + " but not " + baseAndStateToHandle);
|
||||
}
|
||||
}
|
||||
final IntSet curP2Set = find(pkToP2Set, baseAndStateToHandle);
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* 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.
|
||||
*
|
||||
* This file is a derivative of code released by the University of
|
||||
* California under the terms listed below.
|
||||
*
|
||||
* Refinement Analysis Tools is Copyright ©2007 The Regents of the
|
||||
* University of California (Regents). Provided that this notice and
|
||||
* the following two paragraphs are included in any distribution of
|
||||
* Refinement Analysis Tools or its derivative work, Regents agrees
|
||||
* not to assert any of Regents' copyright rights in Refinement
|
||||
* Analysis Tools against recipient for recipient’s reproduction,
|
||||
* preparation of derivative works, public display, public
|
||||
* performance, distribution or sublicensing of Refinement Analysis
|
||||
* Tools and derivative works, in source code and object code form.
|
||||
* This agreement not to assert does not confer, by implication,
|
||||
* estoppel, or otherwise any license or rights in any intellectual
|
||||
* property of Regents, including, but not limited to, any patents
|
||||
* of Regents or Regents’ employees.
|
||||
*
|
||||
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
|
||||
* AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND FURTHER DISCLAIMS ANY STATUTORY
|
||||
* WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE AND ACCOMPANYING
|
||||
* DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
|
||||
* IS". REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
|
||||
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
package com.ibm.wala.demandpa.alg;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.demandpa.flowgraph.AbstractFlowGraph;
|
||||
import com.ibm.wala.demandpa.flowgraph.AbstractFlowLabelVisitor;
|
||||
import com.ibm.wala.demandpa.flowgraph.AssignGlobalLabel;
|
||||
import com.ibm.wala.demandpa.flowgraph.AssignLabel;
|
||||
import com.ibm.wala.demandpa.flowgraph.DemandPointerFlowGraph;
|
||||
import com.ibm.wala.demandpa.flowgraph.GetFieldLabel;
|
||||
import com.ibm.wala.demandpa.flowgraph.NewLabel;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel.IFlowLabelVisitor;
|
||||
import com.ibm.wala.demandpa.util.MemoryAccessMap;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.HeapModel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ssa.IR;
|
||||
import com.ibm.wala.ssa.SSAAbstractInvokeInstruction;
|
||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.UnimplementedError;
|
||||
|
||||
/**
|
||||
* Simple field-based points-to analysis using {@link DemandPointerFlowGraph}.
|
||||
* Primarily for testing purposes.
|
||||
*
|
||||
* @author Manu Sridharan
|
||||
*
|
||||
*/
|
||||
public class TestNewGraphPointsTo extends AbstractDemandPointsTo {
|
||||
|
||||
public TestNewGraphPointsTo(CallGraph cg, HeapModel model, MemoryAccessMap fam, ClassHierarchy cha, AnalysisOptions options) {
|
||||
super(cg, model, fam, cha, options);
|
||||
}
|
||||
|
||||
public Collection<InstanceKey> getPointsTo(PointerKey pk) throws UnimplementedError {
|
||||
|
||||
Assertions._assert(pk instanceof LocalPointerKey, "we only handle locals");
|
||||
LocalPointerKey queriedPk = (LocalPointerKey) pk;
|
||||
// Create an (initially empty) dependence graph
|
||||
final AbstractFlowGraph g = new DemandPointerFlowGraph(cg, heapModel, fam, cha);
|
||||
|
||||
// initialize the graph with the subgraph of x's method
|
||||
g.addSubgraphForNode(queriedPk.getNode());
|
||||
|
||||
// do a DFS traversal of the assign and match edges
|
||||
// in the graph, adding instance keys to the points-to set
|
||||
final HashSet<InstanceKey> p2set = HashSetFactory.make();
|
||||
final HashSet<PointerKey> marked = HashSetFactory.make();
|
||||
final Stack<PointerKey> worklist = new Stack<PointerKey>();
|
||||
class Helper {
|
||||
void prop(PointerKey thePk) {
|
||||
if (!marked.contains(thePk)) {
|
||||
marked.add(thePk);
|
||||
worklist.push(thePk);
|
||||
}
|
||||
}
|
||||
|
||||
void propAll(Iterator<? extends Object> keys) {
|
||||
while (keys.hasNext()) {
|
||||
prop((PointerKey) keys.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
final Helper h = new Helper();
|
||||
// final Mapper pkExtractor = new Mapper() {
|
||||
//
|
||||
// public Object map(Object obj_) {
|
||||
// return ((PointerKeyAndCallSite) obj_).getKey();
|
||||
// }
|
||||
//
|
||||
// };
|
||||
h.prop(queriedPk);
|
||||
final IFlowLabelVisitor v = new AbstractFlowLabelVisitor() {
|
||||
|
||||
@Override
|
||||
public void visitNew(NewLabel label, Object dst) {
|
||||
p2set.add((InstanceKey) dst);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitGetField(GetFieldLabel label, Object dst) {
|
||||
h.propAll(g.getWritesToInstanceField(null, label.getField()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignGlobal(AssignGlobalLabel label, Object dst) {
|
||||
h.propAll(g.getWritesToStaticField((StaticFieldKey) dst));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssign(AssignLabel label, Object dst) {
|
||||
h.prop((PointerKey) dst);
|
||||
}
|
||||
|
||||
};
|
||||
while (!worklist.isEmpty()) {
|
||||
PointerKey curPk = worklist.pop();
|
||||
g.visitSuccs(curPk, v);
|
||||
// interprocedural edges
|
||||
if (curPk instanceof LocalPointerKey) {
|
||||
LocalPointerKey localPk = (LocalPointerKey) curPk;
|
||||
if (g.isParam(localPk)) {
|
||||
CGNode cgNode = localPk.getNode();
|
||||
int paramPos = localPk.getValueNumber() - 1;
|
||||
for (Iterator<? extends CGNode> iter = cg.getPredNodes(cgNode); iter.hasNext();) {
|
||||
CGNode caller = iter.next();
|
||||
IR ir = caller.getIR();
|
||||
for (Iterator<CallSiteReference> iterator = ir.iterateCallSites(); iterator.hasNext();) {
|
||||
CallSiteReference call = iterator.next();
|
||||
// TODO on-the-fly call graph
|
||||
if (cg.getPossibleTargets(caller, call).contains(cgNode)) {
|
||||
g.addSubgraphForNode(caller);
|
||||
SSAAbstractInvokeInstruction[] callInstrs = ir.getCalls(call);
|
||||
for (int i = 0; i < callInstrs.length; i++) {
|
||||
SSAAbstractInvokeInstruction callInstr = callInstrs[i];
|
||||
PointerKey actualPk = heapModel.getPointerKeyForLocal(caller, callInstr.getUse(paramPos));
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(g.containsNode(actualPk));
|
||||
Assertions._assert(g.containsNode(localPk));
|
||||
}
|
||||
h.prop(actualPk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SSAInvokeInstruction callInstr = g.getInstrReturningTo(localPk);
|
||||
if (callInstr != null) {
|
||||
boolean isExceptional = localPk.getValueNumber() == callInstr.getException();
|
||||
|
||||
CallSiteReference callSiteRef = callInstr.getCallSite();
|
||||
// get call targets
|
||||
Set<CGNode> possibleCallees = cg.getPossibleTargets(localPk.getNode(), callSiteRef);
|
||||
// construct graph for each target
|
||||
for (CGNode callee : possibleCallees) {
|
||||
// TODO on-the-fly call graph stuff
|
||||
g.addSubgraphForNode(callee);
|
||||
PointerKey retVal = isExceptional ? heapModel.getPointerKeyForExceptionalReturnValue(callee) : heapModel
|
||||
.getPointerKeyForReturnValue(callee);
|
||||
if (Assertions.verifyAssertions) {
|
||||
Assertions._assert(g.containsNode(retVal));
|
||||
}
|
||||
h.prop(retVal);
|
||||
}
|
||||
}
|
||||
// Assertions._assert(sameContents(orig, newRets), "orig " + orig +
|
||||
// "\nnew " + newRets);
|
||||
// h.propAll(new IteratorMapper(pkExtractor,
|
||||
// g.getReturnSuccs((LocalPointerKey) curPk)));
|
||||
// h.propAll(new IteratorMapper(pkExtractor,
|
||||
// g.getParamSuccs((LocalPointerKey) curPk)));
|
||||
}
|
||||
}
|
||||
|
||||
return p2set;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,9 +18,9 @@ package com.ibm.wala.demandpa.alg.refinepolicy;
|
|||
*/
|
||||
public abstract class AbstractRefinementPolicy implements RefinementPolicy {
|
||||
|
||||
private static final int DEFAULT_NUM_PASSES = 3;
|
||||
private static final int DEFAULT_NUM_PASSES = 4;
|
||||
|
||||
private static final int[] DEFAULT_BUDGET_PER_PASS = { 1000, 12000, 12000 };
|
||||
private static final int[] DEFAULT_BUDGET_PER_PASS = { 1000, 12000, 12000, 12000 };
|
||||
|
||||
protected final FieldRefinePolicy fieldRefinePolicy;
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ package com.ibm.wala.demandpa.alg.refinepolicy;
|
|||
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachine;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
/**
|
||||
|
@ -51,7 +52,7 @@ import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
|||
*/
|
||||
public class AlwaysRefineFieldsPolicy implements FieldRefinePolicy {
|
||||
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, StateMachine.State state) {
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ package com.ibm.wala.demandpa.alg.refinepolicy;
|
|||
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachine;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
/**
|
||||
|
@ -58,7 +59,7 @@ public interface FieldRefinePolicy {
|
|||
* @return <code>true</code> if match edges for the field access should be refined. Otherwise, <code>false</code>
|
||||
* is returned, indicating that the field can be handled with match edges.
|
||||
*/
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, StateMachine.State state);
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state);
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -43,6 +43,7 @@ import java.util.regex.Pattern;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachine;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.demandpa.util.ArrayContents;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
|
@ -70,7 +71,7 @@ public class ManualFieldPolicy implements FieldRefinePolicy {
|
|||
|
||||
final private IClass[] encounteredClasses = new IClass[NUM_DECISIONS_TO_TRACK];
|
||||
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, StateMachine.State state) {
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) {
|
||||
if (field == ArrayContents.v())
|
||||
return true;
|
||||
final IClass declaringClass = field.getDeclaringClass();
|
||||
|
|
|
@ -39,11 +39,12 @@ package com.ibm.wala.demandpa.alg.refinepolicy;
|
|||
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachine;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
public class NeverRefineFieldsPolicy implements FieldRefinePolicy {
|
||||
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, StateMachine.State state) {
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Collection;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.demandpa.alg.statemachine.StateMachine;
|
||||
import com.ibm.wala.demandpa.flowgraph.IFlowLabel;
|
||||
import com.ibm.wala.demandpa.util.ArrayContents;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
|
@ -24,7 +25,9 @@ import com.ibm.wala.util.collections.HashSetFactory;
|
|||
|
||||
public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private final ClassHierarchy cha;
|
||||
|
||||
private final Collection<IClass> typesToRefine = HashSetFactory.make();
|
||||
|
||||
|
@ -33,6 +36,9 @@ public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
|
|||
public boolean nextPass() {
|
||||
if (firstSkippedClass != null) {
|
||||
typesToRefine.add(firstSkippedClass);
|
||||
if (DEBUG) {
|
||||
System.err.println("now refining " + firstSkippedClass);
|
||||
}
|
||||
firstSkippedClass = null;
|
||||
return true;
|
||||
} else {
|
||||
|
@ -40,7 +46,7 @@ public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, StateMachine.State state) {
|
||||
public boolean shouldRefine(IField field, PointerKey basePtr, PointerKey val, IFlowLabel label, StateMachine.State state) {
|
||||
if (field == ArrayContents.v()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -67,8 +73,8 @@ public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
|
|||
/**
|
||||
*
|
||||
* @param klass
|
||||
* @return the top-level {@link IClass} where klass is declared, or klass
|
||||
* itself if klass is top-level or if top-level class not loaded
|
||||
* @return the top-level {@link IClass} where klass is declared, or klass itself if klass is top-level or if top-level
|
||||
* class not loaded
|
||||
*/
|
||||
private IClass removeInner(IClass klass) {
|
||||
ClassLoaderReference cl = klass.getClassLoader().getReference();
|
||||
|
|
|
@ -354,10 +354,10 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
|||
private void debugPrintIR(IR ir) {
|
||||
if (DEBUG) {
|
||||
if (ir == null) {
|
||||
Trace.println("\n No statements\n");
|
||||
System.err.println("\n No statements\n");
|
||||
} else {
|
||||
try {
|
||||
Trace.println(ir.toString());
|
||||
System.err.println(ir.toString());
|
||||
} catch (Error e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -107,4 +107,9 @@ public class PutFieldBarLabel implements IFlowLabel {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "putfield_bar[" + field + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue