use of soot.util.BitVector in project soot by Sable.
the class HybridPointsToSet method intersection.
public static HybridPointsToSet intersection(final HybridPointsToSet set1, final HybridPointsToSet set2, PAG pag) {
final HybridPointsToSet ret = new HybridPointsToSet(Scene.v().getObjectType(), pag);
BitVector s1Bits = set1.bits;
BitVector s2Bits = set2.bits;
if (s1Bits == null || s2Bits == null) {
if (s1Bits != null) {
// set2 is smaller
set2.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (set1.contains(n))
ret.add(n);
}
});
} else {
// set1 smaller, or both small
set1.forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
if (set2.contains(n))
ret.add(n);
}
});
}
} else {
// both big; do bit-vector operation
// potential issue: if intersection is small, might
// use inefficient bit-vector operations later
ret.bits = BitVector.and(s1Bits, s2Bits);
ret.empty = false;
}
return ret;
}
use of soot.util.BitVector in project soot by Sable.
the class SharedHybridSet method nativeAddAll.
private boolean nativeAddAll(SharedHybridSet other, SharedHybridSet exclude) {
/*
* If one of the shared hybrid sets has a bitvector but the other
* doesn't, set that bitvector as the base bitvector and add the stuff
* from the other overflow list. If they both have a bitvector, AND them
* together, then add it to the lookupMap. If neither of them has a
* bitvector, just combine the overflow lists.
*/
BitVector mask = getBitMask(other, pag);
if (exclude != null) {
if (exclude.overflow.size() > 0) {
// Make exclude only a bitvector, for simplicity
PointsToBitVector newBitVector;
if (exclude.bitVector == null) {
newBitVector = new PointsToBitVector(pag.getAllocNodeNumberer().size());
} else {
newBitVector = new PointsToBitVector(exclude.bitVector);
}
add(newBitVector, exclude.overflow);
exclude = new SharedHybridSet(type, pag);
exclude.bitVector = newBitVector;
} else // in that case.
if (exclude.bitVector == null)
exclude = null;
}
int originalSize = size(), originalOnes = originalSize - overflow.size(), otherBitVectorSize = other.size() - other.overflow.size();
// Decide on the base bitvector
if (bitVector == null) {
bitVector = other.bitVector;
if (bitVector != null) {
// Maybe both bitvectors were null; in
// that case, no need to do this
bitVector.incRefCount();
// Since merging in new bits might add elements that
// were
// already in the overflow list, we have to remove and re-add
// them all.
// TODO: Can this be avoided somehow?
// Maybe by allowing an element to be both in the overflow set
// and
// the bitvector?
// Or could it be better done by checking just the bitvector and
// removing elements that are there?
OverflowList toReAdd = overflow;
overflow = new OverflowList();
// whether a new bit vector
boolean newBitVectorCreated = false;
// was created, which is used to decide whether to re-add the
// overflow list as an overflow list again or merge it into the
// new bit vector.
numElements = otherBitVectorSize;
if (exclude != null || mask != null) {
PointsToBitVector result = new PointsToBitVector(bitVector);
if (exclude != null)
result.andNot(exclude.bitVector);
if (mask != null)
result.and(mask);
if (!result.equals(bitVector)) {
add(result, toReAdd);
int newBitVectorSize = result.cardinality();
numElements = newBitVectorSize;
findAppropriateBitVector(result, other.bitVector, otherBitVectorSize, otherBitVectorSize);
newBitVectorCreated = true;
}
}
if (// if it was, then toReAdd has
!newBitVectorCreated) // already been re-added
{
for (OverflowList.ListNode i = toReAdd.overflow; i != null; i = i.next) {
add(i.elem);
}
}
}
} else if (other.bitVector != null) {
// Now both bitvectors are non-null; merge them
PointsToBitVector newBitVector = new PointsToBitVector(other.bitVector);
if (exclude != null)
newBitVector.andNot(exclude.bitVector);
if (mask != null)
newBitVector.and(mask);
newBitVector.or(bitVector);
if (// if some elements were
!newBitVector.equals(bitVector)) // actually added
{
if (other.overflow.size() != 0) {
PointsToBitVector toAdd = new PointsToBitVector(newBitVector.size());
add(toAdd, other.overflow);
if (mask != null)
toAdd.and(mask);
if (exclude != null)
toAdd.andNot(exclude.bitVector);
newBitVector.or(toAdd);
}
// At this point newBitVector is still bitVector + some new bits
// # of bits in the
int numOnes = newBitVector.cardinality();
// new bitvector
int numAdded = add(newBitVector, overflow);
numElements += // number of new bits
numOnes - originalOnes + numAdded - // might be negative due to
overflow.size();
if (size() > originalSize) {
findAppropriateBitVector(newBitVector, other.bitVector, otherBitVectorSize, originalOnes);
// checkSize();
return true;
} else {
// It might happen that the bitvector being merged in adds some bits
return false;
// to the existing bitvector, but that those new bits are all elements that were already
// in the overflow list. In that case, the set might not change, and if not we return false.
// We also leave the set the way it was by not calling findAppropriateBitvector,
// which maximizes sharing and is fastest in the short term. I'm not sure whether it
// would be faster overall to keep the already calculated bitvector anyway.
}
}
}
// Add all the elements in the overflow list of other, unless they're in
// exclude
OverflowList overflow = other.overflow;
for (OverflowList.ListNode i = overflow.overflow; i != null; i = i.next) {
// for (int i = 0; i < overflow.size(); ++i) {
Node nodeToMaybeAdd = i.elem;
if ((exclude == null) || !exclude.contains(nodeToMaybeAdd)) {
if (mask == null || mask.get(nodeToMaybeAdd.getNumber())) {
add(nodeToMaybeAdd);
}
}
}
// checkSize();
return size() > originalSize;
}
use of soot.util.BitVector in project soot by Sable.
the class TypeResolverBV method remove_transitive_constraints.
private void remove_transitive_constraints() throws TypeException {
refresh_solved();
BitVector list = new BitVector();
list.or(solved);
list.or(unsolved);
for (BitSetIterator varIt = list.iterator(); varIt.hasNext(); ) {
final TypeVariableBV var = typeVariableForId(varIt.next());
var.removeIndirectRelations();
}
}
use of soot.util.BitVector in project soot by Sable.
the class TypeResolverBV method compute_solved.
private void compute_solved() {
unsolved = new BitVector();
solved = new BitVector();
for (TypeVariableBV var : typeVariableList) {
if (var.depth() == 0) {
if (var.type() == null) {
unsolved.set(var.id());
} else {
solved.set(var.id());
}
}
}
}
use of soot.util.BitVector in project soot by Sable.
the class TypeResolverBV method merge_connected_components.
private void merge_connected_components() throws TypeException {
refresh_solved();
BitVector list = new BitVector();
list.or(solved);
list.or(unsolved);
new StronglyConnectedComponentsBV(list, this);
}
Aggregations