001: /* Soot - a J*va Optimization Framework
002: * Copyright (C) 2007 Manu Sridharan
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the
016: * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017: * Boston, MA 02111-1307, USA.
018: */
019: package soot.jimple.spark.ondemand;
020:
021: import java.util.Set;
022:
023: import soot.PointsToSet;
024: import soot.jimple.spark.ondemand.genericutil.ArraySet;
025: import soot.jimple.spark.ondemand.genericutil.ImmutableStack;
026: import soot.jimple.spark.pag.Node;
027: import soot.jimple.spark.sets.EqualsSupportingPointsToSet;
028: import soot.jimple.spark.sets.P2SetVisitor;
029: import soot.jimple.spark.sets.PointsToSetInternal;
030:
031: public final class AllocAndContextSet extends ArraySet<AllocAndContext>
032: implements EqualsSupportingPointsToSet {
033:
034: public boolean hasNonEmptyIntersection(PointsToSet other) {
035: if (other instanceof AllocAndContextSet) {
036: return nonEmptyHelper((AllocAndContextSet) other);
037: } else if (other instanceof WrappedPointsToSet) {
038: return hasNonEmptyIntersection(((WrappedPointsToSet) other)
039: .getWrapped());
040: } else if (other instanceof PointsToSetInternal) {
041: return ((PointsToSetInternal) other)
042: .forall(new P2SetVisitor() {
043:
044: @Override
045: public void visit(Node n) {
046: if (!returnValue) {
047: for (AllocAndContext allocAndContext : AllocAndContextSet.this ) {
048: if (n.equals(allocAndContext.alloc)) {
049: returnValue = true;
050: break;
051: }
052: }
053: }
054: }
055:
056: });
057: }
058: throw new UnsupportedOperationException(
059: "can't check intersection with set of type "
060: + other.getClass());
061: }
062:
063: private boolean nonEmptyHelper(AllocAndContextSet other) {
064: for (AllocAndContext otherAllocAndContext : other) {
065: for (AllocAndContext myAllocAndContext : this ) {
066: if (otherAllocAndContext.alloc
067: .equals(myAllocAndContext.alloc)) {
068: ImmutableStack<Integer> myContext = myAllocAndContext.context;
069: ImmutableStack<Integer> otherContext = otherAllocAndContext.context;
070: if (myContext.topMatches(otherContext)
071: || otherContext.topMatches(myContext)) {
072: return true;
073: }
074: }
075: }
076: }
077: return false;
078: }
079:
080: public Set possibleClassConstants() {
081: throw new UnsupportedOperationException();
082: }
083:
084: public Set possibleStringConstants() {
085: throw new UnsupportedOperationException();
086: }
087:
088: public Set possibleTypes() {
089: throw new UnsupportedOperationException();
090: }
091:
092: /**
093: * Computes a hash code based on the contents of the points-to set.
094: * Note that hashCode() is not overwritten on purpose.
095: * This is because Spark relies on comparison by object identity.
096: */
097: public int pointsToSetHashCode() {
098: final int PRIME = 31;
099: int result = 1;
100: for (AllocAndContext elem : this ) {
101: result = PRIME * result + elem.hashCode();
102: }
103: return result;
104: }
105:
106: /**
107: * Returns <code>true</code> if and only if other holds the same alloc nodes as this.
108: * Note that equals() is not overwritten on purpose.
109: * This is because Spark relies on comparison by object identity.
110: */
111: public boolean pointsToSetEquals(Object other) {
112: if (this == other) {
113: return true;
114: }
115: if (!(other instanceof AllocAndContextSet)) {
116: return false;
117: }
118: AllocAndContextSet otherPts = (AllocAndContextSet) other;
119:
120: //both sets are equal if they are supersets of each other
121: return super SetOf(otherPts, this ) && super SetOf(this , otherPts);
122: }
123:
124: /**
125: * Returns <code>true</code> if <code>onePts</code> is a (non-strict) superset of <code>otherPts</code>.
126: */
127: private boolean super SetOf(AllocAndContextSet onePts,
128: final AllocAndContextSet otherPts) {
129: return onePts.containsAll(otherPts);
130: }
131: }
|