soot.jimple.spark.ondemand.AllocAndContextSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of soot Show documentation
Show all versions of soot Show documentation
A Java Optimization Framework
package soot.jimple.spark.ondemand;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2007 Manu Sridharan
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.HashSet;
import java.util.Set;
import soot.PointsToSet;
import soot.Type;
import soot.jimple.ClassConstant;
import soot.jimple.spark.ondemand.genericutil.ArraySet;
import soot.jimple.spark.ondemand.genericutil.ImmutableStack;
import soot.jimple.spark.pag.AllocNode;
import soot.jimple.spark.pag.ClassConstantNode;
import soot.jimple.spark.pag.Node;
import soot.jimple.spark.pag.StringConstantNode;
import soot.jimple.spark.sets.EqualsSupportingPointsToSet;
import soot.jimple.spark.sets.P2SetVisitor;
import soot.jimple.spark.sets.PointsToSetInternal;
public final class AllocAndContextSet extends ArraySet implements EqualsSupportingPointsToSet {
public boolean hasNonEmptyIntersection(PointsToSet other) {
if (other instanceof AllocAndContextSet) {
return nonEmptyHelper((AllocAndContextSet) other);
} else if (other instanceof WrappedPointsToSet) {
return hasNonEmptyIntersection(((WrappedPointsToSet) other).getWrapped());
} else if (other instanceof PointsToSetInternal) {
return ((PointsToSetInternal) other).forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (!returnValue) {
for (AllocAndContext allocAndContext : AllocAndContextSet.this) {
if (n.equals(allocAndContext.alloc)) {
returnValue = true;
break;
}
}
}
}
});
}
throw new UnsupportedOperationException("can't check intersection with set of type " + other.getClass());
}
private boolean nonEmptyHelper(AllocAndContextSet other) {
for (AllocAndContext otherAllocAndContext : other) {
for (AllocAndContext myAllocAndContext : this) {
if (otherAllocAndContext.alloc.equals(myAllocAndContext.alloc)) {
ImmutableStack myContext = myAllocAndContext.context;
ImmutableStack otherContext = otherAllocAndContext.context;
if (myContext.topMatches(otherContext) || otherContext.topMatches(myContext)) {
return true;
}
}
}
}
return false;
}
public Set possibleClassConstants() {
Set res = new HashSet();
for (AllocAndContext allocAndContext : this) {
AllocNode n = allocAndContext.alloc;
if (n instanceof ClassConstantNode) {
res.add(((ClassConstantNode) n).getClassConstant());
} else {
return null;
}
}
return res;
}
public Set possibleStringConstants() {
Set res = new HashSet();
for (AllocAndContext allocAndContext : this) {
AllocNode n = allocAndContext.alloc;
if (n instanceof StringConstantNode) {
res.add(((StringConstantNode) n).getString());
} else {
return null;
}
}
return res;
}
public Set possibleTypes() {
Set res = new HashSet();
for (AllocAndContext allocAndContext : this) {
res.add(allocAndContext.alloc.getType());
}
return res;
}
/**
* Computes a hash code based on the contents of the points-to set. Note that hashCode() is not overwritten on purpose.
* This is because Spark relies on comparison by object identity.
*/
public int pointsToSetHashCode() {
final int PRIME = 31;
int result = 1;
for (AllocAndContext elem : this) {
result = PRIME * result + elem.hashCode();
}
return result;
}
/**
* Returns true
if and only if other holds the same alloc nodes as this. Note that equals() is not overwritten
* on purpose. This is because Spark relies on comparison by object identity.
*/
public boolean pointsToSetEquals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof AllocAndContextSet)) {
return false;
}
AllocAndContextSet otherPts = (AllocAndContextSet) other;
// both sets are equal if they are supersets of each other
return superSetOf(otherPts, this) && superSetOf(this, otherPts);
}
/**
* Returns true
if onePts
is a (non-strict) superset of otherPts
.
*/
private boolean superSetOf(AllocAndContextSet onePts, final AllocAndContextSet otherPts) {
return onePts.containsAll(otherPts);
}
}