126 lines
4.8 KiB
Java
126 lines
4.8 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.cast.java.ipa.slicer;
|
|
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.Set;
|
|
|
|
import com.ibm.wala.cast.ir.ssa.AstAssertInstruction;
|
|
import com.ibm.wala.cast.java.ipa.modref.AstJavaModRef;
|
|
import com.ibm.wala.ipa.callgraph.CGNode;
|
|
import com.ibm.wala.ipa.callgraph.CallGraph;
|
|
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
|
|
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
|
import com.ibm.wala.ipa.slicer.NormalStatement;
|
|
import com.ibm.wala.ipa.slicer.SDG;
|
|
import com.ibm.wala.ipa.slicer.Slicer;
|
|
import com.ibm.wala.ipa.slicer.Statement;
|
|
import com.ibm.wala.ssa.IR;
|
|
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
|
|
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
|
|
import com.ibm.wala.ssa.SSAGetInstruction;
|
|
import com.ibm.wala.ssa.SSAInstruction;
|
|
import com.ibm.wala.ssa.SSAMonitorInstruction;
|
|
import com.ibm.wala.ssa.SSAPutInstruction;
|
|
import com.ibm.wala.util.CancelException;
|
|
import com.ibm.wala.util.collections.Filter;
|
|
import com.ibm.wala.util.collections.Pair;
|
|
import com.ibm.wala.util.graph.traverse.DFS;
|
|
|
|
@SuppressWarnings("deprecation")
|
|
public class AstJavaSlicer extends Slicer {
|
|
|
|
/*
|
|
* Use the passed-in SDG
|
|
*/
|
|
public static Collection<Statement> computeBackwardSlice(SDG sdg, Collection<Statement> ss) throws IllegalArgumentException,
|
|
CancelException {
|
|
return computeSlice(sdg, ss, true);
|
|
}
|
|
|
|
/**
|
|
* @param ss a collection of statements of interest
|
|
* @throws CancelException
|
|
*/
|
|
public static Collection<Statement> computeSlice(SDG sdg, Collection<Statement> ss, boolean backward) throws CancelException {
|
|
return new AstJavaSlicer().slice(sdg, ss, backward);
|
|
}
|
|
|
|
public static Set<Statement> gatherStatements(CallGraph CG, Collection<CGNode> partialRoots, Filter<SSAInstruction> filter) {
|
|
Set<Statement> result = new HashSet<Statement>();
|
|
for (Iterator<CGNode> ns = DFS.getReachableNodes(CG, partialRoots).iterator(); ns.hasNext();) {
|
|
CGNode n = ns.next();
|
|
IR nir = n.getIR();
|
|
if (nir != null) {
|
|
SSAInstruction insts[] = nir.getInstructions();
|
|
for (int i = 0; i < insts.length; i++) {
|
|
if (filter.accepts(insts[i])) {
|
|
result.add(new NormalStatement(n, i));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public static Set<Statement> gatherAssertions(CallGraph CG, Collection<CGNode> partialRoots) {
|
|
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
|
public boolean accepts(SSAInstruction o) {
|
|
return o instanceof AstAssertInstruction;
|
|
}
|
|
});
|
|
}
|
|
|
|
public static Set<Statement> gatherMonitors(CallGraph CG, Collection<CGNode> partialRoots) {
|
|
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
|
public boolean accepts(SSAInstruction o) {
|
|
return o instanceof SSAMonitorInstruction;
|
|
}
|
|
});
|
|
}
|
|
|
|
public static Set<Statement> gatherWrites(CallGraph CG, Collection<CGNode> partialRoots) {
|
|
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
|
public boolean accepts(SSAInstruction o) {
|
|
return (o instanceof SSAPutInstruction) || (o instanceof SSAArrayStoreInstruction);
|
|
}
|
|
});
|
|
}
|
|
|
|
public static Set<Statement> gatherReads(CallGraph CG, Collection<CGNode> partialRoots) {
|
|
return gatherStatements(CG, partialRoots, new Filter<SSAInstruction>() {
|
|
public boolean accepts(SSAInstruction o) {
|
|
return (o instanceof SSAGetInstruction) || (o instanceof SSAArrayLoadInstruction);
|
|
}
|
|
});
|
|
}
|
|
|
|
public static Pair<Collection<Statement>, SDG> computeAssertionSlice(CallGraph CG, PointerAnalysis pa,
|
|
Collection<CGNode> partialRoots, boolean multiThreadedCode) throws IllegalArgumentException, CancelException {
|
|
CallGraph pcg = PartialCallGraph.make(CG, new LinkedHashSet<CGNode>(partialRoots));
|
|
SDG sdg = new SDG(pcg, pa, new AstJavaModRef(), DataDependenceOptions.FULL, ControlDependenceOptions.FULL);
|
|
System.err.println(("SDG:\n" + sdg));
|
|
Set<Statement> stmts = gatherAssertions(CG, partialRoots);
|
|
if (multiThreadedCode) {
|
|
// Grab anything that has "side effects" under JMM
|
|
stmts.addAll(gatherReads(CG, partialRoots));
|
|
stmts.addAll(gatherWrites(CG, partialRoots));
|
|
stmts.addAll(gatherMonitors(CG, partialRoots));
|
|
}
|
|
return Pair.make(AstJavaSlicer.computeBackwardSlice(sdg, stmts), sdg);
|
|
}
|
|
|
|
}
|