package soot.jimple.spark.sets; import soot.util.BitVector; import soot.jimple.spark.pag.Node; /** An extension of a bit vector which is convenient to use to represent * points-to sets. Used by SharedHybridSet. * * We have to extend soot.util.BitVector rather than java.util.BitSet * because PointsToSetInternal.getBitMask() returns a soot.util.BitVector. * which must be combined with other bit vectors. * * @author Adam Richard * */ public class PointsToBitVector extends BitVector { public PointsToBitVector(int size) { super(size); } /** * Adds n to this * @return Whether this actually changed */ public boolean add(Node n) { int num = n.getNumber(); if (!get(num)) //if it's not already in this { set(num); return true; } else return false; } public boolean contains(Node n) { //Ripped from the HybridPointsToSet implementation //I'm assuming `number' in Node is the location of the node out of all //possible nodes. return get(n.getNumber()); } /** * Adds the Nodes in arr to this bitvector, adding at most size Nodes. * @return The number of new nodes actually added. */ /* public int add(Node[] arr, int size) { //assert size <= arr.length; int retVal = 0; for (int i = 0; i < size; ++i) { int num = arr[i].getNumber(); if (!get(num)) { set(num); ++retVal; } } return retVal; } */ /**Returns true iff other is a subset of this bitvector*/ public boolean isSubsetOf(PointsToBitVector other) { //B is a subset of A iff the "and" of A and B gives A. BitVector andResult = BitVector.and(this, other); //Don't want to modify either one return andResult.equals(this); } /**@return number of 1 bits in the bitset. * Call this sparingly because it's probably expensive.*/ /*Old algorithm: public int cardinality() { int retVal = 0; BitSetIterator it = iterator(); while (it.hasNext()) { it.next(); ++retVal; } return retVal; } */ public PointsToBitVector(PointsToBitVector other) { super(other); /* PointsToBitVector retVal = (PointsToBitVector)(other.clone()); return retVal;*/ } //Reference counting: private int refCount = 0; public void incRefCount() { ++refCount; //An estimate of how much sharing is going on (but it should be 1 less //than the printed value in some cases, because incRefCount is called //for an intermediate result in nativeAddAll. //System.out.println("Reference count = " + refCount); } public void decRefCount() { --refCount; } public boolean unused() { return refCount == 0; } }